FHIR Chat · Patient group scopes · smart

Stream: smart

Topic: Patient group scopes


view this post on Zulip Nikolai Schwertner (Jul 09 2021 at 13:18):

@Alexander Zautke and I have been discussing the available approaches in SMART for a client to request access to a specific group of patients and their observation with certain LOINC codes. Initially we were looking into leveraging SMART v2 granular scopes to ask for user-level scopes for patients belonging to a certain study group and observations with specific loinc codes. It's not clear however how one can limit the observations scope to the patients from the patients scope. If interpreted literally, this set of scopes (such as user/Patient.rs?_has:Group:member:identifier=<identifier> user/Observation.rs?code=http://loinc.org|code1,http://loinc.org|code2,...) would enable access to the patients in the group but also to all the Observations with the specified codes available to the user (not just the observations for the patients in the group). So that appears to be a dead end (unless there is something we are missing).

We are looking at somewhat simpler (but less transparent) approach where the client requests user/Patient.rs user/Observation.rs?code=http://loinc.org|code1,http://loinc.org|code2,... where the end user gets a set of user credentials each linked to a different group (so that depending on which login is used, the "user" scope limits to a specific group). A variation would be that the authorization server will ask the user to select the limiting group at authorization time (but then the identitiy of the limiting group won't be origininating from the client, which is not ideal). That feels like a hacky approach however with account management overhead, so we are not super happy with it either.

Finally, we are thinking of introducing a new scope type "group/" which is a subset of the "user/" scope limiting the data set to a specific group of patients. This however has the issues that it is: a. outside the current SMART scopes standard b. it's not clear how the client will communicate the identifier of the group that it is requesting (perhaps via a custom authorize parameter?).

Has anyone done anything like this before? Which approach would make most sense in the context of FHIR? Is there another way to approach this?

view this post on Zulip Josh Mandel (Jul 09 2021 at 13:45):

Thanks for the question and the detail here. It's worth talking through the use case a bit more. For background, see the proposed disposition on FHIR-32251 -- SMART provides a way to delegate the access that some authorized user or client already has. In your case, what is the underlying method of deciding the full set of data a given client is allowed to delegate? Where and how do you model this, and is it tied to specific groups or data types? One way of asking this: if your client requests an access token with h system/*.rs scopes ("generated access token that's able to read and search everything I can"), what data will they in fact be able to export? Is this something you track client by client, and how is it managed?

view this post on Zulip Josh Mandel (Jul 09 2021 at 13:45):

The most common scenario we have seen in production so far is a client at registration time is granted access to certain patient groups. Any access token the client request at that point will be limited to data in those groups.

view this post on Zulip Josh Mandel (Jul 09 2021 at 13:46):

Over time we might push more and more of this into a structured computable language (a permission layer, below the delegation layer) but we have not tried to standardize that yet.

view this post on Zulip Nikolai Schwertner (Jul 09 2021 at 14:17):

Thanks for the input, @Josh Mandel Indeed this use case does not quite match the pattern of the user-level scopes that we have in SMART. More specifically, here the user has access to a set of patient groups (say group A, B, and C), then the client requests access to the patients and their observations within group B [id = g9245] only. This is a scope at a level between user\ and 'patient\' that we don't have yet. It could looks something like group[g9245]\Patient.rs or group[g9245]\Observation.rs?code=123.

view this post on Zulip Josh Mandel (Jul 09 2021 at 15:11):

And you doing bulk export, or using the regular FHIR REST API?

In theory you could have a client request a scope like

Observation.rs?
  code:in=http://server.example.org/my-value-set&
  patient._has=Group:member:_id=g9245

view this post on Zulip Josh Mandel (Jul 09 2021 at 15:12):

The semantics of that scope kind of get at what you'd want for "Allow access to all observations for a given valueset, for members of a given group", but in practice we do not expect servers would be able to manage/parse/enforce such complex scopes on the fly.

view this post on Zulip Nikolai Schwertner (Jul 09 2021 at 15:48):

I believe we are talking about the FHIR REST API (is that right @Alexander Zautke ?) Yes, this scope does get close to what the use case would need, I think. It is rather complex though and indeed would present a challenge for the underlying server to evaluate in real time if it is not translated into a more comprehensible higher level scope restriction. Then again, I don't know how common this particular use case is to warrant such an extension to the protocol.

view this post on Zulip Alexander Zautke (Jul 16 2021 at 09:46):

Yes, we are taking about the FHIR REST API here. For our implementation it wouldn't be too much trouble to interpret such a code. However, it pushing the syntax to it's limits (excluding _filter as a even more advanced feature for now). Soon you would like to additionally add a check that the patient within the group also has a reference to a valid Consent resource. Or some other checks. That's the part where it would stop working. The main issue for us, in implementing it in Firely Server, is that we don't have any out-of-the-box solution for the permissions layer. Therefore we see users trying to push as much as possible into the SMART scopes. Anything else would currently be a custom implementation.

view this post on Zulip Alexander Zautke (Jul 16 2021 at 09:47):

I would be incredibly interested in helping out when you start discussing on how such a standardized permissions layer could look like.

view this post on Zulip Alexander Zautke (Jul 16 2021 at 09:50):

BTW, I really like the resolution in FHIR-32251. Hopefully, it'll help to make users aware that we are talking about different layers here.

view this post on Zulip Nikolai Schwertner (Jul 16 2021 at 15:00):

This is a good point, @Alexander Zautke The scope expression complexity can get rather high in some otherwise benign scenarios. The pattern is: a client needs access to a selection of resources related to patients that match a constraint (in this case - group membership). Expressing the common constraint as chained query parameters for each scope element is bound to result in inefficiency (both in terms of verbosity but also in terms of computation optimization). The best possible scenario for processing when faced with a scopes set with such a constraint expressed as chained queries is a sophisticated evaluation engine which analyzes the entire list of scopes together, recognizes that all the scopes contian a common/linked constraint, evaluates and caches the common constraint result set (for example, the list of IDs of the Patient resources that match the constraint), then reuses the cache across all security evaluations. But that is really too much of a sophistication to expect.

For optimal expressiveness and evaluation, it would be ideal if the common constraint is expressed as such in a generalized way and then applied to all the scopes that require it. Then the evaluation is much easier to optimize. We are already doing this in practice via the patient\ and user\ constraints (always with respect to the Patient resources set). The question is, would it be useful to extend the standard such that it is possible for the client to provide a constraint expression for establishing a custom scope different from patient\ and user\?

view this post on Zulip Josh Mandel (Jul 16 2021 at 16:18):

Right now this can be done in extension space (OAuth scopes are extensible!); I'd say if a couple of servers want to experiment with this, try out some ideas, and bring back a proposal, it'd be a good way to move things ahead.

view this post on Zulip Josh Mandel (Jul 16 2021 at 16:20):

My suspicion is that servers actually want to model permissions at a lower level in the stack (where having some constraint language is also helpful but it may look quite different from our scopes language, which is designed for per-token delegation).


Last updated: Apr 12 2022 at 19:14 UTC