SMART on FHIR OAuth 2.0 scopes supported by HealthLake
HealthLake uses OAuth 2.0 as an authorization protocol. Using this protocol on your authorization server allows you to define HealthLake data store permissions (create, read, update, delete, and search) for FHIR resources that a client application has access to.
The SMART on FHIR framework defines a set of scopes that can be requested from the
authorization server. For example, a client application that is only designed to allow
patients to view their lab results or view their contact details should only be
authorized to request read scopes.
Note
HealthLake provides support for both SMART on FHIR V1 and V2 as described below. The
SMART on FHIR AuthorizationStrategy is set to one of the following three
values when your data store is created:
-
SMART_ON_FHIR_V1– Support for only SMART on FHIR V1, which includesread(read/search) andwrite(create/update/delete) permissions. -
SMART_ON_FHIR– Support for both SMART on FHIR V1 and V2, which includescreate,read,update,delete, andsearchpermissions. -
AWS_AUTH– The default AWS HealthLake authorization strategy; not affiliated with SMART on FHIR.
Standalone launch scope
HealthLake supports the standalone launch mode scope launch/patient.
In standalone launch mode a client application requests access to patient's clinical data because the user and patient are not known to the client application. Thus, the client application's authorization request explicitly requests the patient scope be returned. After successful authentication, the authorization server issues a access token containing the requested launch patient scope. The needed patient context is provided alongside the access token in the authorization server's response.
| Scope | Description |
|---|---|
|
A parameter in a OAuth 2.0 authorization request requesting that patient data be returned in the authorization response. |
SMART on FHIR resource scopes for HealthLake
HealthLake defines three levels of SMART on FHIR resource scopes.
-
patientscopes grant access to specific data about a single Patient. -
userscopes grant access to specific data that a user can access. -
systemscopes grant access to all FHIR resources found in the HealthLake data store.
The following sections list the syntax for constructing FHIR resource scopes using either SMART on FHIR V1 or SMART on FHIR V2.
Note
The SMART on FHIR authorization strategy is set when your data store is created.
For more information, see AuthorizationStrategy in the AWS HealthLake API
Reference.
SMART on FHIR V1 scopes supported by HealthLake
When using SMART on FHIR V1, the general syntax for constructing FHIR resource scopes for HealthLake follows. To view the entire URL path in the following example, scroll over the Copy button.
('patient' | 'user' | 'system') '/' (fhir-resource | '*') '.' ('read' | 'write' | '*')
| Scope syntax | Example scope | Result |
|---|---|---|
|
patient/AllergyIntolerance.* |
The patient client application has instance-level read/write access to all recorded allergies. |
|
user/Observation.read |
The user client application has instance-level read/write access to all recorded observations. |
system/('read' | 'write' | *) |
system/*.* |
The system client application has read/write access to all FHIR resource data. |
SMART on FHIR V2 scopes supported by HealthLake
When using SMART on FHIR V2, the general syntax for constructing FHIR resource scopes for HealthLake follows. To view the entire URL path in the following example, scroll over the Copy button.
('patient' | 'user' | 'system') '/' (fhir-resource | '*') '.' ('c' | 'r' | 'u' | 'd' | 's')
Note
To use SMART on FHIR V2, you must pass in the value permission-v2capabilities string, which is a member of the IdentityProviderConfiguration data type.
HealthLake supports granular scopes. For more information, see supported granular scopes
| Scope syntax | Example V1 scope | Result |
|---|---|---|
|
user/Observation.read |
Permission to read and search Observation resource
for the current patient. |
|
system/*.* |
The system client application has full create/read/update/delete/search access to all FHIR resource data. |
SMART on FHIR V2.2 scopes supported by HealthLake
V2.2 extends V2 scopes with search-parameter–based filtering. Authorization servers can now issue scopes that restrict access by specific data characteristics and not just by resource type and CRUDS operation.
Everything from V2 remains unchanged. V2.2 is purely additive:
-
Existing V2 scopes (without filters) continue to work as before.
-
The V2 grammar is extended with an optional
?param=valuequery string. -
No changes to scope levels (
patient/user/system), resource types, or CRUDS letters.
Prerequisites
Before enabling SMART on FHIR V2.2, ensure the following:
-
Your data store was created with
AuthorizationStrategyset toSMART_ON_FHIR(supports both V1 and V2). Data stores usingSMART_ON_FHIR_V1orAWS_AUTHare not eligible. -
Your data store already includes
permission-v2in thecapabilitiesarray. V2.2 is additive as it extends V2 and cannot be used standalone. -
Your IDP Lambda is configured to validate and pass through the V2.2 scope format (scopes containing
?query syntax).
Enabling V2.2
The enablement path depends on whether you are creating a new data store or updating an existing one.
New data stores
When creating a new data store, add
permission-v2.2 to the capabilities array
in the Metadata field of your IdentityProviderConfiguration:
"capabilities": [ "launch-ehr", "sso-openid-connect", "client-public", "permission-v2", "permission-v2.2" ]
Existing data stores
For existing data stores, submit a support ticket requesting the addition
of permission-v2.2 to your data store configuration. This
follows the same process used when upgrading from SMART on FHIR V1 to
SMART on FHIR V2.
Self-service updates for V2.2 on existing data stores are not yet available. The HealthLake team will apply the change on your behalf upon ticket submission.
Requirements:
-
permission-v2must remain in the array. V2.2 cannot be used without V2. -
AuthorizationStrategymust beSMART_ON_FHIR(notSMART_ON_FHIR_V1orAWS_AUTH). -
No downtime required. The change takes effect immediately.
To verify, confirm via the Discovery Document (requires SigV4):
GET {healthlake-endpoint}/r4/.well-known/smart-configuration
If the capabilities array in the response includes
permission-v2.2, SMART on FHIR V2.2 is
active.
Extended scope syntax
The V2 grammar is extended with an optional query string:
V2: (patient|user|system) / resource . cruds V2.2: (patient|user|system) / resource . cruds [? param=value [& param=value ...]]
| Component | Description |
|---|---|
|
Search-parameter filter. Only resources matching this criterion are accessible. |
|
Additional filter. Multiple filters are ANDed – all must match. |
Rules:
-
Filters only apply to the resource type specified in the scope. Wildcard (
*) with filters is not supported. -
Parameters must be valid for the resource type per your data store's search configuration (check via
GET /r4/metadata). -
The full scope string (for example,
patient/Observation.rs?category=laboratory) is the literal value that appears in the OAuth 2.0 scope parameter and access tokenscpclaim. -
URL-encode special characters per RFC 6749
in authorization requests (for example, |→%7C). -
For date, number, and quantity parameters, V2.2 supports prefix comparators (for example,
?date=eq2023-01-01). V2.2 also supports search parameter modifiers.
Scope examples
| Scope | Access granted |
|---|---|
|
Only |
|
Only |
|
Only |
|
Only |
|
Only active |
Enforcement behavior
When a token includes V2.2 scopes, HealthLake applies filters per operation:
| Operation | Behavior |
|---|---|
Read ( |
Succeeds only if the resource matches all scope filters. Otherwise returns 403. |
Search ( |
Scope filters are intersected with the query. Only matching resources are returned. |
Create/Update ( |
Resource must satisfy scope filters to be written. Otherwise returns 403. |
Delete ( |
Target resource must match scope filters. Otherwise returns 403. |
Scope precedence
-
Multiple V2.2 scopes for the same resource type are unioned (OR across scopes).
-
A broader V2 scope without filters (for example,
patient/Observation.rs) grants full access regardless of any narrower V2.2 scopes in the same token. -
V2.2 scopes on a data store without
permission-v2.2enabled are silently ignored.
Limitations
The following are not supported in V2.2 scope filters:
-
Composite search parameters (for example,
code-value-quantity). -
Chained search parameters (for example,
subject:Patient.name=Smith). -
_include/_revincludesearch parameters. -
$export/$davinci-data-export(Bulk Data) – V2.2 filters do not apply; bulk export uses V2 scopes. -
Wildcard resource type combined with filters (for example,
patient/*.rs?category=LABis invalid). You must specify an explicit resource type when using search-parameter filters (for example,patient/Observation.rs?category=LAB).
| Symptom | Cause | Fix |
|---|---|---|
Token scope not recognized |
V2.2 not enabled on data store |
Check |
403 on a resource that exists |
Resource does not match scope filter |
Verify resource values against scope parameters. |
Empty search results |
Scope filter narrower than query |
Results are the intersection of query and scope filters. |
|
Invalid search parameter in scope |
Confirm parameter via
|
End-to-end example
Scenario: A patient app should only show finalized lab results from 2023 onward.
-
Authorization server issues token with scope:
patient/Observation.rs?category=laboratory&status=final&date=ge2023-01-01 -
Client calls HealthLake:
GET {endpoint}/r4/Observation?patient=Patient/123 -
HealthLake enforces scope filters. The response contains only
Observationresources wherecategory=laboratoryANDstatus=finalANDdate ≥ 2023-01-01– even though the client requested all Observations.