Validate the access token
When aanother care organization queries your FHIR API (or other data API), the request comes in at your resource endpoint,carries an access token shouldyour beNuts availablenode issued. Your API (or the API gateway in front of it) must check that token on every request, then decide whether to allow the HTTPquery.
The header.Nuts Younode can validatechecks the token and tells you who is asking. Whether that party may see the data is decided by calling:your application.
Before you start
What an incoming request looks like
For a DPoP token, the request has two headers:
GET https://fhir.example.com/r4/Patient?identifier=http://fhir.nl/fhir/NamingSystem/bsn|123456789
Authorization: DPoP eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...
DPoP: eyJhbGciOiJFUzI1NiIsInR5cCI6ImRwb3Arand0In0...
For a Bearer token, there's only Authorization: Bearer <token>.
1. Introspect the token
POST <internal Nuts interface>/internal/auth/v2/accesstoken/introspect
Content-Type: application/x-www-form-urlencoded
token=ciOiJSUzI1NiIsInR5cCI6IkpeyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...
Note:Result thefor content-type of this call is application/x-www-form-urlencoded.
And the result:360-graden-clientbeeld:
{
"active": true,
"iss": "https://nuts.example.com/oauth2/other_subject_identifier"careorg-a-acc",
"client_id": "https://example.com/nuts.other.example/oauth2/my_subject_identifier"careorg-b",
"scope": "coffee"360-graden",
"exp": 1793110000,
"cnf": { "jkt": "jlkhnp87453slfhansdhf" },
"organization_ura": "87654321",
"organization_name": "CareZorgorganisatie Bears"B",
"organization_city": "Utrecht",
"employee_name": "J. de Vries",
"employee_role": "Verpleegkundige",
"employee_identifier": "123456"
}
active is false, reject the request with 401 Unauthorized. The token is expired, invalid or unknown.
Check that scope is the scope of the use case the request belongs to.
The other fields come from the credentials the requester presented. They're named by the field IDs in the policy definition, so they depend on the use case.
cnf.jkt is only there for DPoP tokens. You need it in the next step.
LikeNeed the presented credentials themselves, e.g. for your audit log? Use POST /internal/auth/v2/accesstoken/introspect_extended: same result, plus the Verifiable Presentations.
2. Check the DPoP header (DPoP tokens only)
A DPoP token is only valid together with a DPoP header that the requester signed for this request:
POST <internal Nuts interface>/internal/auth/v2/dpop/validate
Content-Type: application/json
{
"dpop_proof": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImRwb3Arand0In0...",
"method": "GET",
"url": "https://fhir.example.com/r4/Patient",
"thumbprint": "jlkhnp87453slfhansdhf",
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp..."
}
dpop_proof
The DPoP header of the incoming request
method
The HTTP method of the incoming request
url
The URL of the incoming request, as the requester called it. Query parameters are ignored.
thumbprint
cnf.jkt from the introspection result
token
The access token from the Authorization header
The node answers with 200 OK and whether the DPoP header is valid:
{
"valid": false,
"reason": "DPoP proof is expired"
}
valid: true: the DPoP header belongs to this token and this request.
valid: false: reject the request with 401 Unauthorized. reason says why.
Use the URL as the requester called it, not as your API sees it after a reverse proxy rewrote it. Otherwise the check fails.
3. Decide whether to allow the query
The Nuts node doesn't decide whether the requester may see this data. Your application does, using the introspection result and the rules of the use case.
For 360-graden-clientbeeld, the rules are in volume 2a of the IG. In short:
organization_ura) must be identified, and the user (employee_identifier, employee_role) must be present for the audit log.
There must be a legal basis: consent registered in Mitz, the requester is in the patient's CareTeam, or another legal basis.
The request must be about one patient: a BSN in /Patient/_search, otherwise a reference to the Patient.
You don't have to build this from scratch:
Log every request with the discoveryrequester's service,organization anyand constraintuser, inas the presentation definition of the policy file is also added as key/value pair to the introspection result. This is the mechanism to use attestationscase from presented credentials for authorization purposes.requires.
TheAPI tokenreference: introspectionAuth result is the last thing the Nuts node can do for you. From this point you have to apply the authorization policy...(v2)