Health endpoints
Two unauthenticated health endpoints are available for infrastructure probes. These are defined inapp/routers/ops.py on a public router with no auth dependency.
Use these for Kubernetes probes, Caddy health checks, and uptime monitors:
api service healthcheck calls /health:
Health response format
503 Service Unavailable response (with body {"status": "unhealthy"}) is returned if the process is shutting down or the event loop is unresponsive.
Deep health check (planned)
The observability spec defines aGET /healthz/deep endpoint (operator-only, not a k8s probe) that performs a live dependency sweep including Postgres, Redis, and LLM providers:
Operations endpoints
Protected operations endpoints (require auth) are also defined inapp/routers/ops.py on a separate router with the standard auth dependency:
Structured logging
The observability architecture specifies structured JSON logging with mandatory fields on every log line:
PII policy: no PII or secrets appear in logs. Email addresses, API keys, and encrypted values are never logged.
Centralized log aggregation (Loki, Datadog, Papertrail) is not yet configured out of the box. The application writes structured logs to stdout, which can be forwarded to any log aggregation service via your container runtime or a log collector sidecar. Centralized logging + SIEM is a SOC 2 gap — see SOC 2 readiness.
Metrics — OpenTelemetry
The target observability stack is OpenTelemetry (OTel) with a Gateway Collector exporting to Prometheus. The spec defines RED metrics per route:
The planned OTel Collector configuration uses:
- Tail sampling: 100% for errors and slow requests, 5% baseline
spanmetricsconnector for RED metrics derived from spans (pre-sampling, so metrics are unbiased)- Grafana dashboards per service + a tenant-health overview
OTel instrumentation and the Prometheus/Grafana stack are specified in the observability backend spec but are not yet wired into the current FastAPI application. This is a SOC 2 gap (CC7.1–7.3). Adding OpenTelemetry involves installing
opentelemetry-sdk, opentelemetry-instrumentation-fastapi, and configuring the OTel exporter in app/main.py.Audit log
The audit log is the primary operational record for compliance and incident investigation. It is:- Append-only: an
UPDATE/DELETEtrigger (0002_audit_trace_append_only.sql) raises an exception if anyone attempts to modify or delete an audit record - RLS-scoped: each workspace sees only its own audit trail
- Retention-configured: governed by
workspace_settings.audit_log_retention_dayswith a compliance floor of ≥ 365 days
Schema
Querying the audit log
Alerting (planned)
The SOC 2 audit identifies security alerting as a gap. The target alert set includes:
These are not yet implemented. Integrating with PagerDuty, OpsGenie, or Slack alerts via the OTel Collector or a Grafana alerting rule is the recommended approach.
Operations runbook checklist
For day-to-day operations:- Deployment:
docker compose pull && docker compose up -d(VPS) orrailway up/render deploy - Schema migration:
make migrateafter each deploy that includes new migration files - New client:
SELECT onboard_client(...)— see Client provisioning - Retention purge: call
purge_expired(DATABASE_URL)via a scheduled job (daily recommended) - Backup:
pg_dump "$DATABASE_URL" -Fc -f backup_$(date +%Y%m%d).dump - Health check:
curl https://api.yourdomain.com/health - Log tailing:
docker compose logs -f api(VPS) or your platform’s log viewer