-
Notifications
You must be signed in to change notification settings - Fork 88
cross organizational auth
This document is a working draft of a OAuth 2.0 profile to support the EHR-to-EHR use case defined by The Argonaut Project.
This profile of OAuth 2.0 specifies the application programming interface (API) for the organization-to-organization exchange described in the Argonaut Project's use case 5. This profile enables an electronic health record (EHR) system in one organization to access FHIR resources managed by an EHR system in another organization, on a user's behalf.
The OAuth 2.0 Authorization Framework, RFC 6749, defines several methods of requesting authorization to access protected resources, all resulting in the issuance of an access token, which is then presented to retrieve the authorized resource. Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants, RFC7521, is an abstract extension to OAuth 2.0 that provides a general framework for the use of assertions (i.e., security tokens) as client credentials and/or authorization grants. JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants, RFC7523) profiles the OAuth Assertion Framework (RFC7521) to define an extension grant type that uses a JWT Bearer Token to request an OAuth 2.0 access token as well as for use as client credentials.
This Cross-Organization Data Access Profile implements OAuth 2.0 as described in these specifications to enable a requesting organization to obtain an access code using JSON Web Tokens to:
- Authenticate the requesting EHR (EHR-A)
- Request an OAuth 2.0 access token from the EHR holding the desired FHIR resource (EHR-B)
As described in RFC7523, an authorization JSON Web Token (JWT) bearer token is used to request an access token "when a client wishes to utilize an existing trust relationship, expressed through the semantics of the JWT, without a direct user-approval step at the authorization server." In the Argonaut use case, the trust relationship between the EHR authorization servers of the two exchanging organizations allows each to enforce local institutional policy within its own EHR context, while enabling access to FHIR resources in accordance with policy agreed upon between the two organizations. Essentially, access mediation occurs at two points:
-
When the EHR-A authorization server decides whether to grant an end user’s request for a cross-entity query of FHIR resources held by the EHR-B, and
-
When the EHR-B authorization server decides whether to grant EHR-A access to the requested FHIR resources.
Similarly, the EHR-to-EHR exchange involves two “client” entities – the “client” through which the end-user submits the request, and the EHR-A authorization server, which acts as a “client” in the exchange with EHR-B. The workflow through which the end-user requests a resource, and the process through which such request is mediated within an organization, are outside the scope of this specification. This specification focuses on the application programming interface through which an organization desiring a FHIR resource held by another organization requests and is granted (or denied) access.
The authorization JWT conveys the identity of the authenticated end user, and contains details about the FHIR resource to which EHR-A is requesting access. The authentication JWT is used to authenticate the identity of the EHR-A authorization server (as “client” to EHR-B). In advance of this exchange, EHR A will have registered its own identity and end-point URI with EHR B. The digitally signed authentication JWT confirms that the sender is the registered “client.”
While a single authorization JWT could be used for both purposes, this specification calls for the use of separate authentication and authorization JWTs to allow for potential future use cases wherein a third party might generate an authorization JWT that is presented by an EHR that is trusted by the data holder. Treating authentication and authorization as two separate claims enables support for such use cases under one consistent set of processing rules.
This specification does not address inter-organizational agreements or specific policies enforced by the organizations involved in the exchange.
This specification does not address the workflow involved in enabling an end-user to request an external resource, nor the workflow for presenting the retrieved resource to the end-user.
The Argonaut EHR-to-EHR use case states as a pre-condition that the requesting EHR knows the patient identifier used by the data holder to identify the individual whose data are being requested. Therefore, the design described here is silent about how patient matching is accomplished.
The two organizations that operate the EHRs involved in the exchange dictate the rules under which FHIR resources may be requested and accessed. Each EHR’s authorization server controls security-critical operations, including client registration, authentication, JWT validation, authorized scopes, and the structure and format of access requests. The implementation and management of the authorization server is critical to the protection of FHIR resources, and to adherence with any agreements in place between the two organizations sharing data.
The JWT assertions passed between the two organizations could contain protected health information or other privacy-sensitive information. Preventing unauthorized disclosure of such information requires security protection during transmission and storage, and a conscious effort to minimize the amount of information exchanged. Both organizations (end-users and technology) involved in the exchange should assure that the minimum amount of information necessary is requested and authorized.
The use of Transport Layer Security (TLS) to secure links between the two organizations protects against unauthorized disclosure of sensitive information in transit, and digital signatures protect against forgery of JWTs. Each organization will need to implement protections against denial-of-service attacks against exposed interfaces.
To protect against token forgery and interception, the FHIR resource server must validate the access token, and assure that the resource requested is within the bounds of the access authorized. Also, authorization servers and resource servers MUST use a combination of the JWT assertion ID (jti
) and issuance and expiration time attributes (iat
and exp
) to protect against replay attacks.
The strength of the security mechanisms incorporated in this profile is highly dependent upon encryption keys, as they are used to establish the TLS channel between entities and to digitally sign the JWTs. Effective key management policies and procedures are essential for both organizations. See NIST Special Publication 800-57, Recommendation for Key Management: Part I for guidance in this area.
- HL7 FHIR RESTful API
- FHIR resource conformance specification
- RFC2616, IETF Hypertext Transfer Protocol – HTTP/1.1
- RFC3986, IETF Uniform Resource Identifier (URI): Generic Syntax
- RFC5246, The Transport Layer Security Protocol, V1.2
- RFC6749, The OAuth 2.0 Authorization Framework
- RFC6750, The OAuth 2.0 Authorization Framework: Bearer Token Usage
- RFC6819, OAuth 2.0 Threat Model and Security Considerations
- RFC7515, JSON Web Signature
- RFC7517, JSON Web Key
- RFC7519, JSON Web Token (JWT)
- RFC7521, Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
- RFC7523, JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
- RFC7591, OAuth 2.0 Dynamic Client Registration Protocol
- JSON Web Algorithms (JWA): draft-ietf-jose-json-web-algorithms-14
This profile inherits terminology from the standards referenced above.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this specification are to be interpreted as described in RFC2119.
Table 1 below defines some of the terms defined in the standards referenced above and used in this profile specification. The definitions in the table are customized to apply to this specification and are not meant to supersede or modify the terms’ original authoritative definitions in the respective standards.
|Term |Description |
|------|----------|------------|
Access token | A token that EHR-B issues to EHR-A (as client to EHR-B) and which EHR-A then passes to EHR-B's FHIR resource server as proof of access authorization.
Authorization server | A server that implements the OAuth 2.0 endpoints, and issues authorization tokens to clients. In this specification, EHR-A's authorization server, having authorized an internal request for an external FHIR resource, then acts as a client to EHR-B's authorization server to present the request on behalf of the end user.
Bearer token | A security token with the property that any party in possession of the token (a "bearer") can use the token in any way that any other party in possession of it can. Using a bearer token does not require a bearer to prove possession of cryptographic key material (proof-of-possession). EHR-B mediates requests for authorization received from EHR-A, and if the request is authorized, EHR-B issues a bearer token to EHR-A.
Client | A software entity that requests OAuth access tokens from an authorization server.
FHIR resource | A health-information resource defined using the HL7 FHIR standard.
Token endpoint | The EHR-B authorization server endpoint to which EHR-A submits authorization and authentication JWTs in order to receive access tokens.
The sequence diagram below provides more detail regarding the transactions identified above. The numerals in the diagram correspond with the enumerated steps below the diagram.
Note that prior to the start of this sequence, an end-user of an EHR-A clinical application has requested access to a FHIR resource held by EHR-B, and the EHR-A authorization server has agreed to act on the end-user's behalf in requesting the resource. How the end-user requests access, and the policy and workflow involved in mediating the request are outside the scope of this profile.
-
An end-user of the EHR in the requesting organization (EHR-A) initiates a request, the details of which are outside the scope of this specification.
-
EHR-A's authorization server prepares and digitally signs each of two JWTs: one describing the access for which authorization is being requested, and the other authenticating EHR-A's own identity (as pre-registered with EHR-B).
-
EHR-A posts the two JWTs to EHR-B's API for requesting access to FHIR resources.
-
EHR-B's authorization server validates each of the JWTs and mediates the access against organization B's policies.
-
If access is denied, EHR-B returns a denial response, with an explanation.
-
If the requested access is allowed, EHR-B's authorization server generates an OAuth 2.0 bearer access token specifying the access authorized (which may be different from that requested).
-
EHR-B returns the access token to EHR-A.
-
EHR-A presents the access token to EHR-B's FHIR resource server.
-
EHR-B's FHIR server validates the access token and assures that it authorizes access to the resource being requested.
-
If the token cannot be validated, or the resource authorized is different from the resource being requested, EHR-B FHIR server returns a denial response.
-
Else EHR-B FHIR server returns the authorized resource to EHR-A.
-
EHR-B FHIR server records the release of the resource as a disclosure of PHI.
In advance of the exchange profiled in this specification, the EHR-A authorization server MUST register with the EHR-B authorization server. If EHR-B chooses to implement dynamic registration, it is RECOMMENDED that the implementation be in accordance with RFC7591.
The EHR-A authorization server SHALL have been issued a public/private key pair for use in digitally signing the JWT requests. The EHR-A authorization server SHALL have registered its public key with EHR-B by either sending the public key directly in the jwks
metadata field or by registering a jwks_uri
that MUST be reachable by the EHR-B authorization server. It is RECOMMENDED that EHR-A register its key using a jwks_uri
if possible as this allows for key rotation more easily. The jwks
field or the content available from the jwks_uri
of a client MUST contain a public key in JWK Set format.
OAuth 2.0 authorization and resource servers MUST conform to applicable recommendations found in the Security Considerations sections of RFC6749 and RFC6819. EHR-B servers MUST protect all communications to and from their OAuth endpoints using TLS as specified in RFC5246. Minimally, the EHR-B servers MUST authenticate themselves to the requester (EHR-A). Authentication of the EHR-A TLS endpoint is OPTIONAL, depending upon the policy enforced by EHR-B.
The EHR-B authorization server MUST publish a conformance statement as defined in the FHIR resource conformance specification. The conformance statement describes the features implemented in the server, and the rules with which an application needs to conform.
The conformance statement MUST identify the following OAuth 2.0 endpoints:
-
issuer
: The fully qualified issuer URI of the server -
token_endpoint
: The fully qualified URI of the server’s token endpoint
Example conformance statement:
{
"resourceType": "Conformance",
...
"rest": [{
...
"security": {
"extension": [{
"url": "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris",
"extension": [{
"url": "token",
"valueUri": "https://my-server.org/token"
}]
}],
...
The authorization request SHALL BE a JWT, as defined in RFC7519 and SHALL contain the details the EHR-B authorization server will need to know in order to mediate the request for access to a FHIR resource. The HTTP parameters for transporting the authorization JWT from the EHR-A authorization server to the EHR-B authorization server's token endpoint SHALL BE as defined in The OAuth Assertion Framework RFC7521, with the following specific parameter values and encodings (as shown in the sequence diagram above):
- The value of the "grant_type" MUST BE "urn:ietf:params:oauth:grant-type:jwt-bearer."
- The value of the "assertion" parameter MUST contain a single signed authorization JWT.
Example:
POST body:
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&
assertion={signed authorization JWT}&
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&
client_assertion+{signed authentication JWT}
The authorization JWT MUST be digitally signed by the EHR-A authorization server as specified in RFC7515, JSON Web Signature, using the private key counterpart to the public key registered with EHR-B. The EHR-B authorization server MUST support the RS256 signature method and MAY use other asymmetric signature methods listed in JSON Web Algorithms (JWA): draft-ietf-jose-json-web-algorithms-14.
Upon receipt, the EHR-B authorization server MUST validate the digital signature and MUST reject authorization JWTs with an invalid digital signature. The algorithm used to validate the signature, and the mechanism for designating the secret used to generate the signature, are outside the scope of this specification.
The authorization JWT SHALL contain claims relating to the resource being requested (e.g., FHIR patient resource, data scope, requesting practitioner, reason) and claims necessary to help ensure the security of the exchange (expiration time, issuer, subject, a token identifier; see RFC7523 for details):
Claim | Priority | Description |
---|---|---|
iss | REQUIRED | Requesting EHR's issuer URI. |
sub | REQUIRED | EHR-A's id for the user on whose behalf this request is being made. Matches requesting_practitioner.id
|
acr | REQUIRED | Level of assurance of the requesting user's identity (e.g. NIST level 0-4, as defined in NIST SP 800-63-2) |
aud | REQUIRED | EHR-B authorization server's "token URL" (the URL to which this authorization JWT will be posted) |
requested_record | REQUIRED | The FHIR patient resource being requested |
requested_scopes | REQUIRED | Patient data being requested |
requesting_practitioner | REQUIRED | FHIR practitioner resource making the request |
reason_for_request | REQUIRED | Purpose for which access is being requested |
exp | REQUIRED | Expiration time integer after which this authorization JWT MUST be considered invalid; expressed in seconds since the "Epoch" (1970-01-01T00:00:00Z UTC). This time MUST be no more than five minutes in the future. |
kid | REQUIRED | Key id of the encryption key used to digitally sign this token |
jti | REQUIRED | A nonce string value that uniquely identifies this authorization JWT. MUST have at least 128 bits of entropy and MUST NOT be reused in another token. EHR-B MUST check for reuse of jti values and MUST reject all tokens issued with duplicate jti values. |
iat | REQUIRED | The UTC time the JWT was created by EHR-A. |
{
"iss": "https://ehr-a.com",
"sub": "128641521",
"aud": "https://ehr-b.com/token",
"acr": "http://nist.gov/id-proofing/level/3",
"jit": "some-nonce-abc",
"iat": 1418698788,
"exp": 1422568860,
"requested_record": {
"resourceType": "Patient",
"name": {
"text": "Pauline Smith",
},
"address": {
"postalCode": "94118"
}
"gender": "female",
"birthDate": "1970-05-18"
},
"reason_for_request": "treatment",
"requested_scopes": "patient/*.read",
"requesting_practitioner": {
"resourceType": "Practitioner",
"id": "128641521",
"identifier": [{
"system": "https://ehr-a.com",
"value": "123"
},{
"system": "https://nppes.cms.hhs.gov/",
"value": "1770589525"
}],
"name": {
"text": "Juri van Gelder"
},
"practitionerRole": [{
"role": {
"coding": [{
"system": "http://snomed.info/sct",
"code": "36682004",
"display": "Physical therapist"
}]}}]}}
The authentication JWT SHALL BE a JWT as defined in RFC7519 and SHALL contain the details the EHR-B authorization server will need to know in order to authenticate the identity of the EHR-A authorization server. The HTTP parameters for transporting the authentication JWT from the EHR-A authorization server to the EHR-B authorization server's token endpoint SHALL BE as defined in The OAuth Assertion Framework RFC7521, with the following specific parameter values and encodings (as shown in the sequence diagram above):
- The value of the
client_assertion_type
is "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" - The value of the
client-assertion
parameter MUST contain a single signed authentication JWT
The authorization JWT MUST be digitally signed by the EHR-A authorization server as specified in RFC7515, JSON Web Signature, using the private key counterpart to the public key registered with EHR-B. The EHR-B authorization server MUST support the RS256 signature method and MAY use other asymmetric signature methods listed in JSON Web Algorithms (JWA): draft-ietf-jose-json-web-algorithms-14.
Upon receipt, the EHR-B authorization server MUST validate the digital signature and MUST reject authorization JWTs with an invalid digital signature. The algorithm used to validate the signature, and the mechanism for designating the secret used to generate the signature, are outside the scope of this specification.
The EHR-B authorization server MUST use a combination of the JWT ID (jti
) and the issuance and expiration parameters (iat
and exp
respectively) to detect any attempts to replay authorization JWTs. The EHR-B authorization server SHOULD reject authorization requests that have been previously processed and those received outside the time window within which they remain valid.
The authentication JWT SHALL contain the following claims. Note the similarity to claims in the authorization JWT, except that sub
here represents EHR A's client_id
-- not the user on whose behalf the request is being made.
Claim | Priority | Description |
---|---|---|
iss | REQUIRED | Requesting EHR's issuer URI; i.e., the EHR-A authorization server's URL |
sub | REQUIRED | The OAuth client_id by which EHR-B knows the EHR-A authorization server |
aud | REQUIRED | EHR-B authorization server's token_URL (the same URL to which this authentication JWT will be posted) |
expires_in | REQUIRED | The expiration time (integer number of seconds since from 1970-01-01T00:00:00Z UTC), after which this authentication JWT MUST BE considered invalid. This time MUST BE no more than five minutes in the future |
jti | REQUIRED | A nonce string value that uniquely identifies this authentication JWT. MUST have at least 128 bits of entropy and MUST NOT be reused in another token. EHR-B MUST check for reuse of jti values and MUST reject all tokens issued with duplicate jti values. |
kid | REQUIRED |
Key_id of the keypair used to digitally sign this token |
iat | REQUIRED | The UTC time the JWT was created by EHR-A. |
The EHR-B authorization server SHALL return either a JSON structure that includes an access token, as defined in RFC6749 and RFC6750, or a message indicating that the authorization request has been denied.
The JSON structure includes the following parameters:
Parameter | Priority | Description |
---|---|---|
access_token | REQUIRED | The access token issued by the EHR-B authorization server |
token_type | REQUIRED | Fixed value: Bearer |
expires_in | RECOMMENDED | Lifetime in seconds of the access token, after which the token SHALL NOT be accepted by the resource server |
scope | REQUIRED | Scope of access authorized. Note that this can be different from the scope requested by EHR-A. |
The parameters are included in the entity-body of the HTTP response, as described in section 5.1 of RFC6749 and RFC6750. The access token is essentially a private message that EHR-B's authorization server passes to EHR-B's FHIR Resource Server, telling the FHIR server that the "message bearer" has been authorized to access the specified resources. Defining the format and content of the access token is left up to EHR-B.
EHR-B authorization server's response MUST include the HTTP "Cache-Control" response header field with a value of "no-store," as well as the "Pragma" response header field with a value of "no-cache." EHR-A MUST protect the integrity and sensitivity of the access token at the TLS endpoint, and assure that it is accessible only as authorized.
Establishing the lifetime of the access token is the responsibility of the EHR-B authorization server, but as a guideline, cross-organizational access tokens SHOULD have a valid lifetime no greater than one hour.
A large range of threats to bearer tokens can be mitigated by digitally signing the token as specified in RFC7515 or by using a Message Authentication Code (MAC) instead. Alternatively, a bearer token can contain a reference to authorization information, rather than encoding the information directly into the token itself. To be effective, such references must be infeasible for an attacker to guess. Using a reference may require an extra interaction between the resource server and the authorization server; the mechanics of such an interaction are not defined by this specification.
Refresh tokens are not supported in this profile.
EHR-A SHOULD present the access token to the EHR-B FHIR server by issuing a FHIR API call to the FHIR endpoint on EHR-B's resource server. The request MUST use the Authorization Request Header Field with the "bearer" HTTP authorization scheme as defined in RFC6750 to present the access token to the EHR-B FHIR Resource Server. The authorization
header MUST identify the access_token
as a "bearer" token:
Authorization: Bearer [access_token]
(Note that in a real request, access_token
is replaced
with the actual token value.)
For example:
GET https://ehr/fhir/Patient/123
Authorization: Bearer i8hweunweunweofiwweoijewiwe
{
"resourceType": "Patient",
"birthTime": ...
}
The EHR-B FHIR resource server MUST support bearer tokens passed in the Authentication Request Header Field as defined by RFC6750. The EHR-B FHIR server MAY support the Form-Encoded Body Parameter or URI Query Parameter methods defined in RFC6750.
Authorized requests MUST BE made over TLS, and EHR-A MUST authenticate the EHR-B FHIR Server as part of the TLS set-up. The EHR-B FHIR server MAY require that EHR-A authenticate itself as well.
The EHR-B FHIR Resource Server MUST ensure that the token has not expired and MUST reject expired access tokens. If the access token is signed, the EHR-B resource server MUST validate the digital signature and MUST reject access tokens signed with an invalid digital signature. The algorithm used to validate the signature, and the mechanism for designating the secret used to generate the signature, are outside the scope of this specification.
If the EHR-B resource server rejects a token for any reason, it MUST return a message to the EHR-A authorization server indicating the reason for rejection. The message MUST NOT disclose any protected health information.
The EHR-B resource server MUST assure that the specified scope covers the requested FHIR resource(s), and MUST NOT return any resources beyond those authorized in the access token.