In some workflows, it may be necessary to have the user specifically authorize a FHIR transaction or even re-authenticate to complete the transaction. We have worked out a workflow that we call “transactional authorization” to address this that leverages the concept of scopes. This uses a new scope "transaction/X" where "X" is a transactional identifier understood by the EHR's AS and RS, and makes use of a standard signaling path for 403 errors.

  1. The request is submitted by the client; the RS determines that specific authorization (+/- user re-authentication) is required to process the request.
  2. The RS returns a 403 error as per RFC 6750 indicating insufficient scope for the current access token. The RS encodes the specific transaction within a new required scope that is communicated to the client in the response, e.g. ABCDEF is an opaque identifier for the transaction in question. The response might look like this:
        HTTP/1.1 403 Forbidden
        WWW-Authenticate: Bearer realm="example",
                error_description="Authorization is required to process this request",
  3. The client directs the user to the usual EHR AS authz endpoint to request the additional transaction-specific scope identified in the 403 response, e.g.
  4. The AS presents the appropriate dialog to the user based on the transactional identifier ABCDEF supplied in the request. This could be a simple confirmation dialog or require the user to re-authenticate based on the local business logic for the transaction in question. The AS could also display information about the requested transaction for the user to confirm.
  5. If successful, the AS returns an authorization code which the client then exchanges for a new access token as per the usual OAuth 2.0 flow. The new access token will allow the client to complete the transaction.
  6. The client repeats the request that initially generated the 403 error with the new token.
  7. The RS identifies that the new token is now sufficient for this transaction and processes the request.

Additional information could be included in as an OperationOutcome resource in step 2 but this is not required for the proposed workflow, as the response should provide the client app with enough information to proceed. Also, the example assumes an authorization code grant but this would also work for implicit grants.

This approach would take advantage of logic already present in some apps to request the additional scopes needed when the RS includes these scopes in the 403 response. Note that the transaction identifier could alternatively be passed as a separate parameter in the authz endpoint request, similar to how a client communicates the launch code back to the AS during a SMART launch, though including it right in the scope name does make it clearer that the scope requested is for a single transaction.