Version 0.2
Target audience
This specification is intended for developers who wants to integrate a multi-tenant system with HelseID.
Background
HelseID now supports the use of multi-tenancy, i.e. the architecture pattern that allows multiple consumers of a software vendor to use the same instance of the vendor’s software. In our case, this system can for instance be an electronic health record system. The consumers share the usage of this system, but are unaware of each other. As such, the sharing of health records should not be allowed to happen between random users in such a system.
The initial stage for creating this pattern is that a Consumer (e.g. a GP’s office or a municipality) delegates a right to the Supplier (e.g. a software company that delivers a SaaS-type EHR system). This right allows the Supplier to maintain health records on behalf of the Consumer. This is typically done with the use of a legal agreement (databehandleravtale) between the parties.
In order for HelseID to pick up on these delegations, the Consumer also needs to delegate the right “Databehandler kan opptre på vegne av min virksomhet I HelseID” to the Supplier in Altinn.
Any user that has logged on to a multi-tenant system should only be able to see and edit the health records that they have a legal right to access:
It is up to the Supplier to make sure that the user is only authorized for the correct Consumer(s).
The implication of this is that when the user accesses a service (e.g. Persontjenesten) by using the OAuth 2 protocol through HelseID, a claim that indicates the organization number for the Consumer that the user represents is present in the access token.
If the Service has requested it, the access token will also contain a claim that indicates the organization number for the Supplier.
Underlying technical mechanisms
Firstly, a HelseID client that is set up with support for multi-tenancy must be created. The Supplier needs to handle a private key for authentication for this client. When requesting an access token from the token
endpoint in HelseID, the system must create a client assertion that, in addition to the general claims needed for HelseID to grant the request a token, also must contain a structured claim named authorization_details
.
This claim is a structure that the Supplier uses to provide the organization number for the Consumer. It MAY also contain a child organisation number for the Consumer; this is typically sent to HelseID when a consumer has multiple organizational levels, such as a municipality. The claim must be structured as the following:
"authorization_details": { "type":"helseid_authorization", "practitioner_role": { "organization": { "identifier": { "system":"urn:oid:1.0.6523", "type":"ENH", "value":"NO:ORGNR:<consumer organization number>:<consumer child organization number>", } } } }
system
MUST be "urn:oid:1.0.6523"
value
MUST be of the form
"NO:ORGNR:<consumer parent organization number>" OR
"NO:ORGNR:<consumer parent organization number>:<consumer child organization number>"
(For instance "value":"NO:ORGNR:987987987:987987765"
.)
See the documents OAuth 2.0 Rich Authorization Requests and Passing a Request Object by Value for more information about structured claims
Issued claims to the service
The claims issued from HelseID will be of the types
helseid://claims/client/claims/orgnr_parent
: containing the organization number for a consumer that the supplier providedhelseid://claims/client/claims/orgnr_child
: containing the organization number for the consumer’s sub-organization (if provided)helseid://claims/client/claims/orgnr_supplier
: containing the organization number for the Supplier. This information is set by HelseID.helseid://claims/client/claims/client_tenancy
: describing the type of client that requested the Access Token. Possible values are"none"
,"single-tenant"
and"multi-tenant"
.
The important thing to notice, is that if the Supplier sends a token request to HelseID containing the organization number of a consumer that has not delegated rights to the supplier via Altinn, HelseID will refuse the request and return an HID-1001 error message.