Enable a common set of scopes that can be used across UMA-based authorization and "vanilla OAuth 2.0" authorization in a consistent way. In particular, support a model where apps know which permissions they'll need and can get authorized, up-front, with all of those permissions explicitly (rather than attempting a FHIR operation, engaging in an UMA flow... and then repeating this process each time the app needs to issue a new query against the patient's clinical record). Effectively it's a way to standardize the logic by which an UMA resource server knows which scopes to register when it creates an authorization request with the authorization server. Plus a bootstrapping protocol to help determine protected resource URLs (which don't quite occur naturally in a FHIR-based API implementation).
For each user, the resource server registers user-level resource sets and (user, patient)-level with the UMA authorization server as follows:
A single resourse set indicating "this user's access to any medical records she's allowed to see" -- user-level resource set
For each specific patient this user is allowed to see, a resource set indicating "this user's access to patient p's record" (user, patient)-level resource set
When an app wants to get access to an UMA-protected FHIR API endpoint, it will first need to determine a "UMA context url" that's scoped to a user, or to a (user, patient) tuple. This context URL is essentially a throwaway identifier indicating something like:
"John Smith's access to any medical records on this resource server" -- for a user-scoped context URL
"John Smith's access to his daughter Abigail Smith's record" -- for a (user, patient)-scoped context URL
Note that a resource server knows how to map its UMA context URLs to individual resource sets that have been pre-registered with an UMA server. But the mapping may be many-to-one, and a client application never learns this mapping. The process by which the app discovers an UMA context URL is not important -- but see "Resolution Service" below for one approach.
The app should, ahead of time, decide which FHIR scopes it needs in order to do
its job. For example, a Flu Clinic app might need to read allergies and write
immunizations, so it would need the scopes
To ask for these specific permissions the app initiates the following HTTP request:
POST /uma-context/29048298472385192382324848/authorize?scope=AllergyIntolerance.read%20Immunization.write Host: hospital.org ...
hospital.org server must understand this UMA context URL, and it must
already know which user or (user, patient) it is scoped to. The server then
maps this context to an internal UMA
resource_set_id that has already been
registered with the user's authorization server. In addition, it uses the
scope parameter requsted by the app to determine which scopes
register in a new request to the authorization server (which results in a
The standard UMA flow continues from here.
For apps that happen to be operated by a resource owner directly, we can offer a streamlined, standardized approach to resource "discovery", in the form of a redirect-based protocol. Something roughly like:
App learns which resource server to talk to -- e.g. by asking the user which
hospitals or clinics they want to connect to. For example:
This is an automated protocol for communicating an UMA context url to an app. It's never strictly needed -- the app could, for example, instead ask the user to paste in an UMA context url directly. Importantly, the resource url conveys no actual access privileges or identifying information
App redirects user-agent to
https://hospital.org/resolve-uma-context/patientwith query params
Resource server authenticates end-user. In the case of the
/userendpoint, an opaque per-user UMA context URL is established. In the case of the
/patientendpoint, an opaque per-(user, patient) UMA context URL is established. To help prevent apps from linking users by comparing UMA context URL, a good practice would be for the resource server to generate a new UMA context URL each time this flow occurs.
Resource server redirect user-agent back to
https://app?resolved=https://hospital.org/uma-context/29048298472385192382324848&state=123. At this point, the app has an opaque UMA context URL that's scoped to a user or (user, patient).