On this page:

7.13SMART on FHIR: Smile CDR Support

 

This page describes support for SMART on FHIR Security within Smile CDR. Note that this page uses terms described on the SMART on FHIR: Introduction page. If you haven't read that already, you should start there.

There are several modules that can be used in different ways in order to create a complete SMART on FHIR compliant architecture.

7.13.1Supported Scopes

 

The following table lists the scopes that are supported by Smile CDR.

Scope Description
User Identity openid profile This pair of scopes permits the client to request details about the logged in user. They enable the OpenID Connect id_token claim.
Refresh Tokens online_access This scope permits that the client be issued a Refresh Token upon authentication, and permits the user to exchange the Refresh Token for an Access Token. This scope has no effect for clients that do not support the refresh_token grant type.
offline_access This scope permits that the client be issued a Refresh Token upon authentication, and permits the user to exchange the Refresh Token for an Access Token. This scope has no effect for clients that do not support the refresh_token grant type.
SMART on FHIR Launch
See Launch Context Scopes for a description of what these scopes do.
launch/patient Request that the server provide a contextual Patient resource identifier as a part of the claims returned to the client during the authorization flow.
launch/encounter Request that the server provide a contextual Encounter resource identifier as a part of the claims returned to the client during the authorization flow.
launch/location Request that the server provide a contextual Location resource identifier as a part of the claims returned to the client during the authorization flow.
SMART on FHIR Data Access
See Scope Permission Model for a description of how these scopes are actually applied to a user session.
patient/*.read This scope permits the client to read (read/search/history) all data for all patients on the server. In other words, all data in any Patient compartment.
patient/*.write This scope permits the client to write (create/update) all data for all patients on the server. In other words, all data in any Patient compartment.
patient/[ResourceType].read This scope permits the client to read (read/search/history) all data for the given resource type for all patients on the server. Note that [ResourceType] must be a valid FHIR Resource type (e.g. Observation).

Clients that have been configured to support wildcard scopes (e.g. Patient/*.read) are also permitted to request this scope without needing to have it declared explicitly in the client definition.
patient/[ResourceType].write This scope permits the client to write (create/update) all data for the given resource type for all patients on the server. Note that [ResourceType] must be a valid FHIR Resource type (e.g. Observation).

Clients that have been configured to support wildcard scopes (e.g. Patient/*.read) are also permitted to request this scope without needing to have it declared explicitly in the client definition.
Misc. Permissions cdr_all_user_authorities This is a special scope that grants the session all permissions that are granted to the authorizing user. Note that this scope supercedes all other data access scopes. This is useful if you wish to have clients/applications authorizing using SMART on FHIR that need to access administrative functions of Smile CDR.

7.13.2Scope Permission Model

 

When a user authorizes with an application, there are two sets of permissions that must be considered: The Client Scopes that are granted to the client, and the User Permissions that are granted to the user.

The permissions that are ultimately available to the user via the client session once they have successfully authorized will be the intersection of these two concepts.

Example

For example, consider a user who has only been granted the FHIR_READ_ALL_IN_COMPARTMENT/Patient/123 permission in their user account, but has not been granted any other permissions. This permission allows the user read-only access to resources associated with their Patient resource (Patient/123).

Now, suppose this user authorizes a client application with the patient/*.read and patient/*.write scopes. Despite these broad scopes being authorized, Smile CDR will only allow the client to perform actions that are within the intersection of the scopes and permissions. In this case, the client/user will only be permitted to read data associated with the given Patient and will not be allowed to write.

On the other hand, suppose the user had been granted the very broad ROLE_FHIR_CLIENT_SUPERUSER permission. This permission allows the user mostly unrestricted access to perform FHIR operations. However, if the user grants a client only the patient/*.read scope, the client will not be permitted to perform any write actions against the FHIR services.

7.13.3Online / Offline Access

 

Note that at present the online_access and offline_access scopes have identical functionality; this is because a standalone CDR and an EHR do not share the same concept of a user session. In future, functionality may be added that allows a more complete online_access session concept.

7.13.4User and Patient Resource Linkage

 

When authorizing applications used by Patients, a common scenario is to have a user account bound to a specific Patient resource in FHIR storage. In this scenario, generally an individual Patient user should only be able to access data that belongs to them.

When authorizing such a user for a patient-facing app, there are two objectives to meet:

  1. The Smile CDR FHIR Endpoint needs to know which Patient resource the user's account corresponds to, so that it can decide if the request is appropriate or not, and block it if it is not.
  2. The App needs to know which Patient resource the user's account corresponds to, so that the App knows which resources are appropriate to request from the FHIR endpoint.

The most common way to accomplish this with Smile CDR is to store an attribute in the user's account that contains the ID of the Patient resource corresponding to their record. In the case of an internally issued access token (i.e. using the SMART Outbound Security module) this can be added to the user session by a script in the Local Inbound Security module (or the LDAP/Script/etc. Inbound Security module). In this case, objective 1 is met by assigning appropriate permissions during the authorization stage (e.g. by assigning them directly to the user's account, or by enriching the permissions via a login script). Objective 2 can be met using launch scopes.

In the case of an externally issued access token (i.e. using a third-party Authorization Server such as Keycloak) the identity of the Patient should be stored in the Authorization Server user record, so that it can be communicated to the FHIR Endpoint via a claim in the Access Token. This satisfies objective 1 by allowing the app to decode and inspect the token to extract the patient ID. This satisfies objective 2 by allowing the SMART Inbound Security module login script to decode and inspect the token to extract the patient ID, then assign appropriate permissions.

This raises an additional challenge: how to add this attribute to the Authorization Server user directory.

There is no single way of solving this, but there are different strategies that can be used depending on the particulars of the application.

If the application has accounts managed by a central authority rather than allowing users to self-register (this is often the case in institutional applications, research trial applications, etc.) then an additional step can be added to the user account creation process that creates a Patient resource, and then assigns its ID to the user account.

If the application will allow direct user sign up and FHIR resources already exist in the FHIR repository, a manual/automatic linking process may need to be developed that inspects a user's account and looks for a FHIR resource with the same attributes (e.g. a common identifier or demographic, such as a medical record number or an email address).

I don't know if this is helpful, but it's certainly something we can talk through. If there are features we need to add to the product to facilitate the specifics of your project, we are of course happy to add them. That's how almost all of the features in the security module have ended up in there, as we see a wider and wider variety of projects using a Smile CDR FHIR backend.