Stream: smart
Topic: Refresh tokens
Josh Mandel (Mar 09 2020 at 16:45):
Looks like ONC's final rule doesn't give public clients the right to a refresh token -- this is a huge blow for pure-client-side apps like native mobile apps and HTML5/JS Web apps, and I'm frankly puzzled by it
FYI @Dan Gottlieb
Abbie Watson (Mar 09 2020 at 20:09):
Does it deny their use? Or simply not specify? If the EHR vendor choses to implement, that would be allowed, I'd assume?
Without the refresh tokens, it becomes a more transactional access model rather than a streaming 'always on' model. And probably will drive solutions towards having a PHR store, like Apple Health Records.
Josh Mandel (Mar 09 2020 at 20:33):
Overall, the rules just set a floor -- so nothing precludes use, but in real life, the regulatory floor is often as high as most parties climb.
Josh Mandel (Mar 09 2020 at 20:34):
Re: forcing solutions towards a PHR store, yes that's true, but it creates an uneven playing field for PHR stores, if big/important PHR providers can negotiate for refresh tokens, and others can't.
Isaac Vetter (Mar 10 2020 at 03:11):
Are you sure?
This includes the requirements finalized in §170.315(g)(10)(v)(A)(2)(i) that Health IT Modules presented for testing and certification must demonstrate that access is granted to patient data in accordance with the implementation specification adopted in § 170.215(a)(3) without requiring re-authorization and re-authentication when a valid refresh token is supplied by the application. It also includes the requirements finalized in § 170.315(g)(10)(v)(A)(2)(ii) that an application capable of storing a client secret must be issued a new refresh token valid for a new period of no less than three months.
Josh Mandel (Mar 10 2020 at 03:14):
See page 1174:
An application capable of storing a client secret must be issued a refresh token valid for a period of no less than three months.
Josh Mandel (Mar 10 2020 at 03:16):
in practice though I think the fact that refresh tokens are available for confidential clients will lead to one of two behaviors:
-
Developers will register native mobile apps as confidential clients, and simply distribute them with a static secret that isn't really a secret.
-
Developers will insert a "secure" web server into their process, rather than having the mobile app connect directly to EHR systems. This exposes more surface area to attackers without a security gain.
So if I were an EHR developer I would just allow public clients to get refresh tokens. The SMART specification allows it and ONC allows it (but does not seem to require it).
Isaac Vetter (Mar 10 2020 at 03:17):
(Oh, sorry, Josh, I misunderstood your original point -- I mistakenly thought you were saying that refresh tokens weren't being mandated at all).
Isaac Vetter (Mar 10 2020 at 03:20):
How is the outcome of your #1 different from allowing public clients to have a refresh token?
Josh Mandel (Mar 10 2020 at 03:21):
The outcome really isn't different; I think #1 just introduces ambiguity or confusion about whether things are secrets or not. When we first wrote the smart specification I wanted to avoid that ambiguity so I made it explicit that public clients would not be given fake secrets. The principle being: if something is labeled as a secret in your code and in the protocol then it should be kept secret :-)
Josh Mandel (Mar 10 2020 at 03:23):
Also from the perspective of the rules: #1 maybe involves app developers misrepresenting the capabilities of their apps to ensure that they can get refreshed tokens? I'm not sure on this.
Isaac Vetter (Mar 10 2020 at 03:24):
I totally agree with your principle. Your entire premise is that developers will act in bad faith. Have you read the comment/response section on dyn reg? That's the technical solution, here.
Josh Mandel (Mar 10 2020 at 03:25):
Dynamic registration would be a nice solution here, I agree! (My premise is not that developers would be acting in bad faith; it is that they would take the technical steps required to provide a reasonable user experience. Adding a web server to the mix clearly is not bad faith, but neither does it improve the security.)
Isaac Vetter (Mar 10 2020 at 03:26):
yes, that's true. Wasn't trying to besmirch you or our hypothetical patient app developer. :)
Josh Mandel (Mar 10 2020 at 03:26):
Also if I think about single device dynamic registration versus just using public clients on those devices, it's really not clear to me that the dynamic registration offers better security properties.
Isaac Vetter (Mar 10 2020 at 03:27):
where public clients means without persistent access? Yes. Totally.
Josh Mandel (Mar 10 2020 at 03:27):
In other words, the dynamic registration approach does let you keep a secret on the device, but does the secret really improve the security properties? It's generally stored in the same place is that the access tokens and refresh tokens and protected health data are stored...
Josh Mandel (Mar 10 2020 at 03:28):
In my comment above when I said public clients I just meant clients that could not keep a static secret; I think these clients are perfectly capable of maintaining persistent access.
Isaac Vetter (Mar 10 2020 at 03:28):
It's all about the length of data access and the requirement on the user to re-authorize. That's where the security actually lives (for clients that cannot "keep a secret").
Josh Mandel (Mar 10 2020 at 03:29):
The user experience is all about that, I agree. But basically any app architecture is capable of supporting refresh tokens, and I'm wondering why you would suggest that a dynamically registered mobile app provides better security when it comes to using those refresh tokens.
Josh Mandel (Mar 10 2020 at 03:30):
The issues you listed re: how long the data access lasts for and the requirement to reauthorize -- they apply equally to apps that can keep a secret and to apps that cannot.
Isaac Vetter (Mar 10 2020 at 03:31):
If a secret is confidential, it serves as a stand-in for the user re-authorizing.
Josh Mandel (Mar 10 2020 at 03:32):
I'm not sure I understand that
Josh Mandel (Mar 10 2020 at 03:32):
I could just as well say if a refresh token is confidential it stands in for the user reauthorizing
Isaac Vetter (Mar 10 2020 at 03:48):
isn't a refresh token typically communicated and, at least temporarily, stored on the insecure client, though? The basic premise here is that the client isn't secure (also, I feel super out of my depth arguing OAuth philosophy with you -- however, it also seems obvious to me that public clients shouldn't be trusted with persistent access).
Josh Mandel (Mar 10 2020 at 14:11):
The refresh token is stored wherever the access token is stored. This could be a client or a server.
Jenni Syed (Mar 10 2020 at 16:35):
To dyn reg aspects in relation to native apps - it limits the attack to the specific app install (since it's not a secret that will be shared with all installs). As you point out, that device has places to (typically) securely store data. But if you put a "shared" secret in that location, you've exposed the broader platform since there are ways to view that data with access to the physical device.
Josh Mandel (Mar 10 2020 at 16:43):
I agree with this exactly as you've stated, Jenni -- i.e., you've articulated exactly the benefit of dynreg. But in my estimation it's a pretty modest benefit; and given we have no production support for (or regulatory requirement for) dynreg today, it feels like quite a jump to say "this is what we need, in order to make native apps safe." We already have real-world native apps (e.g., Apple Health) that we trust to make persistent connections to the EHR (even without dynreg).
Jenni Syed (Mar 10 2020 at 16:50):
Correct, but Apple also correctly protects that secret as a confidential app. I agree that there's confusion about how to correctly set up a confidential app that can have long term access by providing credentials that prove they're the authorized owner of the refresh token
Jenni Syed (Mar 10 2020 at 16:51):
The public apps not having that capability and being tied to an active session goes with the idea that you're only able to protect that specific session and the app doesn't need that data after the user logs off
Jenni Syed (Mar 10 2020 at 16:51):
typically those types of apps also can't continue to call after they're shut down. Native apps get wonky depending on architecture.
Josh Mandel (Mar 10 2020 at 17:02):
Correct, but Apple also correctly protects that secret as a confidential app.
Can you clarify on this? My understanding is that connections go directly from phone to EHR (i.e. "public client", even if under the hood there's a "secret" issued). This is to say, no access tokens, authorization codes, refresh tokens, or PHI leaves the device, and there's no per-device secrets (no dynreg).
John Moehrke (Mar 12 2020 at 16:33):
We do not need to invent these rules. The IETF community already has "Best Current Practice" (bcp212) that has all kinds of these very important rules. We should just leverage that 'standard'... imagine that, a standards organization leveraging another standards organization . https://tools.ietf.org/html/bcp212
John Moehrke (Mar 12 2020 at 16:35):
and are drafting a best current practice for oauth security https://tools.ietf.org/html/draft-ietf-oauth-security-topics-09
Isaac Vetter (Mar 12 2020 at 16:41):
John, would you say that sections 8.5 and 8.6 are most relevant here?
https://tools.ietf.org/html/bcp212#section-8.5
Jens Villadsen (Mar 12 2020 at 21:42):
dyn reg scales awfully bad in products like Keycloak
Jenni Syed (Mar 13 2020 at 01:22):
I think we brought that bcp up/discussed it during one of our oauth threads... but may have ben daVinci? or another accelerator
Jenni Syed (Mar 13 2020 at 01:22):
Definitely has some good things
Michael Donnelly (Nov 17 2020 at 19:34):
Picking up on an old thread.
For a native app to do trusted dynamic client registration like Isaac, John, and Jenni describe above, the client will need to know where to find the register URL.
Michael Donnelly (Nov 17 2020 at 19:34):
Have we discussed this at all yet?
Michael Donnelly (Nov 17 2020 at 19:35):
It seems to make sense that it would be in the CapabilityStatement along with the auth and token endpoints. Is that right? If so, how would we identity it?
Josh Mandel (Nov 17 2020 at 19:38):
It's discoverable in the .well-known SMART configuration
Michael Donnelly (Nov 17 2020 at 19:38):
Oh, hey, there it is! :)
Michael Donnelly (Nov 17 2020 at 19:38):
For anyone who finds this later: http://hl7.org/fhir/smart-app-launch/conformance/index.html#using-well-known
Josh Mandel (Nov 17 2020 at 19:39):
http://hl7.org/fhir/smart-app-launch/conformance/index.html#declaring-support-for-oauth2-endpoints
Michael Donnelly (Nov 17 2020 at 19:39):
From 4.2.1
registration_endpoint: OPTIONAL, if available, URL to the OAuth2 dynamic registration endpoint for this FHIR server.
Michael Donnelly (Nov 17 2020 at 19:39):
Thanks Josh.
Michael Donnelly (Nov 17 2020 at 19:39):
@Kunal Shah this is what we were talking about earlier.
Last updated: Apr 12 2022 at 19:14 UTC