SMARTapplaunchmultiserverauthentication, published by HL7. This guide is not an authorized publication; it is the continuous build for version 0.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/bvdh/smart-multi-auth/ and changes regularly. See the Directory of published versions
The section enables applications to obtain authorization from multiple systems while maintaining appropriate user consent and security controls. It builds on existing SMART App Launch flows, executing them sequentially with contextual information passed between authorization requests.
Dual SMART Launch enables an application to obtain authorization from multiple systems (specifically an EHR and an Imaging Server) while maintaining appropriate user consent and security controls. It builds on existing SMART App Launch flows, executing them sequentially with contextual information passed between authorization requests.
sequenceDiagram
participant App as Application
participant EHR as EHR System
participant IS as Imaging Server
App->>EHR: GET [ehrFhirBaseUrl]/.well-known/smart-configuration
EHR-->>App: Configuration with associated_endpoints & capabilities
App->>IS: GET [imagingServerFhirBaseUrl]/.well-known/smart-configuration
IS-->>App: Configuration with smart-imaging-access-dual-launch capability
When the application begins the Dual SMART Launch process, it first needs to discover where the related systems are located and whether they support this capability. The application starts by querying the EHR's well-known SMART configuration endpoint to obtain metadata about the EHR's capabilities.
The EHR's response includes an associated_endpoints
array that lists related systems such as imaging servers. Each entry in this array includes a URL and a list of capabilities supported by that endpoint. The application looks for endpoints that include the "smart-imaging-access-dual-launch" capability.
After identifying a compatible imaging server from the EHR's configuration, the application directly queries that imaging server's SMART configuration to verify it explicitly supports dual launch. This two-step discovery process ensures both systems are properly configured to support the dual authorization workflow before proceeding.
It's important to note that at this stage, the application is simply discovering endpoints. It doesn't yet know about any patient identifiers in either system. These identifiers, which may differ between systems, will be received later in the authorization process.
[ehrFhirBaseUrl]/.well-known/smart-configuration
.[imagingServerFhirBaseUrl]
is discovered through the associated_endpoints
array.{
"capabilities": [...],
"associated_endpoints": [{
"url": "[imagingServerFhirBaseUrl]",
"capabilities": ["smart-imaging-access-dual-launch"]
}]
}
[imagingServerFhirBaseUrl]/.well-known/smart-configuration
.id_token
as a login_hint
.sequenceDiagram
participant App as Application
participant EHR as EHR System
App->>EHR: Initiate SMART App Launch (with openid, fhirUser scopes)
EHR->>EHR: Authenticate user
EHR->>EHR: User authorization for EHR data
EHR-->>App: Authorization code
App->>EHR: Exchange code for tokens
EHR-->>App: Access token + OpenID id_token for EHR
App->>App: Store EHR tokens and context
After discovering the endpoints, the application initiates a standard SMART App Launch flow with the EHR. This is a crucial first step because the application needs to establish the user's identity and clinical context before accessing imaging data.
The application initiates this process by directing the user to the EHR's authorization endpoint, including special scopes like openid
and fhirUser
in addition to any clinical data scopes it needs. These specific scopes tell the EHR that the application will need an OpenID Connect identity token (id_token
) in addition to the standard access token.
The user then authenticates with the EHR using their credentials and is presented with an authorization screen showing what data the application is requesting. After the user approves, the EHR returns an authorization code to the application.
The application exchanges this code for tokens by making a request to the EHR's token endpoint. The EHR responds with an access token for clinical data and the requested OpenID id_token
, which contains claims about the user's identity. In addition, the token response includes a patient
property containing the FHIR logical id of the patient in the EHR's FHIR server. This logical id is the unique identifier that appears in resource URL path components (e.g., /Patient/123
where "123" is the logical id). The application stores these tokens and the current context for use in the subsequent imaging server authorization.
It's important to understand that this FHIR logical id is specific to the EHR's FHIR server. The same patient may have a different logical id in the imaging FHIR server, though the application doesn't know about the imaging server's identifier yet.
This phase follows standard SMART App Launch, but the request for OpenID scopes is particularly important for the dual launch process, as the id_token
will be used to facilitate the connection to the imaging server.
openid
and fhirUser
scopes to ensure receipt of an OpenID Connect id_token
.id_token
as requested via the scopesid_token
sequenceDiagram
participant App as Application
participant EHR as EHR System
participant IS as Imaging Server
App->>IS: Initiate SMART App Launch (with id_token in login_hint)
rect rgb(240, 240, 255)
note right of IS: Embedded Workflow
IS->>IS: Verify client registration with EHR
IS->>EHR: GET [ehrClientDiscoveryEndpoint]/clients/[clientId]
EHR-->>IS: Client metadata (JWKS, redirect_uri)
IS->>EHR: Authorization request with id_token_hint & prompt=none
EHR->>EHR: Validate id_token_hint
EHR->>EHR: Auto-authorize based on existing session
EHR-->>IS: Access token + OpenID id_token for Imaging Server
end
IS->>IS: Implement authorization policy
alt EHR-Integrated Policy
IS->>EHR: GET /ImagingStudy?patient=X (using EHR token)
EHR-->>IS: Accessible imaging studies
else Independent Policy
IS->>IS: Apply local access policy
end
IS->>IS: User authorization for imaging data
IS-->>App: Authorization code
App->>IS: Exchange code for tokens
IS-->>App: Access token for Imaging Server
This phase represents the most innovative part of the Dual SMART Launch flow. Having obtained authorization from the EHR, the application now initiates a second SMART App Launch with the imaging server. However, unlike a standard launch, the application includes the EHR-issued id_token
as a login_hint
parameter in its request to the imaging server.
When the imaging server receives this request, it kicks off an embedded workflow that's largely invisible to the user:
First, the imaging server needs to verify that the application is legitimate. It does this by contacting the EHR's client discovery endpoint to retrieve information about the application's registration. This allows the imaging server to validate the application's redirect URI and, for confidential clients, obtain the keys needed to verify signatures.
Next, the imaging server initiates its own authorization request back to the EHR. Here's where the magic happens: it includes the original id_token
as an id_token_hint
and sets prompt=none
, essentially telling the EHR "this user has already authenticated, so don't show them another login screen." If the token is valid, the EHR automatically issues tokens to the imaging server without any user interaction. These tokens grant the imaging server permission to access relevant patient data from the EHR.
An important aspect of this token exchange is that the EHR includes a patient
property in its access token response. This property contains the FHIR logical id of the patient in the EHR's FHIR server. The FHIR logical id is the specific identifier that appears in resource URL path components (e.g., /Patient/123
where "123" is the logical id). The imaging server can use this EHR-supplied patient logical id to establish context for subsequent operations.
With these tokens in hand, the imaging server can now implement its authorization policy. It has two main options:
For patient identity correlation, the imaging server can retrieve the full Patient resource from the EHR using the EHR-issued access token and the patient's logical id. This allows the imaging server to access the array of FHIR Identifiers (distinct from the logical id) stored in the Patient resource. These identifiers, which may include MRNs, national IDs, or other identifier systems, can then be used by the imaging server to map to its own internal patient representation, which likely has its own FHIR logical id in the imaging system.
Finally, the imaging server presents an authorization screen to the user, asking for permission to share imaging data with the application. After approval, the imaging server issues an authorization code to the application, which is exchanged for an access token specific to imaging resources. The imaging server includes its own patient
property in the token response, containing the imaging system's FHIR logical id for the patient, which may be different from the EHR's logical id.
This phase elegantly solves the problem of requiring multiple authentications while still maintaining separate, explicit authorization decisions for different data types and managing potentially different patient identifiers across systems.
id_token
(from the EHR) in the login_hint
parameter.[ehrClientDiscoveryEndpoint]/clients/[clientId]
.redirect_uri
id_token
passed in the id_token_hint
parameterprompt=none
to request automated authenticationid_token_hint
id_token
sequenceDiagram
participant App as Application
participant EHR as EHR System
participant IS as Imaging Server
App->>EHR: Access EHR resources (using EHR token)
EHR-->>App: EHR resource data
App->>IS: Access imaging resources (using Imaging Server token)
IS-->>App: Imaging resource data
Once the application has successfully completed authorization with both systems, it now possesses two distinct access tokens: one for the EHR and one for the imaging server. The final phase involves using these tokens to access the respective resources.
The application can now make API calls to both systems in parallel or sequentially as needed. When requesting clinical data, it includes the EHR-issued access token in its requests to the EHR's FHIR API. Similarly, when requesting imaging data, it includes the imaging server-issued access token in its requests to the imaging server's API.
When accessing Patient resources, the application must be aware that it has received different FHIR logical ids for the same patient:
These logical ids are used differently when making requests to their respective systems:
GET [ehrFhirBaseUrl]/Patient/{ehrPatientLogicalId}
(using EHR token)GET [imagingServerFhirBaseUrl]/ImagingStudy?patient={imagingPatientLogicalId}
(using imaging server token)Note that the imaging server may not expose Patient resources directly, but instead uses the patient parameter in queries for ImagingStudy resources.
The application doesn't need to perform any patient identifier mapping itself; that responsibility was handled by the imaging server during the authorization phase. The application simply uses each system's native patient logical id when making requests to that system.
Additionally, if the application needs to access a patient's full identifier set (beyond just the logical id), it can retrieve the Patient resource from the EHR and examine the identifier
array, which contains all the business identifiers (like MRNs, national IDs, etc.) associated with the patient.
This separation of tokens and identifiers maintains the principle of least privilege. Each system issues tokens that grant access only to the resources under its control, and each system independently validates and enforces the appropriate access controls when receiving requests. If a token for one system is compromised, it cannot be used to access resources from the other system.
The application can now provide an integrated view of both clinical and imaging data to the user, having navigated the dual authorization process in a way that balances security with a streamlined user experience.
.well-known/smart-configuration
associated_endpoints
arrayopenid
and fhirUser
scopes/clients/{client_id}
endpoint that returns client metadataid_token_hint
and prompt=none
parameterspatient
property of token responses.well-known/smart-configuration
openid
and fhirUser
id_token
(acting user) and patient
claims (subject)In the Dual SMART Launch flow, it's essential to understand the distinction between different types of identifiers:
/Patient/A123
where "A123" is the logical id)patient
propertyidentifier
property of a resource.
The Imaging Server is responsible for correlating patient identifiers between systems:
This correlation can be implemented in several ways:
The application is shielded from this complexity and simply uses each system's patient logical id in its requests.