SMART on FHIR explained: how apps get secure access to health data

A key labelled SMART

SMART on FHIR is the standard way for an app to get permission to read, and sometimes write, health data through a FHIR API. Patient apps, clinician apps that launch inside the EHR, and back-end systems all use it. It is required by ONC's certification criteria for patient and population access, and by CMS's interoperability rules for payers.

This guide explains how SMART works and what a good implementation looks like.

Built on OAuth 2.0 and OpenID Connect

SMART App Launch builds on OAuth 2.0, the same standard behind "Sign in with..." buttons across the web, and OpenID Connect for identity. A FHIR server advertises its authorization endpoints at .well-known/smart-configuration, and apps discover them there.

Three ways to launch

The flow

  1. The app sends the user to the authorization server, with PKCE so an intercepted code is useless to anyone else.
  2. The user signs in and consents to the scopes the app asked for.
  3. The app exchanges the code for an access token, and usually a refresh token and an ID token.
  4. The app calls the FHIR API with the access token. The server checks the scopes on every request.

Scopes

Scopes say exactly what an app may do. patient/Observation.rs lets an app read and search one patient's observations; user/*.rs covers what the signed-in user can see. SMART v2 adds granular scopes, such as only laboratory observations: patient/Observation.rs?category=laboratory.

How Perfuse does it

An app, the authorization server and the FHIR API, with PKCE, consent, tokens and scopes

Perfuse is a free, Apache-2.0 healthcare integration engine with a built-in SMART on FHIR authorization server in front of its FHIR endpoint.

Around it, Perfuse brings the rest of what a secure FHIR service needs: SAML, OpenID Connect, LDAP, passkeys, SCIM and mutual TLS for staff sign-on, role-based access, an audit log of who changed what, and PHI access monitoring that spots unusual volume, after-hours and bulk access.

And behind the API sits a complete integration engine, converting HL7 v2, X12 and CDA into FHIR and US Core, so the data an app reads is current.

Get started

perfuse serve -smart-clients examples/smart/clients.yaml -smart-users examples/smart/users.yaml

Then point a SMART app, or Inferno's SMART test kit, at the FHIR endpoint. The manual covers every option.

Related: CMS-0057-F explained · TEFCA and UDAP explained.