Skip to main content
Version: 1.0

Healthcare

The challenge

Cross-jurisdictional health data sharing is one of the hardest authorization problems in any sector:

  • Each jurisdiction has its own rules — a physician in one province needs a patient record from another, but each jurisdiction enforces different privacy regulations and consent requirements.
  • No federated authorization model — sharing today means VPNs, fax machines, or custom point-to-point integrations per partner. Every new connection is a months-long project.
  • Consent is a checkbox, not a policy — patient consent is captured in a database but not enforced programmatically at the authorization layer. Compliance depends on application logic, not infrastructure.
  • Audit is reconstructed, not built in — demonstrating compliance means stitching together logs from multiple systems after the fact. Regulators want to see who accessed what, when, and under what authority.
  • New actors have no model — AI agents, remote monitoring systems, and cross-institutional research tools need access but have no authorization framework in the existing infrastructure.

How PBAC handles it

Federated identity, local policy control

Each jurisdiction keeps its own identity provider and defines its own authorization rules. PBAC federates the access decisions — so a provider authenticated by Province A's IdP can access a patient record in Province B, governed by Province B's policies.

Patient consent is not a static flag — it is enforced as a policy-driven obligation at the moment of access. When a provider requests a health record, OPA evaluates whether consent exists, whether it covers the requested scope, and whether the clinical context qualifies. Consent can trigger step-up verification or redaction of sensitive categories.

Scoped access by clinical context

Resource types (HealthRecord, Prescription, LabResult, Encounter) are defined with fine-grained scopes. A pharmacy system gets prescription.read and prescription.dispense — not access to the full health record. Policy enforcement happens at the token layer, not in each application.

Every decision logged

Every access decision — allowed, denied, or constrained — is logged with the subject, the resource, the action, the policy that governed it, and any obligations returned. Compliance audit is a query, not a reconstruction project.


Architecture


Resource types and scopes

ResourceType URIScopes
HealthRecordurn:health:health-recordread, write, share
Appointmenturn:health:appointmentread, write, cancel
Prescriptionurn:health:prescriptionread, dispense
LabResulturn:health:lab-resultread, write
Encounterurn:health:encounterread, write

Scope-resource binding: Scopes are grouped under resource types in granted_resources. read and write for HealthRecord are in the grant for urn:health:health-record. No cross-resource leakage.


Resource servers

RSResource IndicatorTypes Served
EHR APIhttps://api.health.example.com/ehr/*HealthRecord, Encounter
Hospital APIhttps://api.health.example.com/hospital/*Appointment, Encounter
Pharmacy APIhttps://api.health.example.com/pharmacy/*Prescription
Lab APIhttps://api.health.example.com/lab/*LabResult

Trust issuers


Client apps and entitlements

AppTypegranted_resources
Patient Portalconfidential_appurn:as:userinfo (openid); health-record, appointment with scopes; resource_indicators for ehr/, hospital/
Provider EHRconfidential_appurn:as:userinfo (openid); health-record, encounter, lab-result with scopes; resource_indicators for ehr/, lab/
Pharmacy Systemconfidential_appurn:as:userinfo (openid); prescription: read, dispense; resource_indicator for pharmacy/*
Lab Viewerconfidential_appurn:as:userinfo (openid); lab-result: read; resource_indicator for lab/*

Key flows:

  • Patient Portal: health-record.read, appointment.read/write
  • Provider EHR: health-record.read/write, encounter.read/write, lab-result.read
  • Pharmacy: prescription.read, prescription.dispense
  • Lab Viewer: lab-result.read only

Example token requests

Patient Portal — read health record:

scope=openid read
resource=https://api.health.example.com/ehr/records
resource_types=urn:health:health-record

Provider EHR — write encounter:

scope=openid read write
resource=https://api.health.example.com/ehr/encounters
resource_types=urn:health:encounter

Pharmacy — dispense prescription:

scope=openid read dispense
resource=https://api.health.example.com/pharmacy/prescriptions
resource_types=urn:health:prescription

Policy implementation note

The token policy uses the unified model: granted_resources (array of { type, scopes, resource_indicator? }). Resource-scoped scopes require resource_types in the request. Policy evaluates via oauth.entitlements.client_is_allowed.


Try it

See this model in action with the Quickstart — from credentials to a policy decision in 5 minutes.

Want to discuss how PBAC fits your environment? Talk to us →


Next steps

  • Quickstart — From credentials to a policy decision in 5 minutes
  • Consent Extension — Implement consent-as-obligation for user-delegated flows
  • Token exchange — Cross-domain identity via id_token exchange for federated access