Stream: smart
Topic: Context-dependent authorization / authz
Merlyn Albery-Speyer (May 28 2021 at 18:50):
Hey folks, I have a SMART on FHIR proxy sitting in front of a Google FHIR store. The proxy forbids access when a related read scope is missing. That's easy enough. But what's the correct behavior for anything finer grained than that? A trivial example is that an fhirUser of "Patient/abc" and the "patient/Patient.read" scope should only be able to read "Patient/abc" and not any other sibling like "Patient/xyz" (see https://chat.fhir.org/#narrow/stream/179170-smart/topic/Patient.20scopes.2C.20authz.20logic for a more complicated example). What about the other FHIR entities? I haven't seen a specification anywhere. Is there either a formal or informal guide to follow? Thanks!
Josh Mandel (May 28 2021 at 21:45):
The rules and expected behavior here can be subtle.
First off, there's not necessarily A correspondence directly between the fhirUser running an app and the patient context to which authorization is bound for patient/
scopes (for example, a user might be a clinician or parent, sharing access scoped to a child's clinical record).
Next, the interpretation of patient scoped data is not formalized. We reference the FHIR Patient compartment as a starting point, but we also say that if you share a scope like patient/*.read
, this can include data that is not directly in the patient compartment, such as resources linked from Observations in the patient compartment (e.g., an Organization or Location linked from a lab result Observation).
For a non-EHR-based FHIR server like the native FHIR cloud services (Google FHIR store, IBM FHIR server, HAPI, FHIR Server for Azure, Firely Spark, etc), there's often not a place where these policies exist (e.g., which records is user123 allowed to see/share, or which resources should be shared when a scope like patient/*.read
is granted).
Finally, I should note that even when all of the considerations above are established, it can still be challenging to figure out how to perform authorization as a proxy, while maintaining reasonable performance -- and to maintain correctness when supporting features like chained searches, reverse includes, and custom operations. We are much better at standardizing the simple stuff.
Merlyn Albery-Speyer (May 28 2021 at 22:58):
Thanks, Josh.
Is this all formalized anywhere? By this I mean, what will CMS do to determine compliance here? The answer I'd arrived at from the thread that spawned this one was: (https://chat.fhir.org/#narrow/stream/179166-implementers/topic/Definitive.20AuthoriZation.20specification)
"Solution:
- it is sufficient to blacklist any response from the FHIR server that references any other Patient, and otherwise let everything through
Reasoning:
- it is surely possible that there are resources that are (1) not patient associated and (2) contain sensitive data, but when an app use patient scopes to get data about a patient it really need only patient-associated resources and those handful of resources referenced by them that are necessary for completeness: Practitioner, Organization, Location, PractitionerRole"
(And I am using Google FHIR store)
Josh Mandel (May 28 2021 at 23:07):
In general CMS doesn't have conformance testing, do they? ONC has EHR certification rules, which CMS points to and you can review the Inferno test suite behavior for current expectations. That said:
- The US Core profiles don't require any of the fancy search stuff (reverse chaining, includes, etc), so trivial solution is: ignore it. You may find that other profiles in the financial space, like CARIN Blue Button, add requirements here, so that's worth reviewing.
- Re: resources referenced from within the patient compartment, USCDI really only calls out the Organization and Practitioners as part of "basic provenance", so you'd probably want to make these available to all authorized clients, or else compute the subset of them that you need for each patient record
Josh Mandel (May 28 2021 at 23:09):
The solution you proposed sounds like a good starting point; one area where we've seen some concerns/considerations is for Practitioner; we've heard some concerns about exposing details like practitioner names in the context of patient access.
Merlyn Albery-Speyer (May 28 2021 at 23:14):
Sadly (?), _include
and _revinclude
do appear to be part of the requirements ("SEARCH-3" and "RESPONSE-3"), e.g.: [source: "onc_program_matrix_1_6_0.xls"]
SEARCH-3 : "The health IT developer demonstrates the ability of the Health IT Module to support a resource search for the provenance target “(_revIncludes: Provenance:target)” for all the FHIR resources included in the standard adopted in § 170.213 and implementation specification adopted in § 170.215(a)(2) according to the “Basic Provenance Guidance” section of the implementation specification adopted in § 170.215(a)(2)."
Josh Mandel (May 28 2021 at 23:16):
Ah, fair enough -- specifically for provenance. The concerns about pulling sensitive data in through provenance are pretty limited though, because if you can see a resource you should generally be allowed to see the provenance pointing to it.
Josh Mandel (May 28 2021 at 23:17):
At the proxy layer you just want to be very targeted about what is allowed, and not support general usage of includes without being able to either static analysis or dynamically determine whether a particular is just okay
Merlyn Albery-Speyer (May 28 2021 at 23:17):
(This is fantastic input from you - thank you so much for engaging in this discussion!)
Resources referenced from within the patient compartment, USCDI really only calls out the Organization and Practitioners as part of "basic provenance", ...
It looks like the scope must be broader than Organization
and Practitioner
to be useful. E.g. MedicationRequest
looks like it will spider out to other entities such as Medication
.
Josh Mandel (May 28 2021 at 23:27):
Yes; this analysis is exactly the kind of thing you'd want to use to create a definition of what graph links are okay to follow. I'd be happy to collaborate on this if you are interested in publishing it openly somewhere (It's conceivable that a fhir GraphDefinition could help here, but that may be a distraction.)
Merlyn Albery-Speyer (May 29 2021 at 00:16):
Honestly, this whole project to wrap up a Google FHIR store as a SMART on FHIR CMS-Rule friendly repo is entirely open-sourceable.
Paul Church (May 31 2021 at 17:24):
@Merlyn Albery-Speyer I can probably make your project a little easier. The Google Healthcare API has native SMART scope enforcement available in alpha (private preview). You can get access through our Trusted Tester program.
We had to address many of the same problems you have brought up. What we went with initially is a model where patient scopes apply only to the patient compartment itself, and for non-compartment resources like Organization, Location, etc. you can grant a user scope but it allows access to all resources of that type. Provenance remains a problem as it is a "special" compartment member that does not reference the patient directly, so it does not pass our compartment check.
The good news is that this scope enforcement covers search, chained search, include/revinclude, patient $everything...pretty much all of the API surface except for $export and a couple other extended operations.
There still needs to be an auth proxy or other wrapper on top to set the appropriate scopes. The Google solution is Apigee with HealthAPIx, but it's completely decoupled and you can adapt your wrapper to take advantage of the backend support.
Merlyn Albery-Speyer (Jun 01 2021 at 16:43):
Excellent. @Paul Church! I just applied for it. Once we're accepted, where do I go for documentation on authorization using SMART on FHIR scopes with the Google FHIR data store?
Paul Church (Jun 01 2021 at 17:12):
https://cloud.google.com/healthcare/private/docs/how-tos/smart-on-fhir (this link only works when logged in to an account with access)
Ryan Harrison (Jun 07 2021 at 23:51):
@Merlyn Albery-Speyer
By this I mean, what will CMS do to determine compliance here?
The short answer is CMS doesn't have an open-source ONC Inferno style tool for conformance testing.
The Google Trusted Tester program mentioned by @Paul Church being in alpha, there's a de facto monopoly in the commercial space for CMS conformance testing, Aegis Touchstone or Aegis Touchstone up-sold with Drummond.
Here is a 1 year old overview of the FHIR conformance testing landscape.
- Video: https://www.youtube.com/watch?v=XdAsyU9oUms
- Slides: https://www.slideshare.net/RyanMHarrison/20200612-fhir-testing-with-onc-inferno-mitre-crucible-and-aegis-touchstone
Please let me know if you have something more up to date.
I would highly recommend against trying to build your own test harness because the rules get very nuanced, very quickly.
Paul Church (Jun 08 2021 at 00:21):
Just to be clear, Google doesn't have a conformance test. We have server support, which is available in early access (the trusted tester program).
Josh Mandel (Jun 08 2021 at 00:57):
Is there actually a process for conformance testing against CMS? I thought CMS's API details were not directly regulated (e.g., CMS imposes no requirement to use a specific IG for patient access to financial data, but functional requirements align well to CARIN).
Josh Mandel (Jun 08 2021 at 00:57):
Have I misunderstood or is my understanding out to date?
Michele Mottini (Jun 08 2021 at 02:22):
CMS's API details were not directly regulated
Correct
Merlyn Albery-Speyer (Jun 08 2021 at 18:01):
Thanks, Ryan.
For the benefit of others: I'm getting a lot of mileage out of adding request parameters to the proxied request to Google FHIR (i.e. _id
or patient
).
Craig McClendon (Dec 01 2021 at 00:18):
@Merlyn Albery-Speyer - Curious if you ever made headway on the SMART proxy service, or did you switch to the google native SMART enforcement? It seems like a community reference SMART evaluator would be useful. i.e. a module that takes a Bundle of resources and SMART scope information and determines which resources are allowed or not. Does such a beast exist already? Or is there something I'm not seeing which would prevent a generic implementation like that?
Last updated: Apr 12 2022 at 19:14 UTC