Skip to main contentAlvearie

SMART App Launch with Keycloak and the IBM FHIR Server

By Lee Surprenant    |    Published March 23, 2021

Background

The IBM FHIR Server implements HL7 FHIR version 4.0.1 (R4) and supports the FHIR REST API for each resource type defined in the specification.

However, one thing that neither the HL7 FHIR specification nor the IBM FHIR Server prescribe is the security model for this interface. Enter SMART on FHIR.

SMART on FHIR is a collection of specifications that focus on authentication and authorization on top of HL7 FHIR. In November of 2018, Boston Children’s Hospital and HL7 published the first of these specifications called the SMART App Launch Framework. This specification extends OAuth 2.0 with custom scopes and the notion of launch context.

SMART scopes are normal OAuth 2.0 scope strings that are used to define an authorization model that is aligned with FHIR resources. The specification defines the scope strings via a pattern like <context>/<resourceType>.<permission>, where

  • context is patient or user;
  • resourceType is one of the resource types defined in the HL7 FHIR specification, or * to indicate all resource types; and
  • permission is read or write, or * for read and write.

SMART launch context is what allows a user to launch an application in the context of a given user session or patient record. SMART App Launch defines two different launch varieties: one for launching apps from an Electronic Health Record (EHR) system and one for launching “standalone” apps.

In this post, I walk through how to support standalone app launch with the IBM FHIR Server via Keycloak, an open source identity and access management solution.

Introducing the Alvearie Keycloak Extensions for FHIR

Keycloak is wonderfully extensible and easily configurable. Users can automate the creation of SMART scopes through scipting or configuration, or manually create them via the admin console. However, supporting SMART launch context is a bit more tricky.

In particular, SMART extends the OAuth 2.0 / OpenID Connect token response payload with a set of launch context parameters. For example, in the case of the patient context, a SMART-enabled client application would expect a patient parameter in the token response payload (alongside the access token).

In addition to the above, SMART App Launch also defines a custom aud parameter that clients must pass on their authorization request (in addition to the fields required by OAuth 2.0 / OpenID Connect). Per the SMART “best practices” document at http://docs.smarthealthit.org/authorization/best-practices/#25-access-token-phishing-by-counterfeit-resource-servers, authorization servers should validate this field and use this same value for the aud claim in the granted access token.

Neither of these OAuth extensions are supported by Keycloak out-of-the-box (nor almost any other commercial Authorization server) and, for these reasons, the IBM team behind the IBM FHIR Server have introduced a set of Keycloak extensions that fill these gaps.

Using the Alvearie Keycloak Extensions for FHIR

The Keycloak extensions for FHIR project currently consists of two components:

  • keycloak-config for automating the configuration of a Keycloak realm in support of standalone app launch with patient context
  • keycloak-extensions which defines a set of extensions that fill the gaps in Keycloak’s support of SMART App Launch:
    • an AudienceValidator authenticator for validating that the aud parameter passed to the server matches the desired value
    • a UserAttributeMapper mapper for mapping user attributes into custom fields in the token response payload (rather than claims in the issued tokens)

To use the extensions:

  1. Build the keycloak-extensions project into a jar file and add it to the standalone/deployments directory of your Keycloak installation.
    • Note: moving forward, we hope to publish the built artifacts to Maven Central.
  2. Configure a realm in your Keycloak installation for SMART App Launch, either manually or via the keycloak-config project.
    • In addition to defining all the SMART scopes, the keycloak-config automation will create a default group called fhirUser (so that all new users will belong to it), and a Group Membership mapper for adding this group to the access token. This group detail is used to map users to a security-role in the IBM FHIR Server (described below). Group-Membership-mapper
    • The keycloak-config automation does not yet add a mapper for adding the patient parameter to the token response. To support that, add the User Attribute (with token response support) Mapper to the launch/patient scope and configure it to map a user attribute (e.g. resourceId) to the token response. patient-id-mapper
  3. Manually define a new Authentication Flow that requires Audience Validation before login. SMART-Authentication-flow
  4. Add your users and ensure they have a user attribute value that matches the one you mapped in step two. User-attribute

Configuring the IBM FHIR Server

Now that you have Keycloak configured, its time to hook up the IBM FHIR Server. The IBM FHIR Server supports OpenLiberty configDropins for configuring server behavior. To configure the server to validate Keycloak-issued tokens, modify configDropins/disabled/jwtRP.xml for you Keycloak installation and move it to configDropins/overrides/:

<server>
<!-- Enable features -->
<featureManager>
<!-- mpJwt-1.1 is already enabled in the default server.xml, but it doesn't hurt to repeat it here -->
<feature>mpJwt-1.1</feature>
</featureManager>
<!-- Override the application-bnd binding of the main webapp -->
<webApplication contextRoot="fhir-server/api/v4" id="fhir-server-webapp" location="fhir-server.war" name="fhir-server-webapp">

Additionally, to enforce the SMART scopes passed, the server must be configured with the fhir-smart persistence interceptor (by dropping the jar file into the userlib directory of your IBM FHIR Server installation).

Finaly, to advertise the SMART support and make the auth endpoints discoverable, update the security section of the fhir-server-config.json as described in the IBM FHIR Server User’s Guide:

...
"security": {
"cors": true,
"basic": {
"enabled": false
},
"certificates": {
"enabled": false,
"authFilter": {

Conclusion

In this post, we walked through the OAuth 2.0 extensions defined by SMART App Launch, how to support those extensions via the Alvearie Keycloak Extensions for FHIR, and how to use this project together with the IBM FHIR Server to support SMART App Launch.

SMART App Launch is just one of the specifications defined by SMART-on-FHIR and the authentication and authorization challenges in healthcare are immense. We’d love to hear from members of the FHIR community, the SMART-on-FHIR community, and the Keycloak community on the approach outlined here and where you’d like to see us go next. Please connect with us on chat.fhir.org, the Keycloak Extensions for FHIR project, or the IBM FHIR Server project about how we can take this to the next level.


SMART is a trademark of The Children’s Medical Center Corporation. FHIR® is the registered trademark of HL7 and is used with the permission of HL7. Use of the FHIR trademark does not constitute endorsement of this product by HL7. IBM and the IBM logo are trademarks of International Business Machines Corporation, registered in many jurisdictions worldwide. Other product and service names might be trademarks of IBM or other companies. A current list of IBM trademarks is available on https://ibm.com/trademark.