Authentication
SMART on FHIR authentication with ES256 JWT tokens
Overview
The system uses SMART on FHIR authentication with ES256 (Elliptic Curve) signed JWT tokens. All authentication flows go through the smart-auth Edge Function.
Authentication Flow
Staff Login
POST /authenticatewith email + password- If user belongs to one org: token returned directly
- If user belongs to multiple orgs: returns org list
POST /select-staff-organizationwith chosen org_id- Returns JWT token scoped to that organization
Patient Login
POST /authenticate-patientwith email + password- Similar multi-org flow via
POST /select-organization - Returns JWT with
patient_idclaim
JWT Token Structure
Key Claims
| Claim | Description |
|---|---|
sub | Supabase auth user UUID |
roles | Array of roles in current org |
role | Primary role (deprecated, use roles) |
org_id | Current organization UUID |
practitioner | Internal UUID of practitioner record |
practitioner_id | FHIR resource_id of practitioner |
practitioner_reference | Full FHIR reference (e.g., Practitioner/UNB_doctor_001) |
privileges | The privilege list resolved from the user's roles at login |
is_national | Whether org has cross-org access |
patient_id | (Patient tokens only) Patient resource_id |
Using Auth Headers
All API requests require the JWT in the Authorization header:
The fhir-api Edge Function validates the token on every request using validateSmartToken(), which:
- Verifies ES256 signature
- Checks expiration
- Extracts session claims (org_id, practitioner, roles, etc.)
Session Interface
Multi-Organization Support
- Users can belong to multiple organizations with different roles per org
- Organization selection issues a new JWT scoped to the chosen org
- The
org_idclaim scopes all data access via RLS policies - Users can switch orgs without re-entering credentials
Three Auth Code Paths
| Path | Handler | Used By |
|---|---|---|
/select-organization | index.ts inline | Tests + mobile app |
/select-staff-organization | select-staff-organization.ts | Staff web GUI |
| Single-org auto-login | authenticate.ts | When user has exactly 1 org |
All three return consistent roles[], privileges[], and JWT claims.
Token Signing
- Algorithm: ES256 (ECDSA with P-256 curve)
- Key type: Asymmetric (private key signs, public key verifies)
- Storage: Private key in Supabase Edge Function environment variables
- Library:
jose(JavaScript Object Signing and Encryption)