Skip to content

Telemetry Service Integration

Layer 2 feature, not yet implemented. Telemetry is a separate Go service (services/telemetry/) that ingests patient exercise-engagement events and pose-tracking landmark batches from the Patient Portal. No audit_log forwarding, no ClickHouse, no separate compliance Postgres — see ../../telemetry/index.md for the locked design and decisions.md → Why telemetry is PG + S3, not ClickHouse for the rationale.

At-a-glance

ConcernWhere
Serviceservices/telemetry/ (separate Fargate task, same VPC + ALB as Core API)
Auth on hot pathShort-lived signed session token issued by Core API at exercise-session start; verified by signature only on Telemetry API
Storage — aggregatesSame RDS Postgres as Core API (pose_session_metrics, pose_rep_metrics monthly partitioned, media_session_metrics, media_buffering_events monthly partitioned)
Storage — replayS3 bucket restartix-telemetry-{env}, blobs at {org_id}/{session_id}.bin.gz (binary float32 + gzip, ~3 MB per 30-min session)
Cross-service commsTelemetry → Core API via Cat F service-account principal, publishes via events.Bus; Core API subscriber writes the aggregate rows
ReadsAll on Core API; Telemetry API exposes no read endpoints to clients

Endpoints (Telemetry API)

EndpointConsumerPurpose
POST /v1/pose/framesPatient Portal browserBatched MediaPipe landmark frames (binary, 1-sec batches)
POST /v1/media/eventsPatient Portal browserVideo lifecycle events (play/pause/heartbeat/buffering/end)
POST /v1/sessions/{id}/endPatient Portal browserSession finalizer; triggers aggregation + S3 blob write + events.Bus publish
GET /v1/healthzALBHealth check

The earlier POST /v1/audit/ingest, POST /v1/analytics/track, POST /v1/errors/report, and admin/dashboard endpoints have been removed — see ../../telemetry/api.md for the rationale and the canonical reference.

Cross-tenant isolation

  • All ingest carries org_id in the signed session token; Telemetry API rejects mismatched scope with 401.
  • S3 blob paths are partitioned by org_id from the bucket prefix.
  • PG aggregate writes happen on the Core API side under the existing RLS-scoped subscriber — Telemetry never has direct DB write access.
  • Reads in Clinic / Portal / Console all flow through Core API and inherit the same RLS, audit, classification, and per-org permission surface.

Network paths

  • Patient Portal browser → Telemetry API: public HTTPS, signed token in Authorization header.
  • Telemetry API → S3: VPC endpoint (private).
  • Telemetry API → Core API (events.Bus publish): private subnet, service-account credential.
  • No public Core-API-to-Telemetry path. No Telemetry-to-Postgres direct path.

Security checklist

  • [ ] Signed-session-token secret rotated via Secrets Manager per credential-rotation runbook
  • [ ] Cat F service-account credential for Telemetry → Core API rotated on the same cadence
  • [ ] S3 bucket restartix-telemetry-{env} is KMS-encrypted, no public access, lifecycled
  • [ ] Mandatory analytics consent for media events; mandatory biometric consent for pose ingest — Telemetry API rejects with 403 otherwise
  • [ ] CI guard cmd/check-telemetry-bounds rejects direct PG/S3 imports from Telemetry handlers (swap-point interfaces only)
  • [ ] No PII in observability logs from Telemetry API (pseudonym.UserID if any cross-tenant aggregate logging needed; not used for PG aggregates which are clinic-scoped)