Netherlands - Generic Functions for data exchange Implementation Guide
0.2.0 - ci-build Netherlands flag

Netherlands - Generic Functions for data exchange Implementation Guide, published by Stichting Nuts. This guide is not an authorized publication; it is the continuous build for version 0.2.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/nuts-foundation/nl-generic-functions-ig/ and changes regularly. See the Directory of published versions

Token introspection [GFI-006]

Scope

The transaction Introspect Access Token allows a resource server (Custodian) to validate and obtain metadata about an access token issued by an authorization server (Verifier).

The introspection returns the active state of the token along with additional the identity claims associated with the token. This information can be used by the resource server down stream during the authorization decision.

The introspection transaction is added so the access token format can be opaque to the resource server. This allows the authorization server to use any token format, including self-contained tokens such as JWTs, without requiring the resource server to understand the token format.

In case the access token is a self-contained token such as a JWT, the resource server can validate the token locally without needing to call the introspection endpoint. However, the resource server needs to be able to validate the token signature and parse the token claims which adds complexity and duplicates logic that is already present in the authorization server.

Actor Roles

Actor Role
Custodian Validates the access token and retrieves metadata about the token from the authorization server
Verifier Provides an introspection endpoint to validate access tokens and return associated metadata

Referenced standards

Messages

  1. Introspect Access Token Request
  2. Introspect Access Token Response
Resource ServerVerifierResource ServerVerifierIntrospect Access Token RequestIntrospect Access Token Response

Introspect Access Token Request

Trigger events
  • A resource server (Custodian) needs to validate an access token presented by a client (Holder) and obtain metadata about the token and identity claims of the holder.
Message semantics

The resource server initiates an introspect access token request using a HTTP POST request to the authorization server's introspection endpoint. The request includes the access token to be introspected.

Example

Below is a non-normative example of an Introspect Access Token Request:

POST /introspect HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

token=Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU

Introspect Access Token Response

Trigger events
  • The authorization server responds to the introspect access token request with the active state of the token and associated metadata.
Message semantics

The authorization server responds with a HTTP 200 OK response containing a JSON object in the body of the response. The JSON object includes an active boolean field indicating whether the token is valid.

The iss must be the decentralized identifier (DID) of the authorization server. The aud must be the decentralized identifier (DID) of the custodian.

For a DPoP bound access token, the response also includes a cnf claim containing the public key information that can be used to verify the DPoP proof presented by the client as defined in Section 6.2 of RFC 9449.

The response may also include the identity claims associated with the token in the assertions a client_assertions properties. Claims are grouped by subject and each claim has an array of objects with the metadata of the claim, such as the issuer, validity period and the actual claim value.

Example

Below is a non-normative example of an Introspect Access Token Response:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
  "active": true,
  "scope": "read write",
  "token_type": "DPoP",
  "exp": 1419356238,
  "iat": 1419350238,
  "nbf": 1419350238,
  "aud": "did:web:custodian.example.com",
  "iss": "did:web:verifier.example.com",
  "jti": "123e4567-e89b-12d3-a456-426614174000",
  "cnf": {
    "jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
  },
  "assertions": {
    "did:web:example.com:users:john": {
      "name": [{
        "value": "John Doe",
        "iss": "https://issuer.example.com",
        "iat": 1618884473,
        "exp": 1672531199
      }],
      "email": [{
        "value": "john@example.com",
        "iss": "https://issuer.example.com",
        "iat": 1618884473,
        "exp": 1672531199
      },{
        "value": "john.doe@other.example.com",
        "iss": "https://other-issuer.example.com",
        "iat": 1618884473,
        "exp": 1672531199
      }]
    },
    "did:web:org.example.com": {
      "identifier": [{
        "value": {
            "type": "Organization",
            "name": "Example Org",
            "registrationNumber": "123456789"
        },
        "iss": "https://issuer.example.com",
        "iat": 1618884473,
        "exp": 1672531199
      }]
    }
  },
  "client_assertions": {
    "did:web:example.com:apps:myapp": {
      "app_id": [{
         "value": "myapp",
         "iss": "https://auth.example.com",
         "iat": 1618884473,
         "exp": 1672531199
      }],
      "certification": [{
        "value": "UseCase1,UseCase2",
        "iss": "https://auth.example.com",
        "iat": 1618884473,
        "exp": 1672531199
      }]
    }
  }
}
Expected actions
Response Handling

Case 1: The access token is valid. HTTP 200 (OK) is returned as the HTTP status code. The response body contains a JSON object with the active field set to true and additional metadata about the token and identity claims.

Case 2: The access token is invalid or expired. HTTP 200 (OK) is returned as the HTTP status code. The response body contains a JSON object with the active field set to false. Other fields may be omitted or set to null. Case 3: The introspection request is malformed or missing required parameters. HTTP 400 (Bad Request) is returned as the HTTP status code. The response body contains an error message indicating the issue with the request.

DPoP Proof Validation

The authorization server does not check the validity of the DPoP proof. The resource server must validate the DPoP proof separately by checking the cnf.jkt claim in the introspection response against the DPoP proof presented by the client. This claim contains the JWK thumbprint of the public key used to sign the DPoP proof. The resource server must ensure that the jkt value matches the thumbprint of the public key in the DPoP proof to confirm that the client possesses the private key corresponding to the public key.