Stream: smart
Topic: Standalone app and patient id
Łukasz Dywicki (Apr 05 2018 at 20:15):
One of cases which I found underdocumented in the spec is patient identifier handling.
Per smart on fhir: http://docs.smarthealthit.org/authorization/scopes-and-launch-context/#standalone-apps
If I launch my application externally from EHR and attempt to access patient data in read only mode I have to specify patient/Patient.read
scope, but beside that there is a point about launch/patient
scope
Need patient context at launch time (FHIR Patient resource)
Arent these two are same, or very similar concept?
I would like also to share some observation about "Launch context arrives with your access_token"
Once an app is authorized, the token response will include any context data the app requested
This paragraph claims that token endpoint response, upon successful auth request, will have "patient" attribute. This single point blows up 95% of auth provider implementations at the start because most of them do not expect any extensions at this level. If patient
would be returned in token body this would cause no issues as token claims are extensible by definition.
Does anyone know how implementation of these looks a like in real life?
Pascal Pfiffner (Apr 06 2018 at 08:45):
Maybe this can clear up some of the confusion:
patient/Patient.read
is the scope that gives read access to Patient resource(s) that the patient has access to (oftentimes it's just the one Patient resource representing the patient)
launch/patient
tells the server that you want a patient context during launch/auth. While these often go together, they are logically separate concepts.
"Launch context arrives with your access_token": if you specify launch/patient
as one of your scopes, the response from the auth server could be something like: {"access_token": "abc", "expires_in": 1800, "patient": "123"}
. This means you expect a standard OAuth2 token response and in addition are given the patient id with the patient
key.
Does this help?
Christiaan Knaap (Apr 06 2018 at 18:27):
In Vonk we indeed require a "patient":"123" claim if there is any patient/... scope. Otherwise I think a user/... scope would be more applicable.
Emil Diaz (Nov 24 2020 at 22:45):
As @Łukasz Dywicki mentioned before, most auth providers will not support returning "patient": "123"
alongside the access_token
because it's not part of the standard OAuth protocol. Adding the patient
information as a claim to the access_token
or id_token
would make more sense, since it's (a) already supported by the OAuth standard and (b) secure because the patient
context will be part of a signed JWT token (making it tamper proof). Currently, the spec leaves the app exposed to man-in-the-middle attacks. Any proxy can inspect the response from the /token endpoint and change the value of patient
without any evidence of the tampering, because the value not signed by the Auth Server. Does anyone know if this topic has been discussed previously?
Łukasz Dywicki (Nov 24 2020 at 22:53):
Thanks for mentioning me @Emil Diaz , indeed adding extra attributes to standard OIDC/oauth endpoint is pretty tough but I learned how to overcome it at least with OIDC server I worked with back then. Its unfortunate that spec requires such way cause it increases maintenance cost.
So far I had no other feedback than yours in this regard, but on other hand I did not "push" for more answers.
Michele Mottini (Nov 24 2020 at 23:01):
Adding the patient information as a claim to the access_token or id_token
That would preclude the use of opaque access tokens and force the clients to know how to unpack and interpret them
Any proxy can inspect the response from the /token endpoint and change the value of patient
What would an attacker have achieved doing that? (beside breaking the app - that can be done as easily corrupting the access token)
Łukasz Dywicki (Nov 24 2020 at 23:07):
Adding the patient information as a claim to the access_token or id_token
That would preclude the use of opaque access tokens and force the clients to know how to unpack and interpret them
That's whole point of using JWT as a token format - it is a signed response whereas oauth server response is secured as long as we have SSL. I have no doubts that all production environments will have it.
Any proxy can inspect the response from the /token endpoint and change the value of patient
What would an attacker have achieved doing that? (beside breaking the app - that can be done as easily corrupting the access token)
It is open for man-in-the-middle attacks (when ss is gonel), cause you can't verify signature of response.
Łukasz Dywicki (Nov 24 2020 at 23:13):
For Keycloak you can use custom extension: https://igia.github.io/docs/igia-keycloak~introduction - it allows to add more attributes to token endpoint. Stolen from here: https://chat.fhir.org/#narrow/stream/179170-smart/topic/Keycloak.20for.20SMART.20authz/near/214317543
Emil Diaz (Nov 24 2020 at 23:28):
Well, the app is already expected to request the openid profile|fhirUser
scopes in order to determine the identity of the user and the URL of the FHIR resource that represents the user on the EHR:
http://www.hl7.org/fhir/smart-app-launch/scopes-and-launch-context/index.html#scopes-for-requesting-identity-data
That token is not opaque and could have also been used to add an additional patient
claim to provide the launch context.
@Michele Mottini I think you're correct, in that the attack surface is small here, since you wouldn't be able to leak data, only break the app. But wouldn't the app rather receive the patient context from the EHR in a form it can trust?
Michele Mottini (Nov 24 2020 at 23:29):
have no doubts that all production environments will have it.
No: this is CMS: "access_token": "X7WVkgCCl3SoCnb4NkR7EhbHZzXBKN",
But wouldn't the app rather receive the patient context from the EHR in a form it can trust?
At the cost of having to handle and validate JWTs instead of just reading a property? I'd say no
Michele Mottini (Nov 24 2020 at 23:34):
the app is already expected to request the
openid profile|fhirUser
scopes in order to determine the identity of the user
Yes, but most apps do not need the identity of the user (and there are servers that actually do not even implement openid fhirUser
)
Emil Diaz (Nov 24 2020 at 23:37):
Yes, but most apps do not need the identity of the user (and there are servers that actually do not even implement
openid fhirUser
)
Ah, that's the piece of information that was missing for me. I was under the impression that servers are required to implement these scope in order to claim conformance. Thanks for the clarification!
Michele Mottini (Nov 24 2020 at 23:38):
that servers are required to implement these scope in order to claim conformance
They are required, but some still don't support it (and most apps don't care)
Dan Cinnamon (Nov 25 2020 at 00:11):
As a quick note @Emil Diaz and @Łukasz Dywicki , I originally had some of the same questions about the /token behavior as you when i was getting started- as I'm also working with an authz server that would typically put this sort of data in a JWT.
I spoke with a colleague of mine who is very familiar with the OAuth2 specification and it's history, and he pointed out to me that this behavior is very much in line with the OAuth2 specification.
Looking at section 4.1.4 there is an example of additional parameters in the /token response (https://tools.ietf.org/html/rfc6749#section-4.1.4) - so having that extra patient id alongside the access_token is very much allowed in OAuth2 and is a valid way of communicating application level data when an opaque token is in use.
It's not really meant for access control though- the FHIR API still needs to apply proper API security once the access_token is introspected. So the worst thing an attacker could do is mess up the application display if they were to manipulate it.
In a nutshell, the SMART spec I've found to be very, very true to the OAuth2 specification as stated in RFC6749, and in the few areas I've found conflicts with my authz server's behavior, it's because of newer developments that have came out a bit later (like PKCE), or it's because my particular authz server has an opinion over/above the actual OAuth2 specification (like using JWTs). I hope that's helpful!
Emil Diaz (Nov 25 2020 at 00:16):
@Dan Cinnamon Thanks for the additional context! That's exactly what I'm finding right now, our Auth managed service provider restricts this behavior today, likely for the reasons I mentioned above. I will point them to the RFC section you mentioned and see what they say.
Last updated: Apr 12 2022 at 19:14 UTC