Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents

...

What operations the user is allowed to invoke is stated in the "realm_access" attribute. In the example above the user is allowed to issue a "Patient.read" and a "Patient.write". This means that the user can get and edit patient records. This part of the security model is the RBAC - part, as the claims here are entirely based upon on what role the user has.

Attribute-Based Access Control

The ABAC part of the access control combines the access token user type with security token context(s) and, at times, also the access token user id. These are typically compared to attributes of the data from the services.

Access Token Field

Meaning

Example Value

context

List of items that are set in context. context in combination with items in realm_access governs the access to all resources in the ehealth eHealth infrastructure.

"context": {

    "organization_id" : "https://fut.com/fhir/Organization/1",

    "care_team_id": https://fut.com/fhir/CareTeam/4,

    "episode_of_care_id": https://fut.com/fhir/EpisodeOfCare/10,

    "patient_id": "https://fut.com/fhir/Patient/8"

  }

user_id

Id of the user. Can be either a an FHIR patient Id, FHIR practitioner Id or a KeyCloak IdID

"user_id": " e03ccef7-b0b1-4f68-8e16-6fc2f865a922"

user_type

Can be either SYSTEM, PATIENT, PRACTITIONER or SSL

"user_type": "PATIENT"

Each resource type (see IG Profiles) has certain restrictions to what context is required in order to allow data retrieval or data manipulation. 

...

These resources are not patient-related. Read and Search operations do not require any security context apart from the privilege. 

...

These resources are not patient-related.

DocumentReference.read/search

User Type

Context

Practitioner / Patient

-

System

-

...

EpisodeOfCare.create-episode-of-care

User Type

EpisodeOfCare Context 

Patient Context

CareTeam Context

Practitioner

must not be present

required:

must match EpisodeOfCare.Patient

required:

Must match EpisodeOfCare.team

PatientThe patient

must not be present

required:

must match EpisodeOfCare.Patient

-

System

-

-

-

...

EpisodeOfCare.patch/updateCareteams

User Type

EpisodeOfCare Context 

CareTeam Context

Practitioner

required:

must match EpisodeOfCare

required:

Must match EpisodeOfCareEpisodeOfCathe re.team

Patient

required:

must match EpisodeOfCare

-

System

-

-

...

EpisodeOfCare.search

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Practitioner

must not be present

optional but when present:

must match Patient match the Patient search parameter

required:

Must match CareTeam search parameter

Patient

must not be present

Always present:

must match Patient match the Patient search parameter


-

System

-

-

-

...

Provenance.search

User Type

EpisodeOfCare Context

CareTeam Context


Practitioner

required:

must match the EpisodeOfCare search parameter (provenance.target)

-


Patient

required:

must match the EpisodeOfCare search parameter (provenance.target)

-

System

-

-


...

Consent.search

User Type

EpisodeOfCare Context

CareTeam Context

Practitioner

required:

must match the EpisodeOfCare search parameter (consent.data.reference)

-

Patient

required:

must match the EpisodeOfCare search parameter (consent.data.reference)

-

System

-

-

...

CommunicationRequest Create/Read/Update/Delete

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Details

Practitioner

required

must match CommunicationRequest.episodeOfCare

required

must match CommunicationRequest.subject

required

must match CommunicationRequest.recipient if the recipient contains a careteam



Patient

optional but when present:

must match CommunicationRequest.episodeOfCare


required

must match CommunicationRequest.subject

-

Update: Only status


System

-


-


...

CommunicationRequest Search

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context


Practitioner

required if the searchparam recipient is a patient. 

optional otherwise.

must match searchparam CommunicationRequest.episodeOfCare when present

optional but when present:

must match searchparam CommunicationRequest.subject

required if searchparam recipient is a careteam



Patient

optional but when present

must match CommunicationRequest.episodeOfCare

Always present and must match searchparam CommunicationRequest.recipient

-



System

-

-

-


Draft of FUTURE change as a consequence of CCR154: CommunicationRequest Create/Read/Update/Delete

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Details

Practitioner

CommunicationRequest.episodeOfCare and EpisodeOfCare security token context must match.

If CommunicationRequest.episodeOfCare is null then the security token must not have an episodeOfCare context

required

must match CommunicationRequest.subject

required

must match CommunicationRequest.recipient if the recipient contains a careteam

Patient

optional but when present it must match CommunicationRequest.episodeOfCare

If CommunicationRequest.episodeOfCare is null then the security token must not have an episodeOfCare context

required

must match CommunicationRequest.subject

-

Update: Only status

System

-

-

Draft of FUTURE change as a consequence of CCR154: CommunicationRequest Search

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Practitioner

If EpisodeOfCare context is present, then searchparam and context must match

If EpisodeOfCare context is not present, then the search parameter must include at least one of:

  1. episodeOfCare:missing=true

  2. recipient=<careteam> matching CareTeam context

optional but when present:

must match searchparam patient

required if search if the search param recipient is a careteam. The search param and careteam context must match.

Patient

optional but when present

must match searchparam: episodeOfCare

Always present and must match searchparam CommunicationRequest.recipient

-

System

-

-

-

...

ClinicalImpression create/read/update

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context


Practitioner

required:

must match ClinicalImpression.episodeOfCare

required:

must match ClinicalImpression.subject

required:

must be in ClinicalImpressions.ehealth-careplan.careTeam or ClinicalImpressions.episodeOfCare.team



Patient

optional but when present:

must match ClinicalImpression.episodeOfCare

required when EOC context is not present:

must match ClinicalImpression.subject

-



System

-

-

-


...

ClinicalImpression.search

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context


Practitioner

optional but when present:

must match searchparam: episodeOfCare

optional

must match searchparam: subject

Only checked if EOC context is not present:

required:

Must match search param value in context.team or carePlan.careTeam


Patient

optional but when present:

must match searchparam: episodeOfCare

required when EpisodeOfCare Context is not present:

must match searchparam: subject


-



System

-

-

-


...

Task create/read/update

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context  / UserId

Extra Permission

Practitioner

optional but when present:

must match Task.episodeOfCare

optional, but when present:

must match Task.episodeOfCareepisis odeOfCare.subject

CareTeam Context must match Task.responsible

User must have at least one corresponding restriction category privilege in Task.restriction-category.

UserID must match Task.responsible, Task.owner or Task.requester


Patient

optional but when present:

must match Task.episodeOfCare

required when EOC context is not present:

must match Task.episodeOfCare.subject

UserID must match Task.responsible, Task.owner or Task.requester



System

-

-

-


...

Task search

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context  / UserId

Extra Permission

Practitioner

optional but when present:

must match searchparam episodeOfCare

optional

must match searchparam Context.subject

Only checked if EOC context is not present:

CareTeam Context must match searchparam responsible

User Users must have all restriction category privileges corresponding to the list in searchparam restriction-category.

UserID must match searchparam: Responsible, Owner or Requester


Patient

optional but when present:

must match searchparam episodeOfCare

required when EpisodeOfCare Context is not present:

must match searchparam theContext.subject

UserID must match searchparam: Responsible, Owner or Requester



System

-

-

-


When searching for tasks based on careteam, it is possible, but not necessary to specify restriction categories. If they are not specified as search criteria, then they will be inferred from the privileges in the security - token.

If a search is based on a specific userID instead of a CareTeam, then all tasks related to that user will be returned regardless of the restriction - category.

It is recommended to search based on either a userID or a Careteam. It is technically possible to combine these two search parameters, but the results may be confusing.

...

Observation, Media, and QuestionnaireResponse (with status completed) is created by calling $submit-measurement. A draft QuestionnaireResponse (with status in - progress) can be created and updated directly.

Communication read

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context


Practitioner

optional but when present:

must match communication.episodeOfCare

required if EpisodeOfCare context is not present:

must match communication.subject

Only checked if EpisodeOfCare Context is not present.

A match must be found either through the Careteam or the UserID

  • Careteam: must match either communication.senderCareTeam or communication.recipientCareTeam

  • UserID: must match communication.sender or communication.recipient


Patient

-

required:

must match communication.recipient or communication.sender

-


System

-

-

-


...

Communication create/patch

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Extra permission

Practitioner

optional but when present:

must match communication.episodeOfCare

required if EpisodeOfCare context is not present:

must match communication.subject

A match must be found either through the Careteam or the UserID

  • Careteam: must match either communication.senderCareTeam

  • UserID: must match communication.sender


Patient

-

required:

must match communication.subject

-

communication.sender must match AuthToken.userId

System

-

-

-


...

Communication search

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Practitioner

required:

search param must match the context

-

A match must be found either through the Careteam or the UserID

  • Careteam: must match either communication.senderCareTeam or communication.recipientCareTeam

  • UserID: must match communication.sender or communication.recipient

Patient

-

required:

context must match the subject and either of sender or recipient search params

-

System

-

-

-

...

Observation read

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Practitioner

required:

must match observation.episodeOfCare

--

required:

If the CareTeam is assigned on the EpisodeOfCare:

  • The user is granted access with no further checks when the EpisodeOfCare.team of the EpisodeOfCare Context contains the CareTeam in the CareTeam Context

If the Careteam is assigned on to the CarePlan:

  • Observation.basedOn must be a ServiceRequest which is referenced in CarePlan.activity.reference where the CarePlan.careTeam contains the CareTeam in the CareTeam Context

Patient

optional but when present:

must match observation.episodeOfCare

required when EOC context is not present:

must match observation.subject

Only checked if EpisodeOfCare Context is not present.

--

System

--

--

--

...

Observation search

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Practitioner

required:

search param must match the context

--

required:

If the CareTeam is assigned on the EpisodeOfCare:

  • basedOn search parameter is not mandatory

If the Careteam is assigned on to the CarePlan:

  • basedOn search parameter is mandatory and must  must match the context

Patient

optional but when present:

search param must match the context

required when EOC context is not present:

search param must match the context

--

System

--

--

--

...

QuestionnaireResponse read

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Practitioner

required:

must match questionnaireResponse.episodeOfCare

--

required:

If the CareTeam is assigned on the EpisodeOfCare:

  • The user is granted access with no further checks when the EpisodeOfCare.team of the EpisodeOfCare Context contains the CareTeam in the CareTeam Context

If the Careteam is assigned on to the CarePlan:

  • QuestionnaireResponse.basedOn must be a ServiceRequest which is referenced in CarePlan.activity.reference where the CarePlan.careTeam contains the CareTeam in the CareTeam Context

Patient

optional but when present:

must match questionnaireResponse.episodeOfCare

required

must match questionnaireResponse.subject

--

System

--

--

--

...

QuestionnaireResponse search

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Practitioner

required:

search param must match the context

--

required:

If the CareTeam is assigned on the EpisodeOfCare:

  • basedOn search parameter is not mandatory

If the Careteam is assigned on to the CarePlan:

  • basedOn search parameter is mandatory and must  must match the context

Patient

optional but when present:

search param must match the context

required when EOC context is not present:

search param must match the context

--

System

--

--

--

...

QuestionnaireResponse (status in - progress) create/update

User Type

EpisodeOfCare Context

CareTeam Context

Practitioner

required:

must match questionnaireResponse.episodeOfCare

required:

If the CareTeam is assigned on the EpisodeOfCare:

  • The user is granted access with no further checks when the EpisodeOfCare.team of the EpisodeOfCare Context contains the CareTeam in the CareTeam Context

If the Careteam is assigned on to the CarePlan:

  • QuestionnaireResponse.basedOn must be a ServiceRequest which is referenced in CarePlan.activity.reference where the CarePlan.careTeam contains the CareTeam in the CareTeam Context

Patient

required

must match questionnaireResponse.episodeOfCare

--

System

--

--

...

Media read

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Practitioner

required:

must match media.episodeOfCare

--

required:

If the CareTeam is assigned on the EpisodeOfCare:

  • The user is granted access with no further checks when the EpisodeOfCare.team of the EpisodeOfCare Context contains the CareTeam in the CareTeam Context

If the Careteam is assigned on to the CarePlan:

  • Media.basedOn must be a ServiceRequest which is referenced in CarePlan.activity.reference where the CarePlan.careTeam contains the CareTeam in the CareTeam Context

Patient

optional but when present:

must match media.episodeOfCare

required when EOC context is not present:

must match media.subject

--

System

--

--

--

...

Media search

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Practitioner

required:

search param must match the context

--

required:

If the CareTeam is assigned on the EpisodeOfCare:

  • basedOn search parameter is not mandatory

If the Careteam is assigned on to the CarePlan:

  • basedOn search parameter is mandatory and must  must match the context

Patient

optional but when present:

search param must match the context

required when EOC context is not present:

search param must match the context

--

System

--

--

--

...

$search-measurements

User Type

EpisodeOfCare Context

Patient Context

CareTeam Context

Practitioner

required:

search param must match the context

--

required:

If the CareTeam is assigned on the EpisodeOfCare:

  • basedOn search parameter is not mandatory

If the Careteam is assigned on to the CarePlan:

  • basedOn search parameter is mandatory and must  must match the context

Patient

optional but when present:

search param must match the context

required when EOC context is not present:

search param must match the context

--

System

--

--

--

...

Device read

User Type

Patient Context

Organization Context

SSL supplier/Practitioner

Optional but when present:

must match a DeviceUseStatement where:

  • DeviceUseStatement subject = patient context

  • DeviceUseStatement device references the device.

Required if patient context is not present.

Must match the device.owner 

Patient

must match a DeviceUseStatement where:

  • DeviceUseStatement subject = patient context

  • DeviceUseStatement device references the device.

-

System


-

...

Device/DeviceMetric create

User Type

Organization Context

Patient Context

SSL supplier/Practitioner

required

must match the Device.owner organization when the non-privately owned device

-

Patient (Must be privately owned device)

-

must match a DeviceUseStatement where:

  • DeviceUseStatement subject = patient context

  • DeviceUseStatement device references the device

or have no related DeviceUseStatement.

System

-

-

...

Device/DeviceMetric update/delete

User Type

Organization Context

Patient Context

SSL supplier/Practitioner

required

must match the Device.owner organization when the non-privately owned device

Optional but when present:

must match a DeviceUseStatement where:

  • DeviceUseStatement subject = patient context

  • DeviceUseStatement DeviceUseStatematch device references the device.

or have no related DeviceUseStatement.

Patient

-

must match a DeviceUseStatement where:

  • DeviceUseStatement subject = patient context

  • DeviceUseStatement device references the device

or have has no related DeviceUseStatement.

Device The device must be privately owned.

System

-

...

DeviceUseStatement create/update

User Type

Organization Context

Patient Context

SSL supplier/Practitioner

required

must match the Device.owner organization when the non-privately owned device

required

must match DeviceUseStatement.subject

Patient

-

required. The DeviceUseStatement must have:

  • DeviceUseStatement subject = patient context

  • DeviceUseStatement device references the device

Device The device must be privately owned.

System

-

...

DeviceUseStatement search

User Type

Organization Context

Patient Context

SSL supplier/Practitioner

-

required

patient search param must mach match the context

Patient

-

required

patient search param must mach match the context

System

-

-

Questionnaire

...

Actionguidance

User Type

FHIR Operation

Organization Context

Property updated

Role needed

Practitioner / Patient

create

required:

must match Actionguidance.modifierRole.reference

-

owner

update

required:

must match Actionguidance.modifierRole.reference

Actionguidance.modifierRole

owner

Not Actionguidance.modifierRole

owner or co-author

read/search

-

Note:

There are two ways to be able to make a search. First, if a permission for both Actionguidance and view is present, it will give access.

Secondly, to make a search, an actionguidance permission should be present, and the resource should be supplied as part of the profile search or as the search field code. All other cases will be rejected.

 

Values to supply for a profile search

profile=http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-actionguidance

 

Values to supply for a code search

code=http://ehealth.sundhed.dk/cs/basic-resource-type|actionguidance

-

-

System

-

-

-

-

...

View

User Type

FHIR Operation

Organization Context

Property updated

Role needed

Practitioner / Patient

create

required:

must match View.modifierRole.reference

-

owner

update

required:

must match View.modifierRole.reference

View.modifierRole

owner

Not View.modifierRole

owner or co-author

read/search

-

Note:

There are two ways to be able to make a search. First, if a permission for both View and view is present, it will give access.

Secondly, to make a search, an a View permission should be present, and the resource should be supplied as part of the profile search or as the search field code. All other cases will be rejected.

 

Values to supply for a profile search

profile=http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-view

 

Values to supply for a code search

code=http://ehealth.sundhed.dk/cs/basic-resource-type|view

-

-

System

-

-

-

-

...

SSL Annotation create/update/read/delete

User Type

Organization Context

SSL supplier

required:
must resolve to and match the Annotation.CatalogueItem.Catalogue seller party

Practitioner

-

System

-

...

Whitelist

SSL WhiteList create/read/delete

User Type

Organization Context

SSL supplier

- (no access)

Practitioner

required:
must resolve to and match the WhiteList.buyer party

System

-

...

SSL Problem create/patch/delete

User Type

Organization Context

SSL supplier

required:
must resolve to and match the Problem.CatalogueItem.Catalogue seller party

Practitioner

- (no access)

System

-

SSL Problem read

User Type

Organization Context

SSL supplier

required:
must resolve to and match the Problem.CatalogueItem.Catalogue seller party

Practitioner

required:
must resolve to and match WhiteList.buyer party, only returns Problems with CatalogueItems referred by WhiteLists

System

-

...

Schedule/Fetch <Report_name>

User Type

Organization Context

UserID

Extra permission


Practitioner

required

Must match input parameter: ManagingOrganization

Only the user that called schedule is allowed to read the resulting /fhir/Binary/id

The privilege Report.non-anonymized is required if input parameter: anonymization == false


System-user

System user users can't have an organization context

Only the user that called schedule is allowed to read the resulting /fhir/Binary/id

The privilege Report.non-anonymized is required if input parameter: anonymization == false


...

realm_access.role

Patient Context

Episode of Care Context

CareTeam Context

Organization Context

Extra Rules / Comments

Patient.read

R*


R*


REGULAR SEARCH:

In order to To perform a regular Patient Search, the user MUST have the Patient Context.


LIMITED SEARCH (Dashboard Search):

It is also possible to perform a patient search witha CareTeam Context instead of a Patient Context. In that case, the patients are then retrieved from EpisodesOfCare and CarePlan objects that the CareTeam is involved in.

NOTE: The patient resources that are returned from this search are limited and as such only the following information is returned:

  • Identifier

  • Date of Birth

  • Gender

  • Cpr

  • Deceased status

  • Home address

  • Official name


*R - THE CONTEXTS ARE MUTUALLY EXCLUSIVE, AS SUCH IF BOTH CONTEXTS ARE PROVIDED IN THE TOKEN, ONLY THE PATIENT CONTEXT IS USED.

Patient.write

R




1: FHIR operations "create" and "update" are not available on the Patient resource. 
(use $createPatient and "patch")

2: Only certain attributes are allowed to be patched using HTTP PATCH

Patient$updatePatientWithSKRSData






Patient$createPatient






Appointment.read

U


U


For non-group appointments:

1: If an appointment involves a patient, then that patient must be in context

2: The appointment can be read if

  • the user has a Care Team in context that is participating in the appointment

  • the user is participating in the appointment (as a Practitioner or Patient)

3: Searching

  • PATIENT users can search all Appointments that involves involve the user itself

  • PRACTITIONER/SSL users can search all Appointments that involves involve the user itself, or the Organization/CareTeam/Patient in context

Appointment.write

U


U

For non-group appointments:

1: If an appointment involves a patient, then that patient must be in context

2: The appointment can be written if

  • the user has a Care Team in context that is participating in the appointment

  • the user is participating in the appointment (as a Practitioner or Patient)

Appointment$exportAsiCal

U

U

Same The same rules apply as for to reading appointments

Note: Only PRACTITIONER/SSL users can see the names of Practitioner participants in the exported iCal object

RelatedPerson.read

R




Only related persons to the patient in context can be read

RelatedPerson.write

R




Only related persons to the patient in context can be written

Communication.read



U


If the message has a restriction category X, the corrosponding corresponding RestrictionCategory.X role must be present in the realm_access list.

1: PATIENT users can read

  • communication where they themselves are either the sender or recipient

2: PRACTITIONER and SSL users can read 

  • communication where they themselves are either the sender or recipient

  • communication where the CareTeam in context is the sender or recipient

3: Only SYSTEM users can read communication from DEVICE senders

Communication.write



U


1: Communication must have exactly one sender and one recipient

2: Communication with the category "note" can only be created/patched/deleted if user = sender and (recipient = sender or recipient = a CareTeam). 
(notes can be shared with any CareTeam)

3: PATIENT users 

  • can only create/delete "messagemesHTTP" communication where they are the sender, and the recipient is of type CareTeam

  • can only patch "message" communication where they are sender or recipient (the recipient can patch "received" property)

4: PRACTITIONER and SSL users 

  • can only create/delete "message" communication where the sender is the CareTeam in context and the recipient is of type PATIENT or type CareTeam

  • can only patch "message" communication where the CareTeam in context is the sender or recipient

Person$match





Only requires the role “Person$match”

Used to lookup person data by CPR, including name and a patient reference, if one exists.

This is only a read operation and will not create any resources.

The operations is are audit logged.


Group Appointment

A “Group appointment” is an Appointment with one of the profiles http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-group-appointment, http://ehealth.sundhed.dk/fhir/StructureDefinition/ehealth-group-videoappointment

  • Appropriate appointment-related realm_access.role is required for all operations

  • SYSTEM users have access to all data and http operations regardless of context

    • Only SYSTEM users can use PUT, other users must use PATCH to change a group appointment

  • Create

    • All Practitioner/SSL users can create group appointments if the they have an Appointment.write role and a CareTeam in context

      • assigning-careteam extension on participants must match CareTeam in the context

  • Read/Search

    • ehealth-creator, ehealth-responsible and ehealth-performer can see all parts of the appointment, regardless of the CareTeam context

    • All Practitioner/SSL users can read/find all group appointments and view all parts of it, except Patient participants whose assigning-careteam differs from the CareTeam in context, and the RelatedPersons of those

    • Patient users can only read/find group appointments that they themselves are participants onin, and can view all parts, except other Patient participants and RelatedPersons of those

  • Patching

    • Patient users cannot patch

    • When adding/removing a participant, the relevant assigning-careteam must be in the context

      • Removing a Patient/RelatedPerson participant is also allowed if the relevant patient is in context

    • ehealth-creator and ehealth-responsible can patch all parts of the appointment

    • ehealth-performer can patch all parts of the appointment, except ehealth-responsible

    • All other Practitioner/SSL users can only add/remove Patient/RelatedPerson participants

...

Please note that due to the filtering of participants, in some scenarios a client holds only a partial view of the appointment (with some participants missing due to security filtering).
This has an impact when removing a participant in a PATCH using an index, e.g. [{ "op": "remove", "path": "/participant/0" }]. What is in index 0 of the partial view, might not be what is actually in index 0 in the full version of the resource.
The server is aware of this dilemma and “maps” indexes when receiving a http an HTTP patch request, based on the JWT user_id/context used for the request. The server assumes the patch request is performed by the same user_id/context as the patch content indexes was were constructed from.

This means that PATCH operations should be performed with the same JWT as was used when reading the group appointment resource that the patch content (indexes) is based on.

...