SMART – Security

So in the last post we went into some details concerning a specific SMART scenario – where a web based application is launched from the EHR (technically an EHR launch as described below). Let’s take a step back and take an overview of SMART as a whole, including some the other ways it can be used.

One way of looking at SMART is to think of it from 3 distinct perspectives:

The Security Profiles / Authorization part – how a client application can safely access patient specific data in the repository (safely in the sense that the Resource Server is satisfied that it is appropriate to release the requested data, and/or to accept updates to the identified user). This is the OAuth2 / OpenID Connect part. We’ll include the ‘modes’ of access in this discussion – what SMART refers to as the ‘Launch Mode’

The Scope of access – or what data and functions ares available to the client application. There’s actually a negotiation that occurs during authorization – the client application asks for access to a specific set of the patient data (Could be all, could be just observations etc.) and the operations it wants to perform against those resources, The Authorization Server decides if that information should be given to the current user.

This does have some overlap with the concept of privacy, though Privacy is more extensive. For example the Authorization Server may give a client access to Conditions, but the Resource Server may only supply a subset of those conditions, as some are sensitive and the policy engine restricts access.

This is also an OAuth2 concept.

The Data and API part. Having been authorized to access the patients data, what is the API to use to get or update that data, and how will it be represented (This includes the ‘bindings’ to terminologies).

This is the FHIR part, and we’ll need to think about FHIR profiles here.

Each one of these is a large topic, so we’ll consider security aspects here, and do the others later. Note this is by no means a comprehensive discussion on security – rather just calling out a few things of particular interest from the developer perspective in the context of SMART. (I am not a security expert – rather a developer with a desire to implement secure FHIR based applications).

Launch Mode

SMART defines two ways in which a SMART client can be initiated, and these have an impact on the details of how authentication is performed.

  • The EHR launch assumes that the app is launched from within the EHR. For example there is a button (or some other link) within the EHR that will start the client application. In this mode, the user and (possibly) patient have already been identified, making the user experience more streamlined. This was the scenario that we went into detail last time.
  • The standalone mode allows an externally started application to access the EHR data. In this mode the user will need to authenticate to the EHR, and will also need to be allowed to select the patient (the details of this ties in with scopes – more in the next post).

A web application could operate in either of these modes, while a mobile application will generally be in standalone mode (unless the EHR is running on the mobile device of course).

The big difference between the two is that in the EHR launch mode, we know the user (and possibly the patient), but in the standalone mode we don’t know either. This means that in the standalone launch there must be some way that the user (as well as the app) can authenticate themselves to the EHR. SMART doesn’t go into any detail about how that is to be done – it regards that as an implementation detail that can vary across different sites and OAuth2 offers a number of possibilities:

The simplest is that when the app is re-directed to the Authorization Server within the EHR (recall that it gets the url from the conformance resource), the Authorization Server requires the user to log in – possibly using the same login functionality as for a normal EHR user. All it needs to do is redirect to the login form, and for the login form to redirect back to the Authorization Server after a successful login. There won’t be a valid ‘launch’ token in the request so the Authorization Server can easily distinguish between standalone and EHR launched applications. (We might have glossed over some of the details 🙂 )

Refer to step 3 in the diagram in the previous post for details.

An alternative could be to use an external Authorization server that the EHR trusts. The external Authorization Server performs the authentication and issues the authorization code and subsequently the access token. The Resource Server in the EHR then uses that access token to validate a request. There needs to be some way for the Resource server to ‘trust’ the access token – it could be signed with the Authorization Servers public key, or there could be a separate back channel between EHR and Authorization Server – it’s up to the implementation.

Another complication though is that even if the users identity has been ‘asserted’ by the trusted Authorization Server, the EHR (or Resource Server) still needs to apply privacy policies to the request (which can be down to the individual resource level) – and that implies either a common identity source for the user, or some way passing the user identity back to the Authorization Server.

These are issues that are being discussed in the community at the moment – the HEART project seems to be a focus for this, so this is a good time to get involved if you have these sorts of needs or an opinion on how they should be done.

But for implementers, the current SMART approach of having the Authorization Server as part of the EHR makes it easier to get started.

It’s also worth pointing out that the standalone mode of SMART is really no different to the general case of an external client accessing a FHIR based API. In other words, assuming that you want to protect your API then SMART provides a standardized way to do this.


Shouldn’t really need saying, but any exchange of real patient data must be over a secure connection – i.e. HTTPS (or TLS). And note that in some jurisdictions this goes even further, requiring that any query that contains PHI (Personal Health Information) cannot use GET, but must use POST – the main reason this is to prevent that PHI being recorded in Server logs and Browser caches. FHIR offers the _search query mechanism to support this.


This is not really related to SMART, but if you are writing an HTML based application, then you will likely be making HTTPS calls from the browser to the server, usually using javascript. This will generally violate the ‘same origin’ policy and so the EHR server will explicitly need to support this – most commonly using CORS. Fortunately, this is quite simple for a server to do – effectively it adds a few HTTP headers saying ‘it’s OK for code in pages served from other servers to call me’.

Public vs Confidential applications.

SMART divides applications into two categories depending on whether they are able to keep a token secure (this comes from the underlying OAuth2).

  • A web app has the ability to be confidential if it saves the token in a safe area on the web server that is only available by server side code. If it stores the token in, say, a browser store then it is not confidential
  • Public apps are all the others. In particular a mobile device is a public application as the device can be stolen

It’s not entirely clear what the effect of this difference is – other than the fact that the access token can last for longer. It does change the authorization workflow, so it seems simplest from the perspective of the server to assume that all clients are public.

Patient Access

Supporting Patient access to their data isn’t specifically a security issue, but it’s a question that is likely to increasingly asked and there isn’t yet a definitive answer.

A simplistic answer is that from the perspective of the EHR, the patient is simply another user – albeit one in a specialized role (and not one that the EHR has had to accommodate until recently). So provided that the patient has an account with the EHR in the appropriate role then it’s just a matter of authenticating in the same way as a clinician user. The EHR would likely restrict access to that persons records only (based on their role as a patient) plus any other security policies that may be in place (a common one being that access to lab data has to be ‘released’ by the orderer). More sophisticated functionality is possible of course.

But this is a model that is unlikely to scale. Does an EHR really want to have to create and maintain a user account for all of its patients? Seems unlikely. And users in general don’t like having lot’s of different accounts to remember – “why can’t I just use my google login”? This is where having an external Identity provider does make sense, and would provide a better user experience, but there are a lot of details to work out!

It’s certainly an area that is going to evolve over time.

General Notes

There are some general notes on security in the spec that is worth reading (and the page is likely to be enhanced over time).

And here’s a set of statements about apps that is short & to the point:

  • Apps MUST assure that sensitive information (authentication secrets, authorization codes, tokens) is transmitted ONLY to authenticated servers, over TLS-secured channels.
  • Apps MUST generate an unpredictable state parameter for each user session. An app MUST validate the state value for any request sent to its redirect URL; include state with all authorization requests; and validate the state value included in access tokens it receives.
  • An app should NEVER treat any inputs it receives as executable code.
  • An app MUST NOT forward values passed back to its redirect URL to any other arbitrary or user-provided URL (a practice known as an “open redirector”).
  • An app should NEVER store bearer tokens in cookies that are transmitted in the clear.
  • Apps should persist tokens and other sensitive data in app-specific storage locations only, not in system-wide-discoverable locations.

So that’s some notes on some of security aspects of SMART. If you are a supplier of a FHIR API, then it would make sense to align with this aspect of SMART as a step on the way to providing support for the standalone invocation pattern. Even if you don’t support the scopes components, using OAuth2 in this way makes sense.

Feel free to ask any questions here, or even better on the FHIR chat or SMART support group. (and both have the history of previous questions & answers)

Oh – and in the previous post I should have included a link to the Argonaut project where this stuff is being worked on at the moment.




About David Hay
I'm an independent contractor working with a number of Organizations in the health IT space. I'm an HL7 Fellow, Chair Emeritus of HL7 New Zealand and a co-chair of the FHIR Management Group. I have a keen interest in health IT, especially health interoperability with HL7 and the FHIR standard. I'm the author of a FHIR training and design tool - clinFHIR - which is sponsored by InterSystems Ltd.

3 Responses to SMART – Security

  1. Pingback: SMART – Scopes and Profiles | Hay on FHIR

  2. Pingback: SMART on FHIR Supports Safe Access to Healthcare Data - OH Blog

  3. Pingback: SMART on FHIR® Supports Safe Access to Healthcare Data | Lyniate

Leave a Reply

%d bloggers like this: