access control for openEHR 'resources'

continuation of: Karolinska/Stockholm procurement of Digital health platform (CDR, tools, services, consultants) - #17 by joostholslag
@Daniel.Alomar @birger.haarbrandt @erik.sundvall @tangit86 @sebastian.iancu and @Sidharth_Ramesh are probably interested.

Background:
Currently access control has limited support in the openEHR spec itself. The only thing there is an EHR_ACCESS class, which has an abstract ACCESS_CONTROL_SETTINGS which is unconstrained and lives at the EHR level.
So basically a place to record access control rules on the specific EHR in any format.

And there is a general statement that the composition is the atomic unit of commit. And “An ENTRY is also the minimal unit of information any query should return” . Thus you should only set read access at the entry level (not smaller) and only write access if you can edit (and thus read) the entire composition.

As described in the SMART on openEHR there are many more scopes that are relevant to define access control for: e.g. doctors can create compositions that are instances of template composition.acp, or nurses can execute stored AQL with name “patient_history”. etc.

This is a generic topic to share requirements and solutions and architectural thoughts.

My specific requirement is how to define access policies to openEHR resource expression (templates, specific composition etc as defined in smart on openEHR spec) for a network of care organisations, without a single source of trust. E.g. all doctors in the netword can create composition.ACP instances. More info:

Word on the street is XACML is dead. (source listed in GitHub issue) I’m curious for the considerations of your architects.

1 Like

the rumors did not spread to Germany and basically all IHE XDS implementations are based on it. So maybe a bit dated but well tested :wink:

1 Like

At the risk of deviating from the topic: how do you see the relation between XDS and openEHR? XDS only works in a network is present, this is not feasible for my usecase.
Also xacml isn’t human readable imho, so it’s not a good fit for what I’m trying to do.
But interesting nonetheless. Do you have an example xacml policy for access to openehr data?
Does xaxml allows policies to be defined by an external artefact like a yaml file?

1 Like

I think openEHR and XDS deserves its own discussion. Depending on the use-case they can be complements, but openEHR can also replace XDS (though when we talk about distributed querying, you will end up with similar patterns with record locators/registries etc).

I think you will need to put some domain specific language on top of any access control technology to make it user friendly for administrators in healthcare. XACML is surely verbose. So while we are doing this directly on XACML for now, we could also think about some higher abstraction to make this a bit more digestible (or build custom UIs). I will check for examples, though not sure if I’m allowed to share publicly for now.

2 Likes

XDS and openEHR work really well together -see Slovenia for a prime example. @borut.fabjan is the expert here. We are using his XDS archetype in the UK to tag all compositions with at least a ‘document type’ code to allow discovery via XDS or the English record locator service.

This is exactly what I’m trying to achieve. My current idea is to expres the openEHR resource scope in a json schema. Then an access policy will be a json/yaml instance confirming to the schema. Rego/opa seem able to link variables and data in a generic policy to json data based on json schema. Thus to set a specific policy, the editor needs to edit the json. Now if there’s a json schema available it should be trivial to create a ui for that.
Now if XACML can do the same for the same json instance and json schema, we have a ‘dsl’ and policies that are actually machine interpretable and executable in an implementation (rego/xacml) agnostic way and are ui editable and human readable. that sounds really exciting to me. My gut feeling says it’s also very doable, but the proof of the pudding…

1 Like

We should modify that a bit to say that an Entry is the minimal unit of information that should be returned outside of a querying or other retrieval context that already knows the context information of the Entry/ies in question. For example, obtaining just the systolic pressures + times via a query that establishes that they are coming from Observations based on OBSERVATION.blood_pressure, created in the last 3 month (usually via comparing /context/start_time in the WHERE clause) is perfectly sound, because the query establishes the context and domain type (the OBS.blood_pressure).

What is not sound is plucking out just an ELEMENT containing a Quantity containing a systolic pressure, because you don’t know if you are getting it from an OBS or say, an EVALUATION that contains a target BP.

I think everyone understands this intuitively, but may be worth stating more clearly in the specs.

2 Likes

I agree it’s fine to be more selective in the query than the entry. But regarding the access control, you need access to the entire composition (or definitely to the entry level) to be able to correctly interpret the result of the query and to build the right filters in the where clause. E.g. in order to guarantee the correctness of a systolic bloodpressure, you probably should check the diastolic bloodpressure in that entry in that composition is lower than the systolic. To guarantee access to other elements in the entry, we shouldn’t allow access control at element level.

FYI: here’s a nice blog, discussion and upcoming meetup about access control in FHIR: Gasper Andrejc on LinkedIn: Extending the Firely Server & FHIR DS4P

The topic below is also relevant:

2 Likes

One of the questions I have is whether it’s useful to define AQL as a scope. My feeling is it’s only useful to set read access at the ‘entry’ level. Because doing a smaller read authorisation violates the specification that entry is the smallest unit a query should return. And assuming the maximum scope of an AQL is a single entry (and containing compositions) this should be functionally equivalent. If access should be definable on a combination of archetypes, we need this anyways. My gut feeling is also that it will be really convenient to be able to authorise AQLs. So I’m curious about your thoughts.

Apologies if I missed a nuance of what you are saying. One of the issues is that entry-level is not sufficient because it won’t allow you to filter for terminologies. Classic example will be lab values, diagnoses, medications etc., where you will likely depend on whitelisting/blacklisting defined codes.

In reality, we also have many implementers going way more granular than entry level (as Tom explained, we sometimes can assume the context well enough or it does not matter for a particular use-case).

This week I attended to an HL7 webinar about FHIR Access Control. We are all facing the same problems, since this is a complex topic. They are working around several proposal that might be of interest for openEHR.

You can see the videos of the webinar here:
https://www.youtube.com/playlist?list=PLEOOqZS1NtwalGOditsQzRxwlw53aPwZE

1 Like

My main point was that if a user is allowed to read one element in an entry, they must be allowed to see all the others in that entry.
But interesting point with lab data. It might be valid access policy that a nurse should be able to see obs.lab test result for eg HbA1c (diabetes) but not for ANCA (Rheuma).
But I may incline to enforce that at the composition instance level access policy.

Thanks for clarification, I agree that showing (or not showing) the whole entry (based on a more granular criterium) is likely applicable. And yes, it might also depend on your role or association to a healthcare organization what data you might be able to see.

1 Like

Does there exist any summary or documents of that? Finding 2h to burn on a video is not easy these days!

Is there anything wrong with querying a lab panel and extracting just the serum K and not the other analytes?

It’s the context that matters. If your client application only asks for serum K (maybe over time), then it presumably knows what it’s doing…

Couple of things…

It is generally good advice that a query should at least take account of te ENTRY context, but that is different from saying that the SELECT should only return ENTRY-level data. I don’t think that is what is being argued but it might be mis-understood.

Thee will be many use-cases for simple Resultsets at Element level

Thisis a good example

AQL

SELECT w/data[at0001]/items[at0002]/value/value AS Safeguarding_status
FROM EHR e [ehrId/value = :ehrId]
CONTAINS COMPOSITION c[openEHR-EHR-COMPOSITION.report.v1]
CONTAINS EVALUATION w[openEHR-EHR-EVALUATION.safeguarding_concern_uk.v0] 
WHERE c/name/value='OL - Safeguarding'
AND  w/data[at0001]/items[at0002]/value/defining_code/code_string = '1010196001'
AND  w/data[at0001]/items[at0002]/value/defining_code/terminologyId = 'SNOMED-CT'

If a match is found, in Ehrscape AQL returns…

[
    {
        "compositionId": "79ce9194-0907-4224-9240-3a8f35892742::11ed4f4e-6a7f-4849-a03c-2c41333a15ec::1",
        "safeguardingStatusDateTime": "2024-02-20T13:32:47.887Z",
        "safeguardingStatusText": "Safeguarding concern"
    }
]

The other issue is that while, in theory, we might need to apply highly granular access controls, in practice this becomes really tricky, not just in terms of applying the rules technically but in humanly managing them.

I agree this is an area where we really want to be involved in those wider FHIR/IHE conversations, and I think at the last f2f SEC meeting there was I think broad consensus that the EHR_ACCESS placeholder was probably not the place to hold access information.

That is an example of where at some level, this might seem respectful of a patient’s privacy need but my feeling now is that trying to meet this level of expectation (rarely required or wanted by the majority) is just going to tie us in knots. Better to work at composition level in the main, with occasional exceptions.

This is already having a bit of design impact on the way we put together template compositions trying to keep the scope of the content fairly tight. e.g .do not mix housing information with safeguarding information, even through both are ‘social circumstances’. Better to use 2 different templates/compositions.

2 Likes

We need to differentiate the end user that an application provides information too, from the application that extracts information from the repository. The application has an extra context that each individual query can’t access, but the user interface already has, so the user, if the application is well designed, already has the context.

Considering this, the RBAC or any other solution for checking permissions can be at different levels: in the repository itself, between the repository and the application, and in the application. If we get too restrictive and fine grained at the repository, we will affect performance, and might not have all the information the application or the Middleware has in order to check fine grained permissions. So IMO saying openEHR CDRs could support permission checking at the entry level, the any data point retrieved should be checked against is container entry permissions. But if we add permissions at the element level, it can get ugly fast. It’s also good to say to " at least check permissions at the composition level", again each element retrieved should be checked against its container compo permisions.

2 Likes