Security
Introduction
Security is an important condition for exchanging information over the FHIR interface. ZorgDomein uses a FHIR client, which either requests information from a FHIR server of a XIS or sends documents to a XIS. For both requesting and sending, FHIR REST calls are used. Security for these calls is warranted by two means:
- On network level by deploying a two-sided TLS connection in which ZorgDomein offers a client certificate for authentication purposes
- On application level by supplying every call with an HTTP header containing a signed token.
Network level security: mutual TLS
Deploying a mutual TLS connection ensures that:
- All information is encrypted during transport.
- ZorgDomein can authenticate the XIS by the server certificate that the XIS will present to ZorgDomein during the handshake. The server certificate that is presented by the XIS must be a PKIoverheid Private G1 certificate (except for FHIR servers that are secured by a SMART on FHIR interface; these servers must present a CA signed certificate that is trusted by web browsers).
- The XIS can authenticate ZorgDomein by the client certificate that ZorgDomein will present to the XIS during the handshake. ZorgDomein will present a PKIoverheid Private G1 certificate. Please note that the XIS must actively request and validate this client certificate during handshake to setup a mutually authenticated connection!
Contact us to set up such a connection and to exchange certificates.
Conform the security guidelines of the dutch National Cyber Security Center (NCSC) we only support TLS 1.2 with the following ciphers:
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES256-GCM-SHA384
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-CHACHA20-POLY1305
- ECDHE-RSA-CHACHA20-POLY1305
And we support TLS 1.3 with the following ciphers:
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_GCM_SHA256
Application level security: JSON Web Tokens
Next to deploying a two-sided TLS connection, ZorgDomein also includes a JSON Web Token (JWT) in the HTTP headers of every REST call. This is an open industry standard for exchanging claims securely between two parties. Please visit jwt.io if you are not familiar with this standard, it provides excellent information about this standard.
A JWT always consists of the following elements:
- header – metadata about the jwt
- payload – set of claims
- signature – digital signature to verify the claims
For each inbound request, the XIS must validate the signature and validity of the token and it must verify that the token was actually issued by ZorgDomein. A public key is necessary for the validation. Contact us to obtain a public key.
If ZorgDomein interacts with a FHIR endpoint after a user has logged in to ZorgDomein through SSO, ZorgDomein will provide user and organization details of the acting user in the token. This way, all user and context details that were provided in the SSO token are fed back to the XIS for each FHIR request. With this information, the XIS can determine if a user is authorized to access the requested information.
The token is included in the HTTP headers of the REST calls that ZorgDomein directs at the FHIR interface of the XIS. To this end, Authorization : Bearer
is used. An example of such an HTTP header (line breaks added for readability):
Authorization : Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
Token specifications
Token-header
The header of the token contains three parts:
alg
: RS256 (static value)typ
: JWT (static value)kid
: the key id; this id can be used to determine which public key may be used to validate the signature. The kid is exchanged at the same time as the public key.
Token-payload
Parameter | Description | Datatype | Example value |
---|---|---|---|
iss |
Identifier of XIS issuing token | String (fixed) | ZorgDomein |
jti |
Identifier of the token | String | 4a006a12-dc2b-470a-b031-a3682b653ba7 |
iat |
Token creation timestamp | NumericDate | 1496275200 |
exp |
Token expiration timestamp | NumericDate | 1496275200 |
org-id.system * |
System the organization identifier originates from | String | fixed value: local |
org-id.value * |
Organization identifier value NB: This parameter contains the value of the unique organization identifier that was exchanged during auto-activation. |
String | 10987654 |
user-id.system ** |
System the user identifier originates from | String | fixed value: local |
user-id.value ** |
User identifier value | String | 01234567 |
responsible-id.system ** |
System the user identifier of the responsible practitioner originates from | String | agb |
responsible-id.value ** |
User identifier for the responsible practitioner | String | 01234567 |
context.xis-transaction-id ** |
Unique transaction identifier as issued by the XIS at the start of the transaction | String | 6fb34257-7e0d-41a1-b8a7-417a50de6d39 |
* These payload parameters are only set when the auto-activation process is completed.
** These payload parameters are only set when the session with ZorgDomein started through SSO from a XIS.
Token signature
Following the JWT specification, the signature is generated using the encoded header, the encoded payload, and both the key pair and algorithm specified in the header. The signature must be encrypted asymmetrically, so the token is signed using a private key. This private key has a corresponding public key, which the XIS can use to validate the token. Exchange of the public key is done out-of-band.
Token example
Token header
{
"alg": "RS256",
"typ": "JWT",
"kid": "ZorgDomein-TIO-2017"
}
Token payload
{
"iss": "ZorgDomein",
"jti": "4a006a12-dc2b-470a-b031-a3682b653ba7",
"iat": 1475482548,
"user-id.system": "local",
"user-id.value": "10987654",
"org-id.system": "local",
"org-id.value": "01234567",
"context.xis-transaction-id": "6fb34257-7e0d-41a1-b8a7-417a50de6d39"
}
Questions or comments?
Leave your details below, we will contact you asap.