Skip to main content

Auth + Consent Flow

A request from a browser to a PHI endpoint crosses four independent trust boundaries. Each boundary is enforced in code + tested explicitly.

Request lifecycle

When a PHI-route handler carries @ConsentScope("<scope>"), the ConsentGuard resolves in this strict order — short-circuit on first ALLOW:

This is implemented once in ConsentGuardcontrollers never re-implement. Every allow path sets authSource on the audit event so forensic review can trace which branch permitted the access.

MFA flow (step-up)

MFA roles enforced (FR-009d): provider, coordinator, nurse, admin always require MFA. Patients opt in.

For Microsoft tokens MFA is verified via the amr JWT claim evaluated against AMR_ACCEPT. Google OIDC doesn't emit amr, so Google users always enforce the application-layer MFA (Spec 002).

Break-glass access

Break-glass access does NOT bypass ACL (FR-046-005) — consent-denied-at-ACL-level still denies. The break-glass branch only allows bypass of the standing-consent check.

Why 4 independent layers?

Principle III — Defense in Depth. If any single layer is accidentally weakened:

  • CSRF compromised → RBAC still requires the right role
  • RBAC misconfigured → ConsentGuard still requires a consent path
  • ConsentGuard misconfigured → @phi_repository still adds patient_id to the query filter (FR-013d)
  • Repo layer bypassed by direct Mongo access → FieldEncryptionService still refuses plaintext PHI writes

See CLAUDE.md § Authentication & Session — DO / DON'T and § Authorization — DO / DON'T for the exact enforcement rules.