FHIR Chat · OAuth & subscriptions · subscriptions

Stream: subscriptions

Topic: OAuth & subscriptions


view this post on Zulip Lloyd McKenzie (Oct 25 2019 at 22:11):

Da Vinci is looking at using Subscription as a way to indicate that a response is ready (and so to come and get the result). We had a question about whether an OAuth token would be needed to establish the subscription and whether the OAuth token would need to still be valid for the subscription notification

view this post on Zulip Isaac Vetter (Oct 26 2019 at 03:11):

Hey Lloyd, at least a handful of us have thought alot about authnz and subscriptions.

view this post on Zulip Isaac Vetter (Oct 26 2019 at 03:11):

  • An OAuth token should definitely be required to establish a subscription
  • Authn for the subscription notification is murky. The simple technical/security approach is to use a [channel.payload.content](http://build.fhir.org/subscription) of either empty or id-only. (Meaning that an OAuth token would be required to retrieve PHI).

view this post on Zulip Isaac Vetter (Oct 26 2019 at 03:11):

Ultimately, the perception is that anOAuth token is trivial to acquire using the SMART Backend Services/OAuth2 client credentials flow in B2b scenarios and therefore we shouldn't shy aware from it.

view this post on Zulip Lloyd McKenzie (Oct 26 2019 at 03:30):

The backend services OAuth doesn't involve any patient authorization though. So the question is: once a patient gives authorization for data to flow, when does it time out (or how does a patient cancel it)?

view this post on Zulip Isaac Vetter (Oct 26 2019 at 03:35):

Lloyd, apologies, I didn't understand that this was a patient-mediated flow. Generally, the same advice applies --

  • An OAuth token should definitely be required to establish a subscription
  • A "callback" following a subscription notification would require patient authorization. Patient authorized apps will have long-term OAuth refresh tokens and patient portals should provide the ability for patients to revoke authorization.

view this post on Zulip Lloyd McKenzie (Oct 26 2019 at 03:57):

So the notion is that the patient portal would continue to refresh the token until/unless the patient tells it to stop?

view this post on Zulip Isaac Vetter (Oct 26 2019 at 04:01):

Yes, generally, the patient would preserve a refresh token

view this post on Zulip Lloyd McKenzie (Oct 26 2019 at 17:19):

It's probably not realistic for the patient to be involved on an ongoing basis, so some third party would have to manage renewing the token on the patient's behalf.

view this post on Zulip John Moehrke (Oct 28 2019 at 13:05):

I am not sure I understand the full impact, it is Murky... A Subscription involves three legs, yet I see only two being discussed so I am not sure if the second or third leg is being forgotten (or assumed to be okay). ( 1 ) request to subscribe, ( 2 ) notification, and ( 3 ) get of new data. There are subscription types that combine 2 and 3; that if that is what you are talking about then that needs to be discussed.

view this post on Zulip John Moehrke (Oct 28 2019 at 13:05):

The act of subscribing seems clear, but is not universally understood. The discussion around subscription usually does need to address the time-to-live difference between the token at subscription from how long the subscription stays active. This is usually resolved in that the request to subscribe is/was valid at the time the request was made, so all parameters of the subscription must be checked at that time. This check needs to also involve the notification pathway mechanics. This is not obvious to everyone, so does need to be expressed.

view this post on Zulip John Moehrke (Oct 28 2019 at 13:07):

The notification, if only a notification, can be risk-assessed to not need client authentication at all. As ( a ) the subscription said to use that notification mechanics, and ( b ) as purely a notification does not include any data outside the fact that something happened.

view this post on Zulip Gino Canessa (Oct 28 2019 at 15:17):

I'll preface with a note that I don't feel this area is fully resolved.

@John Moehrke, the three legs you specify do cover the basic flow. That said, there is sometimes a request for security on the second leg. So far, the approach has been to add an Auth header to a Subscription, which is passed along with notifications (e.g., so a destination can validate the notification is genuine).
It has some as-yet-unresolved issues (e.g., who can read/write the header, etc.), but does allow for basic validation on the notification (which could also be achieved with a parameter in the URL, but we felt this was more explicit).
As for the notification pathway, that is checked at the time a REST-hook subscription is created (e.g., set to requested and checked before being moved to active). Is there more clarity/description necessary there, or are you thinking of something else?
For other channels (e.g., websocket, email, etc.), the process would be different and we will likely punt to an implementer on what their process is (e.g., send an email asking to verify the address, ask the client to make a connection, or just move to active, etc. - just require it is described somewhere).

@Lloyd McKenzie, for renewing the token - our current recommendation is to use the Subscription.end field to time-out subscriptions (e.g., a Must Support for the Argonaut IG). If the subscription should be renewed, someone with the proper authorization needs to update the record with a new end date/time. This allows for an interested application to confirm that the user still wants the subscription active and there is no need for managing a refresh token on behalf of the user. Is this enough functionality, or is there something missing?

view this post on Zulip Lloyd McKenzie (Oct 28 2019 at 15:22):

I think the desired from the patient's perspective is that they're involved in the initial authorization and that the patient doesn't have to do anything unless they want the authorization to end. If they want the authorization to end, they would interact with one of the systems and subsequent requests would fail.

view this post on Zulip Lloyd McKenzie (Oct 28 2019 at 15:22):

It's not reasonable for the patient to be involved every time a request needs to flow or even on an intermittent basis

view this post on Zulip Gino Canessa (Oct 28 2019 at 15:36):

The patient would not need to be involved, as long as the application managing the subscription had a token. It would just be maintenance that an application would need to do (and conversely, if the patient wanted to stop receiving notifications, the application could go an disable/delete the subscription).

view this post on Zulip Josh Mandel (Oct 28 2019 at 15:37):

(And this dovetails well with ONC's proposal that patient-authorized apps should be able to request refresh tokens that maintain access over time, or until a patient revokes.)

view this post on Zulip Lloyd McKenzie (Oct 28 2019 at 15:40):

The use-case isn't a patient receiving notifications. This is a patient authorizing data to flow from system A to B. Essentially the patient needs to be involved in turning on the switch, after which the subscription should function either until a pre-determined end point (6 months, 1 year) or until the patient decides to end it sooner.

view this post on Zulip Lloyd McKenzie (Oct 28 2019 at 15:40):

My question is what the revocation process would look like

view this post on Zulip Josh Mandel (Oct 28 2019 at 15:40):

The use case here is "any patient-authorized app" (which in you case would be the "system B" app.

view this post on Zulip Josh Mandel (Oct 28 2019 at 15:42):

There's two paths to revocation, I think:

  • If a patient trusts system B to revoke its own access, they just indicate to System B that they want it to stop all access

  • Otherwise a patient uses system A's portal to review current access grants, and revoke (each patient portal has functionality like this built-in). After revocation, system A should stop allowing system B to access the patient's data.

view this post on Zulip Lloyd McKenzie (Oct 28 2019 at 15:50):

Portal = non-standard interface? I.e. there isn't a 'standard' way to revoke access, you just go to a website, navigate as that site dictates and click on the relevant buttons?

view this post on Zulip John Moehrke (Oct 28 2019 at 16:23):

the standards based model I heard explained is to revoke authorization at the oauth authority (which is usually a browser experience the patient has, call this a portal if you want, but humans must interact at the html level, not at the oauth transaction level), which relies on the notifiying app always having to renew the token prior to notification. That is the standards model... right?

view this post on Zulip John Moehrke (Oct 28 2019 at 16:24):

long-term tokens, that are renewed upon use, are the model oauth is based on. we should not try to invent FHIR specific security standards.

view this post on Zulip Gino Canessa (Oct 28 2019 at 16:25):

I believe what Josh is referring to is standard auth revocation... Whatever application was used to create the subscription can disable/delete a subscription on behalf of its user on its way out. If a user is requesting that in the app, it should honor that request. This would be the 'best' way, since it is the only process that allows every party to know that a subscription was removed and clean up their resources immediately.

If the user no longer wants to use the app even to delete access, then the user would need to use some other interface (e.g., the EHR portal, another app which can manage access, etc.) to revoke access.

In the cases where notifications do not contain PHI, removing the client is sufficient since the application will no longer be able to resolve a notification into anything useful. In time, the server will remove the subscription as well, which disables even the 'clean' notifications.

In the cases where a subscription notification contains PHI (e.g., full-resource), then there is currently no way to know that a subscription was created by a specific client and should be removed. I would assume that a portal could ask about items like that (e.g., you are revoking access, is there anything else that needs to be cleaned up), but it hasn't come up to my knowledge.

If you are asking about adding something to link a subscription to the client which created it, I'm happy to bring it up for discussion. We do have to be careful of putting fields on the subscription with things like 'which client created this' since knowing client IDs makes phishing attacks easier.

I feel like anything more than having the ID would be beyond the scope of subscriptions (and into security).

Or, are you asking for clarifying/guidance text on the issue to be included on this topic?

view this post on Zulip John Moehrke (Oct 28 2019 at 16:28):

agree that management of the subscription is done using FHIR Subscription CRUD. The authorization model needs to enhance this, not be used in place of this.

view this post on Zulip John Moehrke (Oct 28 2019 at 16:29):

Lloyd, what subscription type are you looking at... because we need to solve ONE model, not continue to circle around all possible subscription types

view this post on Zulip Gino Canessa (Oct 28 2019 at 16:29):

...the notifiying app always having to renew the token prior to notification...

This has not been discussed (to my knowledge). Adding this to the workflow would require servers save the refresh token, which also has security implications (e.g., can other users read my subscription and now impersonate me).

view this post on Zulip John Moehrke (Oct 28 2019 at 16:31):

you do not need (and should not) save the refresh token INSIDE the subscripiton resource. You save it someplace safe... that is to say I am assuming good systems design and that you are truely a confidential client (as a subscripiton manager server)

view this post on Zulip John Moehrke (Oct 28 2019 at 16:32):

right? surely we can set expectations for good systems design... We have plenty of these good systems design expectations on the fhir core security pages and the fhir core safety pages.

view this post on Zulip Gino Canessa (Oct 28 2019 at 16:50):

Yes, had a discussion offline here with Josh, and here's what we're leaning towards.

In the Subscription spec, put a notice in the Security section that:
- Auth should be checked prior to sending a notification
- Client ID / access tokens / refresh tokens / etc. cannot be stored in the subscription resource

In the Argonaut IG, we will draft out more of a workflow showing how an EHR can actually do this (e.g., when the subscription is created, track the client / user id in a secure manner, then validate prior to sending out a notification that the client and user are still valid, finally, when access is revoked, the subscription should be removed, etc.).

How does that sound?

view this post on Zulip John Moehrke (Oct 28 2019 at 17:00):

when the subscription type if web-hook.... right? As websocket, email, sms, and message would be different... right?

view this post on Zulip Lloyd McKenzie (Oct 28 2019 at 17:01):

Subscription would either be websocket or message

view this post on Zulip John Moehrke (Oct 28 2019 at 17:02):

websocket resolves itself, as all interactions are by the client... right?

view this post on Zulip John Moehrke (Oct 28 2019 at 17:06):

as in the websocket must prove that it is authorized to access the Subscription... normal client side request security

view this post on Zulip John Moehrke (Oct 28 2019 at 17:11):

messaging is more complex: messaging could be simple system-to-system messaging security; but I presume you want more specifics there too... seems an opportunity that needs a general solution... one general solution where message target is a user and not just an organization is just like rest-hook... as a message can be pushed just like anything can be pushed. All push models presume some pre-known knowledge on the target based on some trust-framework, so all start with a trust-framework... yeah, all possible models of complexity are in messaging without some trust-framework constraint.

view this post on Zulip Jenni Syed (Oct 28 2019 at 17:25):

This starts to get back into why most servers aren't sending PHI in the notifications. If we're assuming the access token for the notification is the same as reading the data - I think that's something we haven't done so far

view this post on Zulip Jenni Syed (Oct 28 2019 at 17:26):

That assumes that there's not a central system that may know how to do its own proprietary notification publication to apps downstream

view this post on Zulip Jenni Syed (Oct 28 2019 at 17:27):

This also would imply, possibly, that you need to check the context of each subscription. IE: if the user still has access to the data (the user that was on the token)

view this post on Zulip Jenni Syed (Oct 28 2019 at 17:27):

This is not trivial

view this post on Zulip John Moehrke (Oct 28 2019 at 17:27):

you still expose the ping... which says that for a GUID something happened.. so you do expose some pattern, but not much

view this post on Zulip John Moehrke (Oct 28 2019 at 17:27):

but I would agree that the notificaiton should be nothing but a ping

view this post on Zulip Lloyd McKenzie (Oct 28 2019 at 17:27):

In my scenario, I want the initial authorization to apply to the creation of the subscription and to subsequent reads (up until the expiry of the subscription or outright cancellation).

view this post on Zulip Jenni Syed (Oct 28 2019 at 17:27):

I think it's also an interesting assumption to assume the subscriber is the person reading data later

view this post on Zulip Jenni Syed (Oct 28 2019 at 17:28):

@Lloyd McKenzie for your case, that may be true. I'm not sure if it's always true

view this post on Zulip Lloyd McKenzie (Oct 28 2019 at 17:31):

So you'd be authorizing one app to create the subscription and a different app to query the data after receiving pings? (or possibly even a different 'set' of apps) Yes, I can see that use-case, though you're correct that it's not the one I currently have

view this post on Zulip Gino Canessa (Oct 28 2019 at 17:46):

Sorry, was at lunch.

view this post on Zulip Gino Canessa (Oct 28 2019 at 17:48):

@John Moehrke, yes and no. For WebSockets, we are still tinkering with the way of mapping connections and subscriptions. On first thoughts, disabling a subscription would have the same effect, and feels more consistent than trying to manage it at the channel layer. The same holds true for arbitrary (extensible) channels in my mind.

view this post on Zulip John Moehrke (Oct 28 2019 at 17:51):

So you'd be authorizing one app to create the subscription and a different app to query the data after receiving pings? (or possibly even a different 'set' of apps) Yes, I can see that use-case, though you're correct that it's not the one I currently have

The model where the notification is just a ping: The receive of the updated data is just a REST retrieve of data new since the last time one looked. So it is indistinguishable from any REST query.

view this post on Zulip Gino Canessa (Oct 28 2019 at 17:51):

@Jenni Syed, I can see what you are saying and I would prefer to leave that out of scope for this (e.g., it's a security issue, and thus needs different expertise to truly refine). I think there needs to be guidance as to 'yes, this needs to be considered' in the standard, and 'here are some basic considerations' in the IG, but am wary of doing more since it would be implementation specific. Does that work for you?

view this post on Zulip John Moehrke (Oct 28 2019 at 17:52):

an IG could certainly pick a security model... the core spec needs to leave many things unsaid... so, which are we working on here?

view this post on Zulip Gino Canessa (Oct 28 2019 at 17:53):

I've been working on both - hence why I'm trying to draw the line :-)

view this post on Zulip John Moehrke (Oct 28 2019 at 17:55):

for example IHE used subscription for functionality similar to HL7 v2 ADT... the notification was defined to be messaging, and the security model is either system-to-system (TLS), system-to-system (OAuth), or SMART. Given it was messaging, it is less likely anyone would try to group with SMART and have an interactive session on the notification transaction. Thus it is likely to be OAuth re-directed to a null endpoint and thus not authorized.

view this post on Zulip John Moehrke (Oct 28 2019 at 18:01):

In my scenario, I want the initial authorization to apply to the creation of the subscription and to subsequent reads (up until the expiry of the subscription or outright cancellation).

For your use-case where you are pushing the content in a FHIR Message, this is about all you can expect. The push of the FHIR Message would setup a security context for that messaging channel. Might be system-to-system using mutually-authenticated-TLS (Yes, this is very likely in organization to organization, where they already use this for v2 and soap). That is likely to not be a happy-path, so you want to use OAuth on the client, but OAuth can also be organizational (like bulk-data has spec). I would NOT expect this flow to use the user identity from the subscription requst, that is just strange, and requires so many bad security decisions.

view this post on Zulip John Moehrke (Oct 28 2019 at 18:03):

yes, I can understand a perspective that has the subscripiton manager being delegated rights to callback.. and you can build that Rube Goldberg machine ... just seems fought with opportunities for failure.

view this post on Zulip Gino Canessa (Oct 28 2019 at 18:06):

Yes. In the R5 redesign, those are all still possible. The specification allows for extensible channels, so any not already defined (REST-Hook, WebSocket, email) can be added (or if you want different behavior, define a new channel that uses the same type of channel). Many of the security details depend on the channel layer, so are out of scope for either the core spec or the Argonaut IG. Some of those could be notes in the area of channel extensions (e.g., here are some security issues to consider when making a new channel).

That said, I am hearing that there should be some expected behaviors for a subscription regardless of what the channel-specific details are.

For me, I am actively drafting changes for each of those documents, so if there's feedback on what makes sense I can add some text to the pass for review. Right now, there is nothing in either. I feel that there is consensus that there needs to be more than nothing, so I am trying to figure out what that looks like.

view this post on Zulip Gino Canessa (Oct 28 2019 at 18:08):

I would NOT expect this flow to use the user identity from the subscription requst, that is just strange, and requires so many bad security decisions.

How so (asking for clarification)? If a client is authorized to create a subscription for a patient/group/resource/etc, the server tracking that information and validating it is still true before sending a notification doesn't feel wrong to me in any context. What am I missing?

view this post on Zulip Gino Canessa (Oct 28 2019 at 18:11):

yes, I can understand a perspective that has the subscripiton manager being delegated rights to callback.. and you can build that Rube Goldberg machine ... just seems fought with opportunities for failure.

I don't think this has been proposed here (or if it has, I cannot see it).
The user/app which has received the notification would need to authenticate to perform its query the same way it would for any other query.

view this post on Zulip Gino Canessa (Oct 28 2019 at 18:15):

as in the websocket must prove that it is authorized to access the Subscription... normal client side request security

This is one of the challenges we are working to resolve. Websockets are often not part of 'normal client side security', and even when they are still face issues like revocation (e.g., was valid when I opened my socket, not anymore). It's a complicated issue that I don't think has enough real-world experience to check off yet.

view this post on Zulip John Moehrke (Oct 28 2019 at 18:18):

The security wg welcomes this discussion. Please feel free to approach us.

view this post on Zulip Gino Canessa (Oct 28 2019 at 18:24):

The security wg welcomes this discussion. Please feel free to approach us.

If there is a call/thread/etc. for this, please let me know and I would be happy to participate.

view this post on Zulip John Moehrke (Oct 28 2019 at 19:26):

see #Security and Privacy

view this post on Zulip John Moehrke (Oct 28 2019 at 19:26):

and the workgroup at https://confluence.hl7.org/display/SEC/Security+Work+Group

view this post on Zulip Josh Mandel (Oct 30 2019 at 18:02):

From today's Argonaut discussion, it's unclear whether existing server implementations have a good way to propagate access revocations across all the relevant subscriptions (in a fast/scalable fashion). The open design question that @Michael Donnelly @Jenni Syed and others are going to noodle on:

(How) can servers implement a Subscription/notification mechanism that..

  1. Allows long-term (month-long) subscriptions without further client interaction
  2. Allows user revocation that takes effect "quickly" (within, say, 1 hour)
  3. Is scalable / workable across real-world EHR implementations

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:07):

@Josh Mandel - just to clarify since we zoomed in on the patient app use case...

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:07):

Specifically the authorization we're tying to this is the specific user session?

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:08):

IE: if both I and my husband requested subscriptions on our family data using "MyCoolPhoneApp" - it's that the subscription is still authorized for me ?

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:08):

This is where I keep getting tripped up

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:09):

Since the app is authorized to see little bobby drop tables data from that same app, by different users...

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:09):

And none of those users is little Bobby.

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:11):

If so, this starts to imply that the authorization context by which the app subscribed is specifically tied to that instance of the subscription (something we had avoided to date)

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:11):

I'm not saying we shouldn't, but that we should agree this is the implication

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:13):

And if it is: is that restriction to any authorization of that application, or does it start to intersect with the session scope in SMART (offline, online, none)

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:14):

For subscription clients - what would your expectation be? What is the least surprising behavior here?

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:16):

I could likely look up if an app was still authorized for a specific site relatively easily before sending out subscriptions

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:16):

But I don't think that's the level of functionality that is being requested

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:16):

Looking up if any instance of a patient app is still authorized for a specific patient is more tricky

view this post on Zulip Jenni Syed (Oct 30 2019 at 18:17):

And then tying that subscription to the specific user or specific session (this goes back to the refresh token conundrum) start to get even more complicated

view this post on Zulip Josh Mandel (Oct 30 2019 at 19:00):

I guess from my perspective, the model is something like: each Subscription is created in the context of a specific authorization (knowable at creation time by looking at the access token used to create it). If that authorization is subsequently revoked for any reason, how do we make sure this propagates to subscription notifications?

To take your "MyCoolPhoneApp" example @Jenni Syed ,

if both I and my husband requested subscriptions on our family data using "MyCoolPhoneApp" - it's that the subscription is still authorized for me ?

Are you saying there's one subscription here for the whole family, like "All encounters for Patient 123,456,789"? If so, then either you created it, or your husband created it. If the creator revokes MyCoolPhoneApp's access, then the subscription should stop working. I might not be understanding your example , though.

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:13):

I was implying that there were likely 2 sessions - maybe 2 subscriptions, it would depend on how the app was planning on implementing it. What we determine here would guide how that app MUST behave

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:13):

To date, we only tracked the alert endpoint on a subscription, and what filters/topic

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:14):

it's possible that the subscription I described above for a mobile device could be sent to the actual device system and then sent to the appropriate device(s) via that phone's alerting mechanism - at least today

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:14):

And it could have been smart enough to know that I have 10 devices, and don't necessarily need 10 subscriptions

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:15):

since it's all 1 client id (this assumes we aren't registering specific instances of applications via dynamic reg, for eg)

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:16):

If, however, we tie it to the refresh token in play when the subscription is created, that implies that all 10 instances of the app for me would need to create and manage a unique subscription

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:16):

Tying it to just the filters/app isn't enough

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:17):

Tying it to just the patient id isn't enough

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:18):

It would have to be at least user, client, and then likely patient?

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:20):

So far, if we're assuming this is something the server takes on, it will also have implications/limitations on how the client app will need to behave. I'm trying to find a "not surprising behavior" middle ground

view this post on Zulip Josh Mandel (Oct 30 2019 at 19:22):

Jenni Syed: If, however, we tie it to the refresh token in play when the subscription is created, that implies that all 10 instances of the app for me would need to create and manage a unique subscription

I'm not sure I agree; the decision about how many endpoints to create and how many Subscriptions to create is up to the client. (But of course, the client must have permissions to create the Subscription, and must be prepared to deal with the consequences of revocation.)

view this post on Zulip Josh Mandel (Oct 30 2019 at 19:25):

On the revocations side, there's a spectrum of "conservative" things you could do to handle revocations (which presumable are relatively infrequent events, compared with approvals). I wouldn't want to specify too much about how this works.. but internally you might have a rule like "any time a user revokes any access from an app, all of the Subscriptions for that {app, user} are set to inactive." That's "conservative" because it might invalidate some subscriptions that don't need to be, but an app may be able to come back and re-enable them in response, after seeing missed heartbeats. (If you can fine-tune the inactivations, so much the better.)

view this post on Zulip Josh Mandel (Oct 30 2019 at 19:27):

For a client app, one expectation is to track heartbeats and notice (and take appropriate steps) when they stop.

view this post on Zulip Gino Canessa (Oct 30 2019 at 19:41):

I see this as a tuple for the authorization - a user and an app (acting on behalf of that user).

If a user account responsible for a subscription is disabled, I would expect notifications to halt.
If a user revokes access for an application, I would expect notifications to halt.

In the 'MyCoolPhoneApp' scenario, if the application is consolidating subscriptions and rebroadcasting (users 'A' and 'B' are linked in the app):

  1. 'A' creates subscription, 'MyCoolPhoneApp' access revoked on the EHR, no more notifications (feels fair)
  2. 'A' creates subscription, 'B' revokes access for 'A' on the EHR, no more notifications (feels fair, 'B' needs to setup a subscription)
  3. 'A' creates subscription, 'A' revokes access for 'B' on the EHR, 'MyCoolPhoneApp' still sharing (accounts were linked in the app, need to manage in app, feels fair)

There could be some confusion around 2., in that 'B' may not remember that 'A' was the primary user and revoking their access disabled the subscription, but I (personally) feel like this is a fair process (or at least better than arbitrarily allowing 'A' to continue receiving notifications).

I am confused about your comment about tying it to the patient id (@Jenni Syed). Isn't this process for evaluating access to a resource 'owned' by a patient based on the other two (e.g., this notification is for 'patient/123', does user 'A':'MyCoolPhoneApp' have access)?

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:42):

Ok, so be ready to delve into "user auth" since you tied it up there by "user account is disabled"

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:42):

We specifically and purposefully avoided requiring this in subscriptions today :)

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:42):

because that is just... a mess

view this post on Zulip Gino Canessa (Oct 30 2019 at 19:42):

puts on fins and mask

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:43):

There are so very many reasons the user can loose auth, and most of them aren't that the user isn't part of the system anymore :)

view this post on Zulip Gino Canessa (Oct 30 2019 at 19:43):

I agree that it's a mess. I don't think that we are trying to set out such concrete details here though. I am thinking on these as general security guidelines that need to be mentioned.

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:44):

The reason I said patient: In our system, we tie a consumer authorization (not practitioner, since they aren't authorizing the app) to a set of patients that they saw and confirmed they wanted to grant the app access to

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:45):

So even if I have access to my whole family, and the app uses "user" level scopes, the auth is locked down to who I had access to at the time of the auth request

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:45):

Since that is all I saw and authorized at the time

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:46):

Similarly, even if I have access to my whole family, the app may use "patient" level scopes, so I may choose myself or someone in my family specifically

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:47):

IE: from an oauth scope perspective, that session for a consumer is locked down to some set of patient ids

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:47):

So, I can have 5 people in my family. I could have 5+ different authorizations for that app to have access to different sets of patients on my behalf

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:48):

(this likely depends on how the underlying resource and auth server behaves)

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:48):

But that is just the auth viewable level

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:48):

In realtime access, we put many other authorization checks into play

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:49):

The easy ones: do you have access to this specific piece of data (either via scope or other privacy concerns)

view this post on Zulip Gino Canessa (Oct 30 2019 at 19:49):

That makes sense. My question would be, that during the course of adding subscription support, is it onerous to ask that a 'user' be checked at the time of the notification being sent (e.g., if the user was logging in now, would they be able to access that patient)? Or something like a check that runs once per hour (a delay in revocation would be expected in my mind) to disable a subscription, etc.?

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:49):

But, at any time during the lifetime of that offline access session, someone can lose access for many reasons

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:51):

1) revoked by the patient (actual action in the system),
2) minor aged out (no actual action in the system),
3) something happened to their account link (may have happened in the IDE and not in the local system)

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:52):

4) general system level privs were changed. IE: a specific facility is now marked as "psychiatric" - no direct action happened at the user config level

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:53):

We've seen all of the above in prod with consumer access today

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:53):

many times over

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:53):

so they're not "rare"

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:54):

And the "field" level data restrictions are even more difficult - you have partial access to a patients data. That can be resource level (all allergies) or instance level (some allergies) or even field level (reason for thing - eg: Diagnoses)

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:56):

And all of our favorites: Patient merge and unmerge/combine and uncombine

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:56):

All of these complexities are the main reason we have the no body or id only notification mechanisms today

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:57):

(also the concern with the endpoint you're calling getting hijacked/losing their domain/MITM/etc, but the user viewing it was a huge driver)

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:59):

Practitioner has similar concerns/complications, but in our system the added complexity of there being no concept of what "patients" are authorized (today) for access when the authentication dance happens, unless the app requested 1 patient only (launch/patient scope)

view this post on Zulip Jenni Syed (Oct 30 2019 at 19:59):

This is why I'm trying to decide how deep we want to go here

view this post on Zulip Gino Canessa (Oct 30 2019 at 20:08):

Yep. These are all difficult/tedious to work through. I guess my preference would be for us to set out some basic expected behaviors as guidelines, and go from there.

My concern is that even with 'no' PHI, the notification can still be considered as such. To use one of your examples, if a parent/guardian/etc receives a notification of activity from Planned Parenthood and they didn't go, it's easy to put together it is their now not-minor child that went.

My expectation would be that if a person can't access the resource in question, they shouldn't receive a notification. I would prefer not to go any deeper than that (beyond the minimum qualifications for that statement, like 'a server can specify how long before this takes effect', etc.).

Does that make sense? Or too far?

view this post on Zulip John Moehrke (Oct 30 2019 at 20:09):

Yep. These are all difficult/tedious to work through. I guess my preference would be for us to set out some basic expected behaviors as guidelines, and go from there.

My concern is that even with 'no' PHI, the notification can still be considered as such. To use one of your examples, if a parent/guardian/etc receives a notification of activity from Planned Parenthood and they didn't go, it's easy to put together it is their now not-minor child that went.

My expectation would be that if a person can't access the resource in question, they shouldn't receive a notification. I would prefer not to go any deeper than that (beyond the minimum qualifications for that statement, like 'a server can specify how long before this takes effect', etc.).

Does that make sense? Or too far?

I think that should be something that is checked upon setting up the subscription, not something expected prior to sending the notification... right?

view this post on Zulip Gino Canessa (Oct 30 2019 at 20:25):

@John Moehrke, I would make the argument that both should be applied.

A user should not be able to successfully create a subscription for resources they don't have access to. A user should also not receive notifications for resources they no longer have access to.

I do not think it is realistic at scale to do the full verification on every access . If access is checked every hour/day/etc. and revoked, that would meet my expectations (as long as the user is notified - this may take a few hours to propagate).

view this post on Zulip Josh Mandel (Oct 30 2019 at 20:37):

So the question here is: do EHR vendors have some reasonably efficient way to provide some close approximation to making revocations work on subscriptions. So far I'd summarize discussion as:

  1. It's complicated, with a lot of edge cases
  2. It's hard to enforce revocations immediately but there could be an opportunity to enforce them over a timescale of minutes to hours
  3. It's okay for servers to behave "conservatively" by invalidating subscriptions in some cases where it's not strictly necessary, as long as clients can detect/correct
  4. At the level of the standard or even an Argonaut IG, we don't want to describe all the edge cases; we'd describe general expectations and leave it up to server discretion to nail down the behaviors

view this post on Zulip Josh Mandel (Oct 30 2019 at 20:37):

^^^ Any deep concerns with the summary so far?

view this post on Zulip Lloyd McKenzie (Oct 30 2019 at 20:49):

For #3, clients detecting should be straight-forward. Not clear on how they can 'correct' if the initial authorization was provided by a patient and that patient is no longer avaialble.

view this post on Zulip Josh Mandel (Oct 30 2019 at 20:54):

(Yes, re #3 we should say "detect and, if applicable, correct". Like if a server conservatively knocked out all of a user's subscriptions in response to a narrow revocation.)

view this post on Zulip John Moehrke (Oct 30 2019 at 20:55):

I think what Jenni is pointing out is that there might need to be many models. Where the notification is just a poke, the notification is identified as a risk, a risk only of pattern. Where the notification is the content of the notificaiton then there MUST certainly be access control check pror to sending it.

view this post on Zulip John Moehrke (Oct 30 2019 at 20:56):

These are risk based... security geeks like that... while they are also setting a set of patterns that are reasonable, which architects like to choose from.

view this post on Zulip Josh Mandel (Oct 30 2019 at 20:57):

That makes sense John; is it inconsistent with my summary above?

view this post on Zulip John Moehrke (Oct 30 2019 at 20:58):

I am not sure it is always (1) complected... unless you are just saying that "security" is always complecated...

view this post on Zulip John Moehrke (Oct 30 2019 at 20:58):

if one is just poking in the notification, then the access control falls back to normal REST access control.. if you call normal REST access control hard to enforce immediately... then okay.

view this post on Zulip Josh Mandel (Oct 30 2019 at 20:58):

I mean, the complications seemed evident to me from the discussion above ;-)

view this post on Zulip John Moehrke (Oct 30 2019 at 20:59):

yup

view this post on Zulip Josh Mandel (Oct 30 2019 at 20:59):

"just poking" doesn't necessarily mitigate concerns when the presence of a poke is deeply revealing/undesirable (see Gino's examples above).

view this post on Zulip John Moehrke (Oct 30 2019 at 21:01):

that was my point on 'risk'

view this post on Zulip John Moehrke (Oct 30 2019 at 21:01):

you identify this as a risk of the poke model...

view this post on Zulip John Moehrke (Oct 30 2019 at 21:02):

some uses will find that risk very acceptable, others will not (like the given subscripiton from planned-parenthood)

view this post on Zulip John Moehrke (Oct 30 2019 at 21:03):

whle there i also a risk of sending the PHI in the notification.. usually quite a bit higher... but if the notification content is mundaine (valueset of loinc codes has revised)... then that risk might be acceptable too

view this post on Zulip John Moehrke (Oct 30 2019 at 21:04):

security/privacy considerations section is often just a list of 'considerations'... aka identification of risks without mitigation

view this post on Zulip John Moehrke (Oct 30 2019 at 21:04):

one never gets risk to zero... especially in an interop specification.

view this post on Zulip Josh Mandel (Oct 30 2019 at 21:04):

Yes -- I think we're saying the same thing here.

view this post on Zulip John Moehrke (Oct 30 2019 at 21:04):

(dancing)

view this post on Zulip Jenni Syed (Oct 31 2019 at 15:52):

Right - my point was that invalidating, for example, when the app itself is removed or access is revoked for that app is probably doable consistently. Once you start saying things like "or the user loses access" that is when it starts to become pretty tough to do consistently or completely

view this post on Zulip Jenni Syed (Oct 31 2019 at 15:53):

And that use case is generally where the other security mechanisms come into play: one which we're missing is even limiting what type of subscriptions a system can support (since the poke itself can give info away to varying degrees)

view this post on Zulip Jenni Syed (Oct 31 2019 at 15:54):

The guidance we were getting into was pretty targeted and "the server will do" vs more of a general security guidance and considerations section

view this post on Zulip Jenni Syed (Oct 31 2019 at 15:55):

But we should definitely say that the security context under which the subscription was created is assumed to be the context of the lifetime of the subscription. That is something that was not clear before, and has been discussed at other connectathons

view this post on Zulip Jenni Syed (Oct 31 2019 at 15:56):

Interestingly, for those sending full bodies of data, there is really no way for them to actually enforce that

view this post on Zulip Josh Mandel (Nov 04 2019 at 21:27):

Jenni Syed: Interestingly, for those sending full bodies of data, there is really no way for them to actually enforce that

Wait, no way for these servers to enforce ... what ?

view this post on Zulip Jenni Syed (Nov 04 2019 at 22:40):

That the data is only used under the same authorization context as it was originally subscribed with

view this post on Zulip John Moehrke (Nov 04 2019 at 22:54):

Seems we are getting upside-down. The requester OAuth token is authorizing the requester to have access to the data. The subscription manager checks that authorization applies to the requested subscription. If that same token is used to push the updated PHI to the notification endpoint provided by the requester; then one could present this as authorized. This because the subscription manager is simply enforcing the decision it was given.
My worry with this kind of token reuse is that the subscription notification endpoint can't validate that the data are from an authentic data holder, as that endpoint is never given identity of the sending side of that notification transaction. Thus it can't differentiate these notifications from unauthentic notifications.
This is why I am not a fan of using the requester OAuth token on the notification pathway (that is when the notification is carrying PHI and not just a poke)

view this post on Zulip Mohammad Jafari (Nov 05 2019 at 01:31):

I understand that since this is based on an extension of standard OAuth, it may not be a solution we're looking for, but in a similar (non-healthcare) project involving webhook-based subscriptions, we tweaked the authorization service (at the endpoint equivalent to OAuth Introspection) to return (among other things) the expiry date of the client's refresh token and then ensured that the webhook subscription is set to be valid no later than the expiry date of the client's refresh token. For example, if a client provided an access token which was valid for 10 minutes, and the authorization server records also noted that that the client is in possession of a refresh token valid until the end of the month, the latter date was used as the expiry date of the subscription.

I think if we think of a subscription as a form of pre-authorization for access instances scheduled for future, the main access control requirement here is to make sure the client is not able to schedule any access beyond the date-time at which its current authorization expires. I think the refresh token's expiry is a reasonable and practical upper bound for a client's authorization. The client can renew the subscription by an UPDATE or PATCH and by providing a new access token backed by a newer refresh token.

view this post on Zulip John Moehrke (Nov 05 2019 at 18:45):

Would like to memorialize some of these discussions, so am starting a confluence page as an informal place to write these. This is not to take the place of Change Requests, or formal Implementation Guide. Rather it is a way to get consensus to jumping to those solutions. Please contribute, and question content. (Note that I am proposing that this is a broader topic of callbacks, not just "Subscription" resource)
https://confluence.hl7.org/display/SEC/FHIR+subscriptions+security

view this post on Zulip Jenni Syed (Nov 05 2019 at 18:53):

To be clear: I am not stating that the OAuth token originally used is sent anywhere to the original caller. I think what is being discussed here is that the token/user/app in use (and all privs) when the subscription is created governs the data that can be sent/notified for that subscription

view this post on Zulip Jenni Syed (Nov 05 2019 at 18:53):

That doesn't require storage or maintenance of that token - but likely would require storage of metadata around the context it represented

view this post on Zulip John Moehrke (Nov 05 2019 at 18:57):

that is what I too was proposing. This does bring up a question about how the manager does identify to the callback endpoint... Easy would be by way of the manager TLS certificate, but many in http/REST hate client certificates

view this post on Zulip Gino Canessa (Nov 05 2019 at 19:06):

For validating the server, one idea we've started throwing around is having the server (optionally) sign messages with a public/private key pair (e.g., public key discoverable via capabilities statement).

view this post on Zulip Eric Haas (Nov 05 2019 at 19:24):

@John Moehrke

Easy would be by way of the manager TLS certificate, but many in http/REST hate client certificates

Can you summarize why it is hated?

view this post on Zulip Lloyd McKenzie (Nov 05 2019 at 19:32):

Certificate management requires quite a bit of infrastructure. It means installing certificates on every client, updating those certificates when they expire, etc. In closed, tightly managed environments it can be practical (though not necessarily easy). In open, loosely managed environments, it's near impossible.

view this post on Zulip Eric Haas (Nov 05 2019 at 19:33):

Hence why fhir messaging is so loathsome to many?

view this post on Zulip Eric Haas (Nov 05 2019 at 19:34):

@Lloyd McKenzie can I steal your explanation?

view this post on Zulip John Moehrke (Nov 05 2019 at 19:34):

Lloyd, I was very clear that the subscription manager will already have a TLS certificate, thus all the management is DONE. It is just using it in client mode for th ecallback

view this post on Zulip Eric Haas (Nov 05 2019 at 19:36):

@John Moehrke are you suggesting is not a housekeeping pain but a technical issue?

view this post on Zulip John Moehrke (Nov 05 2019 at 19:38):

yes, client certs in TLS do cause a problem at the server side... if you are using an API gateway or TLS acceleration.

view this post on Zulip John Moehrke (Nov 05 2019 at 19:38):

what I am saying is that the subscription manager must have a TLS cert so that it can have a HTTPS endpoint to receive the POST/GET of the Subscripiton request.

view this post on Zulip Gino Canessa (Nov 05 2019 at 19:39):

John, I don't think that's always true (that the manager will have a TLS certificate). If the server responsible for sending notifications is not the same as the server receiving external calls, there would be no reason to have one there.

It's also common to have a proxy handle the TLS and forward unencrypted requests within an internal network - in which case none of the servers have a cert installed.

view this post on Zulip John Moehrke (Nov 05 2019 at 19:46):

agreed

view this post on Zulip John Moehrke (Nov 05 2019 at 19:47):

I never said it was a good general solution. I don't think there are good general solutions.. just a bunch of options that each have a tradeoff

view this post on Zulip Gino Canessa (Nov 05 2019 at 19:58):

Fair enough. I think the challenge will be in what we can suggest as generally useful (low bar for broad adoption) vs what we would like to have but know is out of reach.

view this post on Zulip John Moehrke (Nov 05 2019 at 20:14):

bestcase is that this need for callback is solved in the general IT OAuth space and we just use that. Seems like we are inventing far too much

view this post on Zulip Gino Canessa (Nov 05 2019 at 20:22):

That would be great! Unfortunately, I think it's out of scope for them. :sad:

view this post on Zulip John Moehrke (Nov 05 2019 at 20:35):

how is the general http/OAuth world not having a need for callback?

view this post on Zulip Gino Canessa (Nov 05 2019 at 20:54):

OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices.

I don't see anything that involves a third-party or subsequent outgoing requests.

The 'hammer approach(1)' I can see (right now) using OAuth would be to have the user authenticate with the Subscription server as the client, which would then give the server a token and refresh token that it could maintain/use. Then, the token could be checked prior to sending out notifications.

Actually, after typing this I'm not sure I hate it.

(1) When your only tool is a hammer, all your problems look like nails.

view this post on Zulip Jenni Syed (Nov 05 2019 at 20:56):

What you just described is what was currently described in the spec, except that it snuck that in via the headers field (we raised concerns about that trick before). Though it didn't really allow for the refresh - it assumed the token was long lived. Which could be problematic :)

view this post on Zulip Jenni Syed (Nov 05 2019 at 20:56):

I would love for whatever we land on to be more explicit and less easy to miss :)

view this post on Zulip Gino Canessa (Nov 05 2019 at 21:01):

In the current spec, it just has a place for an Auth Header.

What I'm thinking right now would be that as part of creating a subscription, there would be a step where the Subscription server needs to perform the OAuth workflow to the Endpoint.

It means that the endpoint would be required to support OAuth (instead of just accepting a JWT token), and I would keep the token out of subscription.

It feels a little convoluted, and I'm not convinced I love requiring OAuth on Endpoints... but it feels much more secure and reliable.

view this post on Zulip Mohammad Jafari (Nov 05 2019 at 23:07):

@Gino Canessa @Jenni Syed to clarify, is the concern you're trying to address here, the authorization for the callback (from the subscription server to the client's registered callback endpoint)? I'm trying to understand why the subscription server needs an oauth token for the call back to the client. Usually for webhooks, the concern is authenticity, i.e. whether the call back is indeed coming from the subscription server which can be addressed with simpler solutions (e.g. a common approach I have seen is an hmac signatures using a shared secret provided by the client and recorded with the subscription context).

view this post on Zulip Gino Canessa (Nov 05 2019 at 23:15):

Hi Mohammad, I think this has turned into a general 'security on subscriptions' thread, unfortunately.

If I am sorting through everything correctly, I see two main topics:
- How does a server know if it should send a notification (authorization window of subscription)?
- How does an Endpoint know that it should accept a notification (authorization of server to send notification)?

I am trying to synthesize what the opinions are around the two into proposals (as far as what needs to go into the resource specs, what needs to go in the security docs, what needs to go into the Argonaut IG, and what needs to be noted as not listed and why (e.g., we feel the bar is too high for mutual TLS to be adopted - so considered and excluded).

view this post on Zulip Pascal Pfiffner (Nov 06 2019 at 05:18):

Do we think the requirements on auth change are based on the subscription type (ping, id-only, full content)? I'm hoping yes and want to make sure we don't end up mandating the receiving server needs to dance the OAuth dance in order to receive pings. :)

view this post on Zulip John Moehrke (Nov 06 2019 at 13:38):

I agree with @Pascal Pfiffner . This full bi-directional OAuth use would only be needed when the notification carries PHI. So the client requesting the subscription is in-charge of which type of subscription they are asking for. Thus if that client asks for full content, then it must also recognize that the endpoint it provides must support the OAuth responsibilities.

view this post on Zulip John Moehrke (Nov 06 2019 at 13:41):

we all should remember that the client can always cancel the Subscription by updating the Subscripiton. So the OAuth checks are necessary but not the typical way to cancel a subscription. The OAuth is primarly going to catch the cases Jenni pointed out much earler in the stream, when the user or app has a security revocation. If the user / app want the subscription to be cancled they would update Subscription

view this post on Zulip Gino Canessa (Nov 06 2019 at 15:15):

@Pascal Pfiffner as of right now, I believe that's an implementation detail. Servers are on the hook for what they do, so they will impose those types of restrictions (e.g., some servers may not allow full-resource at all).

With these discussions, I am trying to make sure the mechanisms in place are reasonably secure and that there is guidance on what should be looked at so implementers aren't broadcasting PHI by using it 'out of the box'.

I would prefer more security, but am realistic enough to know it's too high a barrier for adoption (e.g., end-to-end encryption, key exchanges, etc.).

I am hopeful that some additional channel types eventually 'win' and can be moved into the standard with those types of security, but this likely needs to be in production for a while before that can be properly discussed.


Last updated: Apr 12 2022 at 19:14 UTC