Security
Security controls are implemented at the application and database layers, and are verified by a suite that runs against a real PostgreSQL instance.
Core controls
- organization/client-scoped access;
- row-level security on tenant tables, enforced by the database;
- action-level authorization;
- protected tRPC procedures;
- connection-scoped EHR routing;
- secret references rather than embedded credentials;
- signed document access;
- chained, anchored audit records;
- bounded uploads;
- outbound HTTPS validation;
- FHIR resource allowlisting;
- SMART scope restrictions;
- JWT/JWKS validation;
- idempotency/replay controls in applicable workflows;
- administrator sign-in throttling;
- kill switches for governed AI/voice capabilities.
Tenant isolation
Isolation is enforced twice: every customer-bound query is scoped by organization and client in application code, and the database independently enforces the organization boundary with row-level security policies on every table that carries an organization_id. A connection that declares no tenant scope reads nothing, and the application refuses to serve from a database connection that can bypass the policies.
See Tenant and client isolation.
Audit integrity
Audit records are chained per organization with SHA-256 links, and each chain has an anchor record outside the chain itself, so deleting the newest records, rewriting one, reordering, or inserting is detected and reported with a specific reason.
PHI-safe AI
Every field offered to an AI capability is classified before it is sent. Values classified as direct identifiers are dropped rather than reformatted, and only control metadata and hashes are recorded in the context manifest.
See AI and PHI data flow.
Evidence integrity
An evidence manifest is built from the bytes actually retained in storage, and verification re-reads those bytes instead of trusting the digest recorded alongside them. Replacing a stored document after an approval package is prepared is detected at verification time.
Sign-in protection
Administrator sign-in is rate-limited per submitted address and per client through a distributed counter, and every refused attempt is recorded in the security event stream. The limiter fails closed: if the counter store is unreachable, sign-in is refused rather than admitted. No lockout state is written to credential records, so an attacker cannot lock a known administrator out.
API surface
The serverless entrypoint applies CORS and origin checks, per-IP rate limiting, request-size limits, and security headers before any request reaches the application router.
Storage
Production storage is private and configured through S3 or Supabase. Signed access URLs are issued only after scoped document authorization.
Webhooks
Paddle webhook processing verifies signatures. Future inbound provider webhooks must use equivalent signature verification before activation.
Verification
The database and security suite runs in CI against PostgreSQL and Redis service containers, and reports the number of tests that actually executed rather than only the number that failed, so a silently skipped suite fails the build.