Skip to main content

Access Control — How it works

Overview

The access-control engine is the platform's authorization core. It owns local identity (user accounts, local credentials, refresh tokens), the role/permission model, the access scopes that bound a user or provider to tenants/facilities/departments/modules, and the unified access decision that combines all of these — plus identity-access visibility/consent/grants and feature flags, with optional OPA policy — to answer "may this caller do this to this object?". It also supports break-glass access and audits patient-data access.

Data model & ownership

AreaTables
Local identityuser_account, user_refresh_token
RBACrole, permission, role_permission, user_role
Scopesuser_access_scope (+ _tenant), provider_access_scope (+ _tenant), user_facility_access, user_department_access, user_module_access
Policyauthorization_policy, opa_policy_bundle_reference, policy_decision_log
Break-glass & auditbreak_glass_grant, patient_access_audit_event

Key rules & invariants

  • The unified access decision gathers authoritative local facts (status/roles/permissions/scopes)
    • identity-access visibility/consent/grants + feature flags; OPA evaluates contextual policy and must not duplicate role/scope lookup. OPA is off by default — the local pipeline already enforces access.
  • Patient/person/clinical searches filter by access scope server-side.
  • Break-glass requires a reason, elevated permission, a time box, an audit record, and a review signal.
  • Service-to-service calls carry service identity + delegated user/request context.

API

See the API Reference. Endpoint groups under /api/v1/access-control: auth (local login/refresh), users, roles, permissions, user/provider access scopes (+ facility/department/module access), access-decision and object-access-decision, break-glass, and patient-access audit.

Configuration & feature flags

  • security.access-control.enforce (declarative @RequiresAccess filter; off by default).
  • OPA enablement (OPA_ENABLED, fail-closed, base URL) — off by default.