From 5c01bc170cd5259a9241227e00fd6c036a73b430 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Tue, 23 Sep 2025 16:19:42 +0200 Subject: [PATCH 01/17] Add authentication skeleton --- input/pagecontent/authentication.md | 123 ++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index e69de29..e592a86 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -0,0 +1,123 @@ +### Introduction + +Why is authentication important? + +#### Requirements + +- Peer 2 peer authentication without the need of a central authority +- Support of multiple identity claims from different issuers +- Support for use-cases with and without a end-user (healthcare professional) +- Support for authorizing vendors to act on behalf of an (care) organisation +- Support for authorizing (care) organisations to act on behalf of a healthcare professional +- User-friendly solution for healthcare professionals +- Cost efficient solution for care organisations +- Flexible solution that can be adapted to different use-cases +- Privacy by design +- Securty by design +- Support for leveraging existing identity solutions + +#### Terminology + +- Identity: A set of claims about an entity (person or organisation) +- Claim: A statement about an entity (e.g. name, role, affiliation) +- Authentication: The process of verifying the identity of an entity +- Authorization: The process of granting access to resources based on the identity of an entity +- Use-case: A specific scenario in which authentication and authorization are required + +### Solution overview + +The solution is based on requesting identity tokens from a OpenID Connect (OIDC) authorization server based on identity claims presented in a verifiable presentation (VP). + +#### Identity claims repository + +Several identity claims are required to be presented. Which claims are required depends on the use-case. Each of the claims have different properties such as: + +- Who can issue the claim +- How can the claim be verified +- What is the level of assurance of the claim +- Under which conditions can the claim be used +- Lifecycle of the claim (expiration, revocation, renewal) + +In order for use-case writers to define which claims are required, a repository is needed that keeps track of the claims and its properties. + +#### Mechanics + +The following steps are required to establish the identity of a healthcare organisation and professional in a specific use-case. + +##### Setup for organisations + +- Choose a identity wallet provider +- Acuire identity claims +- Choose a vendor and authorize it to act on your behalf for a specific use-case +- Issue relationship credentials to each healthcare professional + +##### Setup for healthcare professionals + +- Choose a wallet +- Acquire identity claims from DEZI and your branch organization +- Acquire relationship credentials from your care organisation +- authorize the organisation to act on your behalf for a limited amount of time (e.g. 1 day) + +##### Asserting identity + +In the context of a use-case, several identity claims are required to be presented to the verifier. + +- Get a fresh nonce from the nonce endpoint of the verifier +- Gather the required claims from your wallet or other sources +- Create a verifiable presentation including the nonce +- Present the verifiable presentation to the verifier + +##### Verifying identity + +- Verify the verifiable presentation + - Verify the nonce + - verify the signature + - verify the expiration date +- verify the claims + - Verify the signatures + - Verify the revocation status + - verify the issuer + - verify the expiration date +- Respond with a bearer token + +##### Interacting with the resource server + +- Present the bearer token to the resource server along side the request +- Check the DPoP proof (or other token binding mechanism) +- The resource server verifies the bearer token by introspecting it at the oauth-authorization server +- The oauth-authorization server replies with the token status and the the provided identity claims +- The resource server verifies the token status +- The resource server verifies the identity claims and the relationships + +### The actors + +- Care organisation +- Healthcare professional +- Vendor +- Verifier +- Claim Issuer + +#### Relations between the actors + +Vendors get authorized by care organisations to act on their behalf. +The care organisation's identity can be represented by one of the trusted Vendors. + +### Use-cases + +Different use-cases have different requirements for identity claims. + +Each use-case requires its own governance in which it defines the needed identity claims and the trust framework in which the actors operate. + +### Sercurity considerations + +#### Token binding + +#### No sharing of Private Keys of certificates + +#### use of TLS + +Use of TLS for the vendor + +#### replay attacks + +nonce and timestamps From d7a6412bcb6b25b5242292b20b633ae23b7f092a Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Wed, 24 Sep 2025 18:18:57 +0200 Subject: [PATCH 02/17] Add layers with description 4 layers, loosely based on ToIP model describing it's responsibility and choices. --- input/pagecontent/authentication.md | 96 +++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 20 deletions(-) diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index e592a86..f235afa 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -26,7 +26,63 @@ Why is authentication important? ### Solution overview -The solution is based on requesting identity tokens from a OpenID Connect (OIDC) authorization server based on identity claims presented in a verifiable presentation (VP). +The solution is based on exchanging verifiable identity claims between the involved parties. The claims can be flexibily combined to form a complete identity for a specific use-case. The claims can be verified by the verifier without the need of a central authority using cryptographic techniques. + +#### Layered approach + +Autentication is vast and complex topic. To keep the information structured we will use a layered approach. The layers are: + +1. Trust layer +2. Peer-to-peer layer +3. Identity claims layer +4. Application layer + +##### Trust layer + +The trust layer defines techniques and governance to establish trust between entities. Each entity needs an identity in in the form of an identifier. +In order to establish trust into an entity, a party must be able to verify the identifier of the entity. Some identifiers are easier to verify than other. Identifiers that can be verified are called verifiable identifiers (VIDs). +How a verifier can verify a VID depends on the type of identifier. +Identifiers can either be externally verified by an authority (XVIDs), or self-certifying (SCIDs). Many identifiers we know are externally verified, such as your phone number or bank account. Self-certifying identifiers can be verified by a verifier without the need of a third party. An example of a self-certifying identifier is a DID (Decentralized Identifier). + +Self-certifying identifiers are very useful in peer-to-peer scenarios, because they do not require a central authority to verify the identifier. This makes them suitable for use-cases where entities need to interact with each other without the need of a central authority. + +Once an entity has a verifiable identifier, it can use this identifier to link non-verifiable identifiers to its identity. This will be explained in the identity claims layer. + +##### Peer-to-peer layer + +The peer-to-peer layer defines the protocols and mechanisms to establish a secure communication channel between two entities. + +Each entity needs a digital agent to act on its behalf. The digital agent is responsible for managing the SCID, establishing secure communication channels, issuing and presenting identity claims. + +This layer describes the protocols and data standards which can be used between the digital agents of the involved parties to aqcuire, present, and verify identity claims. + +The identity of the above trust layer itself is not that useful in the real world. But when it is combined with identity claims it becomes useful. Identity claims are statements about an entity that can be used to verify its identity in a specific context. By combining the SCID with identity claims, an entity can prove the ownership of the claims. + +##### Identity claims + +The identity claims layer defines the workings of specific identity claims. Identity claims contain inforarmation about the entity such as its name, role, and affiliation. Identity claims can also be XVIDs which can not be self-certified. +These claims are usual managed by existing governance structures such as professional branches and governmental bodies. A chamber of commerce number is an result of such a governance structure. +This layer describes the information in the specific claim, how the claim can be acquired, presented, and verified. It also describes the assurance levels and the lifecycle of the claim, and the trust framework in which the claim can be used. + +In order for use-case designers to choose from the available claims, a repository is needed that keeps track of the all available claims, their properties and governance bodies. + +##### Application layer + +The application layer defines the specific use-cases in which authentication and authorization are required. This includes the specific set of identity claims that are required to be presented, the trust framework in which the entities operate, and the protocols and mechanisms to establish a secure communication channel. It uses the lower layers of the stack to achieve this. + +#### Choice of technologies per layer + +| Layer | Technology / Standard | Description | +| ------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| Trust layer | DID (Decentralized Identifier) | DID web, a domain name based identifier that hosts the DID document conaining the public key | +| Trust layer | PKI (Public Key Infrastructure) | X.509 certificates for the service providers of the digital agents | +| Peer-to-peer layer | OpenID Connect for Verifiable Credential Issuance (OIDC4VCI) | Protocol to request and issue verifiable credentials between digital agents and authoritative registries | +| Peer-to-peer layer | [RFC 7523](https://www.rfc-editor.org/rfc/rfc7523) | JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants to request Access tokens based on a Verifiable Presentation | +| Peer-to-peer layer | DPoP (Demonstrating Proof-of-Possession at the Application Layer) | Mechanism to bind an access token to a public key to prevent token theft | +| Peer-to-peer layer | StatusList 2021 (Revocation mechanism for VCs) | Standard for revoking verifiable credentials | +| Identity claims | Verifiable Credentials (VC) | Standard for expressing identity claims in a cryptographically verifiable way | +| Identity claims | Verifiable Presentations (VP) | Standard for presenting a set of verifiable credentials in a cryptographically verifiable way | +| Application layer | Digital Credential Query Language (DCQL) | Standard for expressing the required identity claims in a specific use-case | #### Identity claims repository @@ -42,6 +98,25 @@ In order for use-case writers to define which claims are required, a repository #### Mechanics +### The actors + +- Care organisation +- Healthcare professional +- Vendor +- Verifier +- Claim Issuer + +#### Relations between the actors + +Vendors get authorized by care organisations to act on their behalf. +The care organisation's identity can be represented by one of the trusted Vendors. + +### Use-cases + +Different use-cases have different requirements for identity claims. + +Each use-case requires its own governance in which it defines the needed identity claims and the trust framework in which the actors operate. + The following steps are required to establish the identity of a healthcare organisation and professional in a specific use-case. ##### Setup for organisations @@ -89,25 +164,6 @@ In the context of a use-case, several identity claims are required to be present - The resource server verifies the token status - The resource server verifies the identity claims and the relationships -### The actors - -- Care organisation -- Healthcare professional -- Vendor -- Verifier -- Claim Issuer - -#### Relations between the actors - -Vendors get authorized by care organisations to act on their behalf. -The care organisation's identity can be represented by one of the trusted Vendors. - -### Use-cases - -Different use-cases have different requirements for identity claims. - -Each use-case requires its own governance in which it defines the needed identity claims and the trust framework in which the actors operate. - ### Sercurity considerations #### Token binding From 941603b83dedd53b4fedd16d4d2f4e7c761c4439 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Fri, 26 Sep 2025 14:35:08 +0200 Subject: [PATCH 03/17] More tekst --- input/pagecontent/authentication.md | 40 ++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index f235afa..2696abd 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -1,29 +1,61 @@ ### Introduction -Why is authentication important? +Authentication is the process of verifying the identity of an entity. In the context of healthcare, authentication is used to verify the identity of healthcare professionals and care organisations. This is important to ensure that only authorized entities can access sensitive information and resources. + +The verified identity is often used downstream for authorization and accounting purposes. Authorization is the process of granting access to resources based on the identity of an entity. Accounting is the process of tracking the actions of an entity. #### Requirements -- Peer 2 peer authentication without the need of a central authority -- Support of multiple identity claims from different issuers +There exists a multitude of authentication solutions, therefore it is important to define the requirements for a authentication in the context of healthcare. The requirements are: + +- Work with identity claims from the authoritative sources +- Support combinations of identity claims from different trusted issuers - Support for use-cases with and without a end-user (healthcare professional) - Support for authorizing vendors to act on behalf of an (care) organisation +- Support for limiting the scope of an authorization of a vendor - Support for authorizing (care) organisations to act on behalf of a healthcare professional - User-friendly solution for healthcare professionals - Cost efficient solution for care organisations - Flexible solution that can be adapted to different use-cases +- No single point of failure - Privacy by design - Securty by design - Support for leveraging existing identity solutions #### Terminology -- Identity: A set of claims about an entity (person or organisation) +Throughout this document the following terminology is used: + +- Entity: An actor in the system (person or organisation) +- Agent: A digital representation of an entity that acts on its behalf, also often called an identity wallet +- Vendor: A party that offers Agents to its customers (care organisations and healthcare professionals) +- Identity: A set of claims about an entity (person or organisation) which is relevant in a specific context +- Verifiable Identifier (VID): An identifier that can be (cryptographically) verified - Claim: A statement about an entity (e.g. name, role, affiliation) +- Verifiable Claim: A claim that can be cryptographically verified +- Issuer: An entity that issues claims about another entity +- Authoritative source: An issuer that is trusted to issue claims about a specific entity +- Verifier: An entity that verifies the identity of another entity based on its claims +- Holder: An entity that holds claims about itself or is authorized to present claims about another entity - Authentication: The process of verifying the identity of an entity - Authorization: The process of granting access to resources based on the identity of an entity - Use-case: A specific scenario in which authentication and authorization are required +#### Problem overview + +A tipical scenario in healthcare is that a healthcare professional needs to access a resource (e.g. patient data) which is located at a different organisation (e.g. a hospital). +In the Netherlands, the custodian of the patient data is by law forbidden to share the data with third parties. Several exceptions to that rule exists. One responsibility of the custodian is to ensure that the requesting party is authorized to access the data. In order to do so, the custodian needs to verify the identity of the requesting party. + +In practice, many of these data exchanges are not done directly between the healthcare professionals, but between computers and systems. Often these systems are operated by vendors on behalf of the care organisations. + +On top of that, use-cases are often described and governed by a governing body. The governing body certifies healthcare organisations and vendors to operate in a specific use-case. The governing body defines the trust framework in which the use-case operates. The custodian also needs to verify that the entities operate within the trust framework of the use-case. + +The custodian needs to verify the identity of the requesting healthcare professional, working for an organisation which is a customer of a vendor. The custodian needs to verify the following: + +- The identity of the healthcare professional, identifier, role, and affiliation with the care organisation +- The identity of the care organisation, identifier, and its relationship with the healthcare professional +- The identity of the vendor, identifier, and its relationship with the care organisation + ### Solution overview The solution is based on exchanging verifiable identity claims between the involved parties. The claims can be flexibily combined to form a complete identity for a specific use-case. The claims can be verified by the verifier without the need of a central authority using cryptographic techniques. From 87f36faf0922e89eb16537f4621db3c016c157ff Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Wed, 1 Oct 2025 14:08:06 +0200 Subject: [PATCH 04/17] Add standards and examples to layers --- input/pagecontent/authentication.md | 166 ++++++++++++++++++++++++++-- 1 file changed, 157 insertions(+), 9 deletions(-) diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index 2696abd..4b5beb0 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -17,6 +17,7 @@ There exists a multitude of authentication solutions, therefore it is important - User-friendly solution for healthcare professionals - Cost efficient solution for care organisations - Flexible solution that can be adapted to different use-cases +- Peer-2-peer trust which allows direct interactions between the involved parties without involvement of a third party - No single point of failure - Privacy by design - Securty by design @@ -58,37 +59,184 @@ The custodian needs to verify the identity of the requesting healthcare professi ### Solution overview -The solution is based on exchanging verifiable identity claims between the involved parties. The claims can be flexibily combined to form a complete identity for a specific use-case. The claims can be verified by the verifier without the need of a central authority using cryptographic techniques. +The solution is based on exchanging verifiable identity claims between the involved parties. +The claims can be flexibily combined to form a complete identity for a specific use-case. +The claims can be verified by the verifier without the need of a central authority, using cryptographic techniques. #### Layered approach -Autentication is vast and complex topic. To keep the information structured we will use a layered approach. The layers are: +Because authentication is a complex topic, this IG tries to structure the solution in a layered approach. Each layer has its own responsibilities and can be implemented using different technologies. The layers are: 1. Trust layer 2. Peer-to-peer layer 3. Identity claims layer 4. Application layer -##### Trust layer +#### Trust layer -The trust layer defines techniques and governance to establish trust between entities. Each entity needs an identity in in the form of an identifier. -In order to establish trust into an entity, a party must be able to verify the identifier of the entity. Some identifiers are easier to verify than other. Identifiers that can be verified are called verifiable identifiers (VIDs). +##### Overview + +The trust layer defines techniques and governance to establish trust between entities. Each entity needs an to be referenced by an identifier. +In order to establish trust into an entity, a verifier must be able to verify the ownership of the identifier by the entity. Some identifiers are easier to verify than other. Identifiers that can be verified are called verifiable identifiers (VIDs). How a verifier can verify a VID depends on the type of identifier. -Identifiers can either be externally verified by an authority (XVIDs), or self-certifying (SCIDs). Many identifiers we know are externally verified, such as your phone number or bank account. Self-certifying identifiers can be verified by a verifier without the need of a third party. An example of a self-certifying identifier is a DID (Decentralized Identifier). +Identifiers can either be externally verified by an authority (XVIDs), or self-certifying (SCIDs). Many identifiers we know are externally verified, such as your phone number or bank account. +Self-certifying identifiers can be verified by a verifier without the need of a third party. An example category of a self-certifying identifiers are DIDs (Decentralized Identifiers). Self-certifying identifiers are very useful in peer-to-peer scenarios, because they do not require a central authority to verify the identifier. This makes them suitable for use-cases where entities need to interact with each other without the need of a central authority. Once an entity has a verifiable identifier, it can use this identifier to link non-verifiable identifiers to its identity. This will be explained in the identity claims layer. -##### Peer-to-peer layer +##### Choice of self-certifying identifier + +The chosen solotion for the trust layer is the [Decentralized Identifiers v1.0 standard](https://www.w3.org/TR/did-1.0/) with the [did:web method](https://w3c-ccg.github.io/did-method-web/). This method uses a domain name as the identifier. The domain name is owned by the entity and ownership can be verified by the verifier by resolving the public key hosted at the domain. This method is secured by DNSSEC and HTTPS which gearentees the domainname resolves to the correct webservice and the traffic is not altered. + +##### Examples + +Example did:web + +``` +did:web:example.com:user:alice +``` + +Which resolves to the DID document at: + +``` +https://example.com/user/alice/did.json +``` + +Which contains the following DID Document: + +```json +{ + "@context": "https://www.w3.org/ns/did/v1", + "id": "did:web:example.com:user:alice", + "verificationMethod": [ + { + "id": "did:web:example.com:user:alice#key-1", + "type": "JsonWebKey2020", + "controller": "did:web:example.com:user:alice", + "publicKeyJwk": { + "kty": "EC", + "crv": "P-256", + "x": "...", + "y": "..." + } + } + ], + "authentication": ["did:web:example.com:user:alice#key-1"] +} +``` + +#### Peer-to-peer layer + +##### Overview The peer-to-peer layer defines the protocols and mechanisms to establish a secure communication channel between two entities. -Each entity needs a digital agent to act on its behalf. The digital agent is responsible for managing the SCID, establishing secure communication channels, issuing and presenting identity claims. +Each entity needs a digital agent to act on its behalf. The digital agent is responsible for managing the SCID, establishing secure communication channels with other parties, receiving and presenting identity claims. This layer describes the protocols and data standards which can be used between the digital agents of the involved parties to aqcuire, present, and verify identity claims. -The identity of the above trust layer itself is not that useful in the real world. But when it is combined with identity claims it becomes useful. Identity claims are statements about an entity that can be used to verify its identity in a specific context. By combining the SCID with identity claims, an entity can prove the ownership of the claims. +The identifier of the underlaying trust layer is not that useful by itself. But when it is combined with identity claims it becomes useful. Identity claims are statements about an entity that can be used to verify its identity in a specific context. By combining the SCID with identity claims, an entity can prove the ownership of the claims. + +##### Choice of protocols and standards + +The dataformat to express identity claims is the [Verifiable Credentials Data Model 1.1](https://www.w3.org/TR/vc-data-model/). This standard defines how to express claims in a cryptographically verifiable way. The claims can be issued by an issuer and presented by a holder to a verifier. + +To prove the ownership of a set of claims, the holder can create a [Verifiable Presentation](https://www.w3.org/TR/vc-data-model/#presentations-0) which contains one or more verifiable credentials. The verifiable presentation is signed by the holder key (which can be resolved using the method defined by the trusr layer) and can be verified by the verifier. + +Verifiable credentials and presentations can be expressed in different formats. We here choose to use the JWT format, because it is widely used and supported by many libraries and tools and is comparetible with existing OAuth 2.0 and OpenID Connect implementations. + +The protocol to request and issue verifiable credentials is [OpenID Connect for Verifiable Credential Issuance (OIDC4VCI)](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html). This protocol is based on OpenID Connect and OAuth 2.0 and defines how to request and issue verifiable credentials between a digital agent and an authoritative registry. + +The protocol to request access tokens is based on [RFC 7523](https://www.rfc-editor.org/rfc/rfc7523), an extension to the OAuth 2.x standard, which defines how to request access tokens using a JWT Authorization Grant combined with a Client Authentication assertion. The JWT Authorization Grant contains a Verifiable Presentation with the required identity claims. The Client Authentication assertion contains the identity of the client according, issued by an authoritative registry. + +In order to prevent token theft, the access token must be bound to the client. This can be done using [DPoP (Demonstrating Proof-of-Possession at the Application Layer)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop). DPoP is a mechanism to bind an access token to a private key, which is used to sign an aditional DPoP access token which is uniquely created for each request to the resource server. + +Verifiable credentials have a long lifetime, often several years. In order to be able to revoke a verifiable credential, a revocation mechanism is needed. The chosen revocation mechanism is [StatusList 2021](https://w3c-ccg.github.io/vc-status-list/), which defines a standard for revoking verifiable credentials using a bitstring. The verifier periodically retrieves (and caches) the statuslist and verifies the existance of the credential in the statuslist. + +##### Examples + +Example Verifiable Credential (VC) in JWT format: + +```json +{ + "iss": "did:web:example.com:issuer", + "sub": "did:web:example.com:user:alice", + "iat": 1516239022, + "exp": 1672531199, + "jti": "http://example.edu/credentials/3732", + "vc": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1" + ], + "type": ["VerifiableCredential", "AlumniCredential"], + "credentialSubject": { + "id": "did:web:example.com:user:alice", + "alumniOf": { + "id": "did:web:example.com:university:example", + "name": [ + { + "value": "Example University", + "lang": "en" + }, + { + "value": "Voorbeeld Universiteit", + "lang": "nl" + } + ] + } + }, + "credentialStatus": { + "id": "https://example.com/status/24#94567", + "type": "StatusList2021Entry", + "statusPurpose": "revocation", + "statusListIndex": "94567", + "statusListCredential": "https://example.com/status/24" + } + } +} +``` + +Example of a Verifiable Presentation (VP) in JWT format: + +```json +{ + "iss": "did:web:example.com:user:alice", + "aud": "https://verifier.example.com", + "iat": 1516239022, + "exp": 1516239322, + "jti": "http://example.edu/presentations/3732", + "vp": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1" + ], + "type": ["VerifiablePresentation"], + "verifiableCredential": [ + { + // verifiable credential 1 + }, + { + // verifiable credential 2 + } + ] + } +} +``` + +Example of an tokenn request using RFC 7523 with a VP in the JWT Authorization Grant: + +``` +POST /token HTTP/1.1 +Host: oauth.example.com +Content-Type: application/x-www-form-urlencoded +grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer& +assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6IjIyIn0...& +client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer& +client_assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6IjIyIn0... +``` ##### Identity claims From 7755d2fbba0c884d8d450312ad11089cbaefbd22 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Thu, 2 Oct 2025 10:37:04 +0200 Subject: [PATCH 05/17] Add more tekst to the layers --- input/pagecontent/authentication.md | 36 +++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index 4b5beb0..645a7ca 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -238,30 +238,46 @@ client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer& client_assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6IjIyIn0... ``` -##### Identity claims +#### Identity claims -The identity claims layer defines the workings of specific identity claims. Identity claims contain inforarmation about the entity such as its name, role, and affiliation. Identity claims can also be XVIDs which can not be self-certified. +The identity claims layer defines the workings of specific identity claims. +Identity claims contain information about the entity such as its name, role, and affiliation. +Identity claims can also be identifiers which can not be self-certified. These claims are usual managed by existing governance structures such as professional branches and governmental bodies. A chamber of commerce number is an result of such a governance structure. -This layer describes the information in the specific claim, how the claim can be acquired, presented, and verified. It also describes the assurance levels and the lifecycle of the claim, and the trust framework in which the claim can be used. + +The identity claims layer can be seen as the "Identification" part of the Generic Funtion "Identification & Authentication". + +This layer describes the information in the specific claim such as its schema. The isuer or issuers that are authorized to issue the claim and the trust framework in which the claim can be used. +It also describes the assurance levels and the lifecycle of the claim. In order for use-case designers to choose from the available claims, a repository is needed that keeps track of the all available claims, their properties and governance bodies. -##### Application layer +This IG will not define specific claims. Eventually a national repository of available claims should be established which can be used in healthcare. + +One of the challenges in architecture is crossing a gap between two technologies. Many existing identity claim technologies exist and are for example based on X.509 certificates or SAML assertions. These technologies are not directly compatible with the verifiable credentials technology. In order to bridge this gap, a mapping between the existing technologies and verifiable credentials is needed. + +This layer can specify techniques to solve interoperability such as introducing custom proof types, introducing a trusted party which can map the information, or define custom verification methods. None of these solutions are ideal. Each solution has its own trade-offs. This layer can be used to specify building blocks to solve these interoperability challenges. + +#### Application layer + +The application layer defines requirements for specific use-cases in which authentication and authorization are required. This includes the specific set of identity claims that are required to be presented, the trust framework in which the entities operate, and the protocols and mechanisms to establish a secure communication channel. It uses the lower layers of the stack to achieve this. + +To define the required identity claims, the [Digital Credential Query Language (DCQL)](https://identity.foundation/dcql/) can be used. This standard defines a way to express the required identity claims in a machine-readable way. The DCQL query can be used as a form of digital contract by the holder to gather the required claims from its wallet (or other sources) and by the verifier to verify the presented claims. -The application layer defines the specific use-cases in which authentication and authorization are required. This includes the specific set of identity claims that are required to be presented, the trust framework in which the entities operate, and the protocols and mechanisms to establish a secure communication channel. It uses the lower layers of the stack to achieve this. +The DCQL language does not have to be implented directly by holders or verifiers, but can be used by specifications to define the required claims in a machine-readable way. -#### Choice of technologies per layer +#### Summary of layers, technologies and standards | Layer | Technology / Standard | Description | | ------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -| Trust layer | DID (Decentralized Identifier) | DID web, a domain name based identifier that hosts the DID document conaining the public key | +| Trust layer | DID (Decentralized Identifier) | DID method did:web, a domain name based identifier that hosts the DID document conaining the public key | | Trust layer | PKI (Public Key Infrastructure) | X.509 certificates for the service providers of the digital agents | | Peer-to-peer layer | OpenID Connect for Verifiable Credential Issuance (OIDC4VCI) | Protocol to request and issue verifiable credentials between digital agents and authoritative registries | | Peer-to-peer layer | [RFC 7523](https://www.rfc-editor.org/rfc/rfc7523) | JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants to request Access tokens based on a Verifiable Presentation | | Peer-to-peer layer | DPoP (Demonstrating Proof-of-Possession at the Application Layer) | Mechanism to bind an access token to a public key to prevent token theft | -| Peer-to-peer layer | StatusList 2021 (Revocation mechanism for VCs) | Standard for revoking verifiable credentials | -| Identity claims | Verifiable Credentials (VC) | Standard for expressing identity claims in a cryptographically verifiable way | -| Identity claims | Verifiable Presentations (VP) | Standard for presenting a set of verifiable credentials in a cryptographically verifiable way | +| Peer-to-peer layer | StatusList2021 (Revocation mechanism for VCs) | Standard for revoking verifiable credentials | +| Peer-to-peer layer | Verifiable Credentials (VC) | Standard for expressing identity claims in a cryptographically verifiable way | +| Peer-to-peer layer | Verifiable Presentations (VP) | Standard for presenting a set of verifiable credentials in a cryptographically verifiable way | | Application layer | Digital Credential Query Language (DCQL) | Standard for expressing the required identity claims in a specific use-case | #### Identity claims repository From ef64c9d5d85d0c636432a90f1e605aabaf443081 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Fri, 3 Oct 2025 15:58:54 +0200 Subject: [PATCH 06/17] Add GFIs to authentication IG A GF-Interaction describes a set of relevant interactions between several actors. This commit add GFI 1, 2 and 3. --- input/images-source/gfi-001.plantuml | 16 +++ input/images-source/gfi-003.plantuml | 16 +++ .../authentication-overview-transactions.png | Bin 0 -> 59458 bytes input/pagecontent/GFI-001.md | 97 +++++++++++++ input/pagecontent/GFI-002.md | 26 ++++ input/pagecontent/GFI-003.md | 129 ++++++++++++++++++ input/pagecontent/GFI-004.md | 0 input/pagecontent/GFI-005.md | 0 input/pagecontent/authentication.md | 81 +++++------ sushi-config.yaml | 19 ++- 10 files changed, 334 insertions(+), 50 deletions(-) create mode 100644 input/images-source/gfi-001.plantuml create mode 100644 input/images-source/gfi-003.plantuml create mode 100644 input/images/authentication-overview-transactions.png create mode 100644 input/pagecontent/GFI-001.md create mode 100644 input/pagecontent/GFI-002.md create mode 100644 input/pagecontent/GFI-003.md create mode 100644 input/pagecontent/GFI-004.md create mode 100644 input/pagecontent/GFI-005.md diff --git a/input/images-source/gfi-001.plantuml b/input/images-source/gfi-001.plantuml new file mode 100644 index 0000000..f2ba58d --- /dev/null +++ b/input/images-source/gfi-001.plantuml @@ -0,0 +1,16 @@ +@startuml GFI-001 + +skinparam roundcorner 20 +skinparam defaultFontName Arial +hide footbox +activate issuer + +!pragma teoz true + +participant verifier as "Verifier" +participant issuer as "Issuer/Holder" + +verifier -> issuer: Resolve DID Document Request [GFI-001] +issuer --> verifier: DID Document Response [GFI-001] + +@enduml diff --git a/input/images-source/gfi-003.plantuml b/input/images-source/gfi-003.plantuml new file mode 100644 index 0000000..1812249 --- /dev/null +++ b/input/images-source/gfi-003.plantuml @@ -0,0 +1,16 @@ +@startuml GFI-003 + +skinparam roundcorner 20 +skinparam defaultFontName Arial +hide footbox +activate issuer + +!pragma teoz true + +participant verifier as "Verifier" +participant issuer as "Issuer" + +verifier -> issuer: Revocation Status Information Request [GFI-003] +issuer --> verifier: Revocation Status Information Response [GFI-003] + +@enduml diff --git a/input/images/authentication-overview-transactions.png b/input/images/authentication-overview-transactions.png new file mode 100644 index 0000000000000000000000000000000000000000..060f8fd65fc5a3046ab9a2f0dce10d4f0933a73e GIT binary patch literal 59458 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�D2M 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 +{% include GFI-001.svg %} + + +#### Resolve DID Document Request + +##### Trigger events + +A verifier needs to verify the authenticity of a signature on a verifiable credential or presentation. + +##### Message semantics + +A verifier initiates a resolve DID document request using a HTTP GET request to the DID web url. No further parameters are required. +The DID web url is constructed followint the rules as defined in the [DID Web Method](https://w3c-ccg.github.io/did-method-web/). + +##### Example + +Example did:web + +``` +did:web:example.com:user:alice +``` + +Which resolves to the DID document at: + +``` +GET https://example.com/user/alice/did.json +``` + +#### DID Document Response + +##### Trigger events + +The requested party responds to the resolve DID document request. + +##### Message semantics + +The requested party responds with a HTTP 200 OK response containing the DID document in the body of the response. The DID document is a JSON-LD document conforming to the [DID Core](https://www.w3.org/TR/did-core/) specification. + +##### Example + +```json +{ + "@context": "https://www.w3.org/ns/did/v1", + "id": "did:web:example.com:user:alice", + "verificationMethod": [ + { + "id": "did:web:example.com:user:alice#key-1", + "type": "JsonWebKey2020", + "controller": "did:web:example.com:user:alice", + "publicKeyJwk": { + "kty": "EC", + "crv": "P-256", + "x": "...", + "y": "..." + } + } + ], + "authentication": ["did:web:example.com:user:alice#key-1"] +} +``` + +##### Expected actions + +**Case 1**: The DID document is found on the server. + +`HTTP 200` (OK) is returned as the HTTP status code. + +A DID document is returned in the body of the response. + +**Case 2**: The DID document is not found on the server. + +`HTTP 404` (Not Found) is returned as the HTTP status code. + +No body is returned in the response. diff --git a/input/pagecontent/GFI-002.md b/input/pagecontent/GFI-002.md new file mode 100644 index 0000000..e666f80 --- /dev/null +++ b/input/pagecontent/GFI-002.md @@ -0,0 +1,26 @@ +### Scope + +The Issue Claims transaction describes the process of issuing verifiable claims from an authoritative issuer to a holder. The claims are typically encapsulated within a verifiable credential, which the holder can later present to verifiers as proof of certain attributes or qualifications. +The Issue Claims transaction can be initiated by the holder or the issuer, depending on the use case and the relationship between the parties involved. + +#### Optionality + +This transaction is optional and provides a standardized way requesting and transferring verifiable claims between an issuer and a holder. It is possible to request, issue and transfer these claims using other protocols such as email or other messaging systems. + +### Actor Roles + +| Actor | Role | +| ------ | --------------------------------------------------------------------------- | +| Issuer | Issues verifiable claims to a holder in the form of a verifiable credential | +| Holder | Receives verifiable claims from the issuer and stores them securely | + +### Referenced standards + +- [Verifiable Credentials Data Model 1.0](https://www.w3.org/TR/vc-data-model/) +- [OpenID4VCI](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html) + +### Messages + +1. Credential Offer +2. Credential Request +3. Credential Response diff --git a/input/pagecontent/GFI-003.md b/input/pagecontent/GFI-003.md new file mode 100644 index 0000000..9357920 --- /dev/null +++ b/input/pagecontent/GFI-003.md @@ -0,0 +1,129 @@ +### Scope + +The transaction Request Revocation Status is used by a verifier to determine the revocation status of a verifiable credential presented by a holder. The verifier sends a request to the revocation registry or authority specified in the credential to determine if the credential is still valid or has been revoked. + +### Actor Roles + +| Actor | Role | +| -------- | -------------------------------------------------------------------------------------- | +| Verifier | Requests the revocation information of a verifiable credential | +| Issuer | Provides the revocation information which the verifier can use to determine the status | + +### Referenced standards + +- [Verifiable Credentials Data Model 2.0](https://www.w3.org/TR/vc-data-model/) +- [Bitstring Status List v1.0](https://www.w3.org/TR/vc-bitstring-status-list/) + +### Messages + +1. Revocation Status Information Request +1. Revocation Status Information Response + +

+{% include GFI-003.svg %} +
+ +#### Revocation Status Information Request + +##### Trigger events + +- A Holder presents a verifiable credential to a verifier and the verifier needs to check the revocation status of the credential. +- A timer based event to refresh the revocation status information based on the `ValidUntil` field in the status list credential. + +##### Message semantics + +The verifier initiates a revocation status information request using a HTTP GET request to the revocation URL specified in the verifiable credential under the `credentialStatus` property. Such as specified in the [Bitstring Status List v1.0](https://www.w3.org/TR/vc-bitstring-status-list/) specification. + +##### Example + +Note: these examples are non normative, for implementation the actual specifications should be followed. + +Example of a revocable Verifiable Credential: + +```json +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1", + "https://w3id.org/vc/status-list/2021/v1" + ], + "id": "http://example.edu/credentials/3732", + "type": ["VerifiableCredential", "UniversityDegreeCredential"], + "issuer": "https://example.edu/issuers/14", + "issuanceDate": "2020-03-10T04:24:12.164Z", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "degree": { + "type": "BachelorDegree", + "name": "Bachelor of Science and Arts" + } + }, + "credentialStatus": { + "id": "https://example.edu/status/24#94567", + "type": "BitstringStatusListEntry", + "statusPurpose": "revocation", + "statusListIndex": "94567", + "statusListCredential": "https://example.edu/status/24" + }, + "proof": { + "type": "RsaSignature2018", + "created": "2020-03-10T04:24:12Z", + "proofPurpose": "assertionMethod", + "verificationMethod": "https://example.edu/issuers/keys/1", + "jws": "..." + } +} +``` + +This results in the following request: + +``` +GET https://example.edu/status/24 +``` + +#### Revocation Status Information Response + +##### Trigger events + +The requested party responds to the revocation status information request. + +##### Message semantics + +The Issuer should respond with the latest version of the status list credential, signed with the Issuer's proofing method. + +##### Example + +Note: these examples are non normative, for implementation the actual specifications should be followed. + +Example of a Status List Credential response: + +```json +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/vc/status-list/2021/v1" + ], + "id": "https://example.edu/status/24", + "type": ["VerifiableCredential", "StatusList2021Credential"], + "issuer": "https://example.edu/issuers/14", + "validFrom": "2025-03-10T04:24:12Z", + "ValidUntil": "2025-03-10T08:24:12Z", + "credentialSubject": { + "id": "https://example.edu/status/24#list", + "type": "BitstringStatusList", + "statusPurpose": "revocation", + "encodedList": "H4sIAAAAAAAAA-3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAPgG6AAB" + }, + "proof": { + "type": "RsaSignature2018", + "created": "2020-03-10T04:24:12Z", + "proofPurpose": "assertionMethod", + "verificationMethod": "https://example.edu/issuers/keys/1", + "jws": "..." + } +} +``` + +##### Expected actions + +The verifier processes the status list credential as specified by the [Validate Algorithm section of the specification](https://www.w3.org/TR/vc-bitstring-status-list/#validate-algorithm) to determine the revocation status of the verifiable credential presented by the holder. The verifier decodes the `encodedList` field to obtain the bitstring representing the revocation status of credentials. The verifier checks the bit at the index specified in the `statusListIndex` field of the verifiable credential's `credentialStatus` property. If the bit is set to `1`, the credential is revoked; if it is set to `0`, the credential is valid. diff --git a/input/pagecontent/GFI-004.md b/input/pagecontent/GFI-004.md new file mode 100644 index 0000000..e69de29 diff --git a/input/pagecontent/GFI-005.md b/input/pagecontent/GFI-005.md new file mode 100644 index 0000000..e69de29 diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index 645a7ca..5933c0c 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -63,6 +63,27 @@ The solution is based on exchanging verifiable identity claims between the invol The claims can be flexibily combined to form a complete identity for a specific use-case. The claims can be verified by the verifier without the need of a central authority, using cryptographic techniques. +#### Actors and Transactions + +Overview of transactions in the authentication function. + +**Table 7.2-1: GF Authentication - Actors and Transactions** + +| Actor | Transaction | Initiator or Responder | Optionality | Reference | +| --------- | ----------------------------------- | ---------------------- | ----------- | --------------------------- | +| Verifier | Request key material [GFI-001] | Initiator | R | [\[GFI-001\]](GFI-001.html) | +| | Request Revocation status [GFI-003] | Initiator | R | [\[GFI-003\]](GFI-003.html) | +| | Request Access Token [GFI-004] | Responder | R | [GFI-004] | +| Holder | Issue Claims \[GFI-002\] | Responder | O | [\[GFI-002\]](GFI-002.html) | +| | Request Access Token [GFI-004] | Initiator | R | [GFI-004] | +| | Authenticated Interaction [GFI-005] | Initiator | R | [GFI-005] | +| Issuer | Issue Claims [GFI-002] | Initiator | O | [GFI-002] | +| | Request key material [GFI-001] | Responder | R | [\[GFI-001\]](GFI-001.html) | +| | Request Revocation status [GFI-003] | Responder | R | [\[GFI-003\]](GFI-003.html) | +| Custodian | Authenticated Interaction [GFI-005] | Responder | R | [GFI-005] | + +{: .grid .table-striped} + #### Layered approach Because authentication is a complex topic, this IG tries to structure the solution in a layered approach. Each layer has its own responsibilities and can be implemented using different technologies. The layers are: @@ -90,43 +111,6 @@ Once an entity has a verifiable identifier, it can use this identifier to link n The chosen solotion for the trust layer is the [Decentralized Identifiers v1.0 standard](https://www.w3.org/TR/did-1.0/) with the [did:web method](https://w3c-ccg.github.io/did-method-web/). This method uses a domain name as the identifier. The domain name is owned by the entity and ownership can be verified by the verifier by resolving the public key hosted at the domain. This method is secured by DNSSEC and HTTPS which gearentees the domainname resolves to the correct webservice and the traffic is not altered. -##### Examples - -Example did:web - -``` -did:web:example.com:user:alice -``` - -Which resolves to the DID document at: - -``` -https://example.com/user/alice/did.json -``` - -Which contains the following DID Document: - -```json -{ - "@context": "https://www.w3.org/ns/did/v1", - "id": "did:web:example.com:user:alice", - "verificationMethod": [ - { - "id": "did:web:example.com:user:alice#key-1", - "type": "JsonWebKey2020", - "controller": "did:web:example.com:user:alice", - "publicKeyJwk": { - "kty": "EC", - "crv": "P-256", - "x": "...", - "y": "..." - } - } - ], - "authentication": ["did:web:example.com:user:alice#key-1"] -} -``` - #### Peer-to-peer layer ##### Overview @@ -268,17 +252,18 @@ The DCQL language does not have to be implented directly by holders or verifiers #### Summary of layers, technologies and standards -| Layer | Technology / Standard | Description | -| ------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -| Trust layer | DID (Decentralized Identifier) | DID method did:web, a domain name based identifier that hosts the DID document conaining the public key | -| Trust layer | PKI (Public Key Infrastructure) | X.509 certificates for the service providers of the digital agents | -| Peer-to-peer layer | OpenID Connect for Verifiable Credential Issuance (OIDC4VCI) | Protocol to request and issue verifiable credentials between digital agents and authoritative registries | -| Peer-to-peer layer | [RFC 7523](https://www.rfc-editor.org/rfc/rfc7523) | JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants to request Access tokens based on a Verifiable Presentation | -| Peer-to-peer layer | DPoP (Demonstrating Proof-of-Possession at the Application Layer) | Mechanism to bind an access token to a public key to prevent token theft | -| Peer-to-peer layer | StatusList2021 (Revocation mechanism for VCs) | Standard for revoking verifiable credentials | -| Peer-to-peer layer | Verifiable Credentials (VC) | Standard for expressing identity claims in a cryptographically verifiable way | -| Peer-to-peer layer | Verifiable Presentations (VP) | Standard for presenting a set of verifiable credentials in a cryptographically verifiable way | -| Application layer | Digital Credential Query Language (DCQL) | Standard for expressing the required identity claims in a specific use-case | +| Layer | Transaction | Technology / Standard | Description | +| ------------------ | ----------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- | +| Trust layer | GFI-001 | DID (Decentralized Identifier) | DID method did:web, a domain name based identifier that hosts the DID document conaining the public key | +| Peer-to-peer layer | GFI-001 | OpenID Connect for Verifiable Credential Issuance (OIDC4VCI) | Protocol to request and issue verifiable credentials between digital agents and authoritative registries | +| Peer-to-peer layer | GFI-003 | [RFC 7523](https://www.rfc-editor.org/rfc/rfc7523) | JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants to request Access tokens based on a Verifiable Presentation | +| Peer-to-peer layer | GFI-005 | DPoP (Demonstrating Proof-of-Possession at the Application Layer) | Mechanism to bind an access token to a public key to prevent token theft | +| Peer-to-peer layer | GFI-003 | StatusList2021 (Revocation mechanism for VCs) | Standard for revoking verifiable credentials | +| Peer-to-peer layer | GFI-[002 | 003] | Verifiable Credentials (VC) | Standard for expressing identity claims in a cryptographically verifiable way | +| Peer-to-peer layer | GFI-003 | Verifiable Presentations (VP) | Standard for presenting a set of verifiable credentials in a cryptographically verifiable way | +| Application layer | None | Digital Credential Query Language (DCQL) | Standard for expressing the required identity claims in a specific use-case | + +{: .grid .table-striped} #### Identity claims repository diff --git a/sushi-config.yaml b/sushi-config.yaml index 1cdebb9..55a70a2 100644 --- a/sushi-config.yaml +++ b/sushi-config.yaml @@ -58,6 +58,21 @@ publisher: pages: index.md: title: Home + GFI-001.md: + title: 7:2.1 Request key material [GFI-001] + generation: markdown + GFI-002.md: + title: 7:2.2 Issue Claims [GFI-002] + generation: markdown + GFI-003.md: + title: 7:2.3 Request Revocation status [GFI-003] + generation: markdown + GFI-004.md: + title: 7:2.4 Request Access Token [GFI-004] + generation: markdown + GFI-005.md: + title: 7:2.5 Authenticated Interaction [GFI-005] + generation: markdown care-services.md: title: Care Services Directory @@ -125,7 +140,6 @@ menu: Authorization: authorization.html Artifacts: artifacts.html - # ╭───────────────────────────Less Common Implementation Guide Properties──────────────────────────╮ # │ Uncomment the properties below to configure additional properties on the ImplementationGuide │ # │ resource. These properties are less commonly needed than those above. │ @@ -258,4 +272,5 @@ instanceOptions: # Determines for which types of Instances SUSHI will automatically set id # if InstanceOf references a profile: # - # setId: always # always | standalone-only \ No newline at end of file + # setId: always # always | standalone-only + From 50d5ef224bd204d8c7d000b038259710fa059b87 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Fri, 3 Oct 2025 17:32:21 +0200 Subject: [PATCH 07/17] Add GFI-004 AT request Adds detailed description about requesting an access token using RFC7523 and VPs. --- input/images-source/gfi-004.plantuml | 19 ++ .../authentication-overview-transactions.png | Bin 59458 -> 63182 bytes input/pagecontent/GFI-004.md | 197 ++++++++++++++++++ input/pagecontent/authentication.md | 91 +------- 4 files changed, 221 insertions(+), 86 deletions(-) create mode 100644 input/images-source/gfi-004.plantuml diff --git a/input/images-source/gfi-004.plantuml b/input/images-source/gfi-004.plantuml new file mode 100644 index 0000000..66345ee --- /dev/null +++ b/input/images-source/gfi-004.plantuml @@ -0,0 +1,19 @@ +@startuml GFI-004 + +skinparam roundcorner 20 +skinparam defaultFontName Arial +hide footbox +autoactivate on + +!pragma teoz true + +participant holder as "Holder" +participant verifier as "Verifier" + +holder -> verifier: Nonce Request +verifier --> holder: Nonce Response + +holder -> verifier: Access Token Request +verifier --> holder: Access Token Response + +@enduml diff --git a/input/images/authentication-overview-transactions.png b/input/images/authentication-overview-transactions.png index 060f8fd65fc5a3046ab9a2f0dce10d4f0933a73e..f520a829c9af324d5eb7bb0c9fc0a90a2f0a0df6 100644 GIT binary patch literal 63182 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�D2M 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 +{% include GFI-004.svg %} + + +#### Nonce Request + +##### Trigger events + +- A client needs to obtain an access token from an authorization server and needs a nonce to include in the access token request. + +##### Message semantics + +The client initiates a nonce request using a HTTP POST request to the authorization server's nonce endpoint. No further parameters are required. + +##### Example + +Below is a non-normative example of a Nonce Request: + +``` +POST /nonce HTTP/1.1 +Host: example.com +Content-Length: 0 +``` + +#### Nonce Response + +##### Trigger events + +- The authorization server responds to the nonce request with a nonce that the client can use in the access token request. + +##### Message semantics + +The authorization server responds with a HTTP 200 OK response containing the nonce in the body of the response. The nonce is a random value that is used to prevent replay attacks. + +The nonce must be an opaque and non predictable value. Authorization server should implement a mechanism to ensure the nonce is only used once and has a limited lifetime. + +Due to the temporal nature of the nonce, the response should include a `Cache-Control: no-store` header to prevent caching of the nonce. + +##### Example + +Below is a non-normative example of a Nonce Response: + +``` +HTTP/1.1 200 OK +Content-Type: application/json +Cache-Control: no-store +{ + "nonce": "n-0S6_WzA2Mj" +} +``` + +##### Expected Actions + +- The client extracts the nonce from the response and includes it in the access token request. +- The authorization server stores the nonce and ensures it is only used once and has a limited lifetime. + +#### Access Token Request + +##### Trigger events + +- A client needs to obtain an access token from an authorization server and has obtained a nonce from the authorization server. + +##### Message semantics + +The client requests an access token from the authorization server using the OAuth 2.0 JWT bearer token flow as defined in [RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523). + +If the client wants to bind the access token to a specific key, it can include a DPoP header in the request as defined in [OAuth 2.0 Demonstration of Proof-of-Possession (DPoP)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop-04). + +Verifiable Credentials and Verifiable Presentations must be encoded as JWTs as defined in [Section 6.3.1 of the Verifiable Credentials Data Model 1.1](https://www.w3.org/TR/2022/REC-vc-data-model-20220303/#json-web-token). + +###### Request parameters + +The reqest must include the following information: + +- `grant_type`: Must be set to `urn:ietf:params:oauth:grant-type:jwt-bearer` +- `assertion`: A JWT assertion in the form of a verifiable presentation containing the verifiable credentials offered by the holder. The JWT must be signed by the holder and the proof must contain the nonce obtained from the authorization server. +- client_assertion: A JWT signed by the client to authenticate itself to the authorization server. The JWT is in the form of a Verifiable Presentation containing a verifiable credentials which contain the identifier of the client and its certifications/affiliations which authorizes the client to request the scopes it is requesting. Just like the `assertion` the `client_assertion` must also contain the nonce obtained from the authorization server to proof the ownership of the credentials. +- `scope`: (Optional) A space-separated list of scopes that the client is requesting. + +###### Assertions + +**The assertion** and **the client_assertion** must include the following claims: + +- `iss`: The issuer of the JWT. For the `assertion` this is the identifier of the holder. For the `client_assertion` this is the identifier of the client. +- `aud`: The audience of the JWT. This must be the identifier of the authorization server. +- `jti`: A unique identifier for the JWT. +- `nbf`: (Optional) The time before which the JWT must not be accepted for processing. +- `iat`: The time at which the JWT was issued. +- `exp`: The expiration time on or after which the JWT must not be accepted for processing. +- `nonce`: The nonce obtained from the authorization server. +- `vp`: The verifiable presentation containing the verifiable credentials. The `vp` claim must conform to the [Verifiable Credentials Data Model 1.0](https://www.w3.org/TR/vc-data-model/) specification. + +The request must be sent as a HTTP POST request to the authorization server's token endpoint with the `Content-Type` header set to `application/x-www-form-urlencoded`. + +##### Example + +Below is a non-normative example of an Access Token Request: + +``` +POST /token HTTP/1.1 +Host: example.com +Content-Type: application/x-www-form-urlencoded +grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer& +assertion=eyJhbGciOiJFUzI1NiIsInR5c& +client-assertion-type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer& +client_assertion=eyJhbGciOiJFUzI1NiIsInR5c& +scope=use-case1 use-case2 +``` + +Below is a non-normative example of a JWT assertion in the form of a verifiable presentation: + +```json +{ + "iss": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "jti": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", + "aud": "did:example:4a57546973436f6f6c4a4a57573", + "nbf": 1541493724, + "iat": 1541493724, + "exp": 1573029723, + "nonce": "n-0S6_WzA2Mj", + "vp": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1" + ], + "type": ["VerifiablePresentation"], + "verifiableCredential": ["... verifiable credential ..."] + } +} +``` + +#### Access Token Response + +##### Trigger events + +- The authorization server responds to the access token request with an access token that the client can use to access a protected resource. + +##### Message semantics + +The authorization server responds with a HTTP 200 OK response containing the access token in the body of the response. The response must include the following information: + +The access token is opaque to the client and the format is determined by the authorization server. + +If the client provided a DPoP header in the access token request, the authorization server must issue a DPoP-bound access token. + +- `access_token`: The access token issued by the authorization server. +- `token_type`: The type of the token issued. Must be set to `Bearer` or `DPoP`. +- `expires_in`: (Optional) The lifetime in seconds of the access token. +- `scope`: (Optional) The scope of the access token. + +##### Example + +Below is a non-normative example of an Access Token Response: + +``` +HTTP/1.1 200 OK +Content-Type: application/json +{ + "access_token": "SlAV32hkKG", + "token_type": "Bearer", + "expires_in": 3600, + "scope": "use-case1 use-case2" +} +``` + +##### Expected Actions + +- The client extracts the access token from the response and uses it to access the protected resource. diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index 5933c0c..6464e32 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -73,14 +73,16 @@ The claims can be verified by the verifier without the need of a central authori | --------- | ----------------------------------- | ---------------------- | ----------- | --------------------------- | | Verifier | Request key material [GFI-001] | Initiator | R | [\[GFI-001\]](GFI-001.html) | | | Request Revocation status [GFI-003] | Initiator | R | [\[GFI-003\]](GFI-003.html) | -| | Request Access Token [GFI-004] | Responder | R | [GFI-004] | +| | Request Access Token [GFI-004] | Responder | R | [\[GFI-004\]](GFI-004.html) | +| | Introspect Access Token [GFI-006] | Responder | O | [GFI-006] | | Holder | Issue Claims \[GFI-002\] | Responder | O | [\[GFI-002\]](GFI-002.html) | -| | Request Access Token [GFI-004] | Initiator | R | [GFI-004] | +| | Request Access Token [GFI-004] | Initiator | R | [\[GFI-004\]](GFI-004.html) | | | Authenticated Interaction [GFI-005] | Initiator | R | [GFI-005] | | Issuer | Issue Claims [GFI-002] | Initiator | O | [GFI-002] | | | Request key material [GFI-001] | Responder | R | [\[GFI-001\]](GFI-001.html) | | | Request Revocation status [GFI-003] | Responder | R | [\[GFI-003\]](GFI-003.html) | -| Custodian | Authenticated Interaction [GFI-005] | Responder | R | [GFI-005] | +| Custodian | Authenticated Interaction [GFI-005] | Responder | R | [\[GFI-005\]](GFI-005.html) | +| | Introspect Access Token [GFI-006] | Initiator | O | [GFI-006] | {: .grid .table-striped} @@ -139,89 +141,6 @@ In order to prevent token theft, the access token must be bound to the client. T Verifiable credentials have a long lifetime, often several years. In order to be able to revoke a verifiable credential, a revocation mechanism is needed. The chosen revocation mechanism is [StatusList 2021](https://w3c-ccg.github.io/vc-status-list/), which defines a standard for revoking verifiable credentials using a bitstring. The verifier periodically retrieves (and caches) the statuslist and verifies the existance of the credential in the statuslist. -##### Examples - -Example Verifiable Credential (VC) in JWT format: - -```json -{ - "iss": "did:web:example.com:issuer", - "sub": "did:web:example.com:user:alice", - "iat": 1516239022, - "exp": 1672531199, - "jti": "http://example.edu/credentials/3732", - "vc": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://www.w3.org/2018/credentials/examples/v1" - ], - "type": ["VerifiableCredential", "AlumniCredential"], - "credentialSubject": { - "id": "did:web:example.com:user:alice", - "alumniOf": { - "id": "did:web:example.com:university:example", - "name": [ - { - "value": "Example University", - "lang": "en" - }, - { - "value": "Voorbeeld Universiteit", - "lang": "nl" - } - ] - } - }, - "credentialStatus": { - "id": "https://example.com/status/24#94567", - "type": "StatusList2021Entry", - "statusPurpose": "revocation", - "statusListIndex": "94567", - "statusListCredential": "https://example.com/status/24" - } - } -} -``` - -Example of a Verifiable Presentation (VP) in JWT format: - -```json -{ - "iss": "did:web:example.com:user:alice", - "aud": "https://verifier.example.com", - "iat": 1516239022, - "exp": 1516239322, - "jti": "http://example.edu/presentations/3732", - "vp": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://www.w3.org/2018/credentials/examples/v1" - ], - "type": ["VerifiablePresentation"], - "verifiableCredential": [ - { - // verifiable credential 1 - }, - { - // verifiable credential 2 - } - ] - } -} -``` - -Example of an tokenn request using RFC 7523 with a VP in the JWT Authorization Grant: - -``` -POST /token HTTP/1.1 -Host: oauth.example.com -Content-Type: application/x-www-form-urlencoded -grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer& -assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6IjIyIn0...& -client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer& -client_assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6IjIyIn0... -``` - #### Identity claims The identity claims layer defines the workings of specific identity claims. From ede08a6a55492351b90e2d612faa8c32c6df8544 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Fri, 3 Oct 2025 17:45:16 +0200 Subject: [PATCH 08/17] Small fixes --- input/pagecontent/GFI-004.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/input/pagecontent/GFI-004.md b/input/pagecontent/GFI-004.md index 957e43f..0976565 100644 --- a/input/pagecontent/GFI-004.md +++ b/input/pagecontent/GFI-004.md @@ -2,7 +2,7 @@ The transaction Request Access Token is used by a client to obtain an access token from an authorization server. The client offers credentials from an holder to the authorization server which then verifies the credentials and answers with an access token that can be used to access a protected resource. -In order to proof possession of the credentials, the holder uses its private key to sign a challenge provided by the verifier. This process is known as Demonstration of Proof-of-Possession (DPoP). +In order to proof possession of the credentials, the holder uses its private key to sign a challenge provided by the verifier in the form of a nonce. This interaction is scoped on the interaction between two computers with not necessarily a human in the loop. Therefore the interaction is a back-channel interaction without a user-agent such as a web browser. For this reason the OAuth 2.0 Extension [RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523) is used to offer the credentials in the form of a JWT assertion directly to the token endpoint without the use of a authorization request. @@ -108,7 +108,7 @@ The reqest must include the following information: ###### Assertions -**The assertion** and **the client_assertion** must include the following claims: +The **assertion** and the **client_assertion** must include the following properties: - `iss`: The issuer of the JWT. For the `assertion` this is the identifier of the holder. For the `client_assertion` this is the identifier of the client. - `aud`: The audience of the JWT. This must be the identifier of the authorization server. @@ -166,12 +166,14 @@ Below is a non-normative example of a JWT assertion in the form of a verifiable ##### Message semantics -The authorization server responds with a HTTP 200 OK response containing the access token in the body of the response. The response must include the following information: +The verifier responds with a HTTP 200 OK response containing the access token in the body of the response. The access token is opaque to the client and the format is determined by the authorization server. If the client provided a DPoP header in the access token request, the authorization server must issue a DPoP-bound access token. +The response must include the following information: + - `access_token`: The access token issued by the authorization server. - `token_type`: The type of the token issued. Must be set to `Bearer` or `DPoP`. - `expires_in`: (Optional) The lifetime in seconds of the access token. From 785359be2f0da4569ddc131f3a32a7c7c6d65f45 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Mon, 6 Oct 2025 08:55:44 +0200 Subject: [PATCH 09/17] Add note about multitenancy to GFI-004 --- input/pagecontent/GFI-004.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/input/pagecontent/GFI-004.md b/input/pagecontent/GFI-004.md index 0976565..d8f568f 100644 --- a/input/pagecontent/GFI-004.md +++ b/input/pagecontent/GFI-004.md @@ -93,7 +93,9 @@ Cache-Control: no-store The client requests an access token from the authorization server using the OAuth 2.0 JWT bearer token flow as defined in [RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523). -If the client wants to bind the access token to a specific key, it can include a DPoP header in the request as defined in [OAuth 2.0 Demonstration of Proof-of-Possession (DPoP)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop-04). +If an authorization server is shared between multiple (care) organizations (e.t. a multi-tenant setup), the authentication server must have a path parameter or a different endpoint to identify the organization the client is requesting the access token for. The client should not have to know the internal identifier of the organization. The access token must be bound to the requested organization. + +If the client wants to bind the access token to a private key, it can include a DPoP header in the request as defined in [OAuth 2.0 Demonstration of Proof-of-Possession (DPoP)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop-04). Verifiable Credentials and Verifiable Presentations must be encoded as JWTs as defined in [Section 6.3.1 of the Verifiable Credentials Data Model 1.1](https://www.w3.org/TR/2022/REC-vc-data-model-20220303/#json-web-token). @@ -126,7 +128,7 @@ The request must be sent as a HTTP POST request to the authorization server's to Below is a non-normative example of an Access Token Request: ``` -POST /token HTTP/1.1 +POST /oauth/{tenant-id}/token HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer& From b7a635368827af780d61a6ebcee3590a4469f5b5 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Mon, 6 Oct 2025 16:29:47 +0200 Subject: [PATCH 10/17] Add GFI-005 Authenticated Request --- input/images-source/gfi-005.plantuml | 18 +++++ input/pagecontent/GFI-004.md | 2 +- input/pagecontent/GFI-005.md | 103 +++++++++++++++++++++++++++ input/pagecontent/authentication.md | 28 ++++---- 4 files changed, 136 insertions(+), 15 deletions(-) create mode 100644 input/images-source/gfi-005.plantuml diff --git a/input/images-source/gfi-005.plantuml b/input/images-source/gfi-005.plantuml new file mode 100644 index 0000000..dd06e11 --- /dev/null +++ b/input/images-source/gfi-005.plantuml @@ -0,0 +1,18 @@ +@startuml GFI-005 + +skinparam roundcorner 20 +skinparam defaultFontName Arial +hide footbox + +!pragma teoz true + +participant client as "Client" +participant RS as "Resource Server" + +client -> client: Create DPoP Proof +client -> RS: Authenticated API Request +activate RS +RS --> client: Authenticated API Response +deactivate RS + +@enduml diff --git a/input/pagecontent/GFI-004.md b/input/pagecontent/GFI-004.md index d8f568f..7a9b4f5 100644 --- a/input/pagecontent/GFI-004.md +++ b/input/pagecontent/GFI-004.md @@ -1,4 +1,4 @@ -# Scope +### Scope The transaction Request Access Token is used by a client to obtain an access token from an authorization server. The client offers credentials from an holder to the authorization server which then verifies the credentials and answers with an access token that can be used to access a protected resource. diff --git a/input/pagecontent/GFI-005.md b/input/pagecontent/GFI-005.md index e69de29..8a1aa57 100644 --- a/input/pagecontent/GFI-005.md +++ b/input/pagecontent/GFI-005.md @@ -0,0 +1,103 @@ +### Scope + +The transaction Authenticated Interaction describes a secure and authenticated communication channel between two parties, typically a client representing a holder and a data custodian protected by the verifier. This channel is created on the application layer using a token based authentication mechanism. + +This interaction describes how a client can use the access token in an HTTP request to interact with a RESTful API provided by a resource server at the Custodian. To prevent token theft and replay attacks, the client uses the OAuth 2.0 Demonstration of Proof-of-Possession (DPoP) mechanism to bind the access token to a public/private key pair held by the client. + +### Actor Roles + +| Actor | Role | +| --------- | ----------------------------------------------------------------------------------------------------- | +| Holder | Uses an access token to interact with a resource server at the custodian | +| Custodian | Provides a RESTful API to access and manage data, protected by an access token issued by the verifier | + +### Referenced standards + +- [OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749) +- [OAuth 2.0 Demonstration of Proof-of-Possession (DPoP)](https://datatracker.ietf.org/doc/html/rfc9449) + +### Messages + +1. Create DPoP Proof +2. Authenticated API Request +3. Authenticated API Response + +

+{% include GFI-005.svg %} +
+ +#### Create DPoP Proof + +##### Trigger events + +- A client needs to access or manage data at a custodian using a RESTful API and has obtained an access token from a verifier. + +##### Message semantics + +The client creates a DPoP proof JWT as specified in the [OAuth 2.0 Demonstration of Proof-of-Possession (DPoP)](https://datatracker.ietf.org/doc/html/rfc9449) specification. The DPoP proof JWT includes claims such as `htm` (HTTP method), `htu` (HTTP URI), `jti` (JWT ID), and `iat` (issued at time). + +##### Example + +Below is a non-normative example of a DPoP proof JWT: + +Header: + +```json +{ + "typ": "dpop+jwt", + "alg": "RS256", + "jwk": { + "kty": "RSA", + "e": "AQAB", + "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86..." + } +} +``` + +Payload: + +```json +{ + "htm": "GET", + "htu": "https://custodian.example.com/fhir/Patient/123", + "jti": "a-123", + "iat": 1618884473 +} +``` + +#### Authenticated API Request + +##### Trigger events + +- A client needs to access or manage data at a custodian using a RESTful API and has obtained an access token from a verifier. + +##### Message semantics + +The client creates a DPoP proof JWT as specified in the [OAuth 2.0 Demonstration of Proof-of-Possession (DPoP)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop-04) specification. The DPoP proof JWT includes claims such as `htm` (HTTP method), `htu` (HTTP URI), `jti` (JWT ID), and `iat` (issued at time). + +The Access Token must be included in the `Authorization` header as a DPoP token, and the DPoP proof JWT must be included in the `DPoP` header of the HTTP request. + +##### Example + +Below is a non-normative example of an Authenticated API Request: + +``` +GET /fhir/Patient/123 HTTP/1.1 +Host: custodian.example.com +Authorization: DPoP eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... +DPoP: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... +``` + +#### Authenticated API Response + +##### Trigger events + +- The custodian processes the authenticated API request and responds with the requested data or an appropriate status + +##### Message semantics + +The resource server verifies the DPoP proof and the access token included in the request. If the verification is successful and the access token is valid, the custodian processes the request accordingly and responds with the requested data or a status message. + +##### Expected Actions + +The resource server should store the `jti` claim from the DPoP proof until it expires, to prevent replay attacks. diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index 6464e32..5091ed5 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -69,20 +69,20 @@ The claims can be verified by the verifier without the need of a central authori **Table 7.2-1: GF Authentication - Actors and Transactions** -| Actor | Transaction | Initiator or Responder | Optionality | Reference | -| --------- | ----------------------------------- | ---------------------- | ----------- | --------------------------- | -| Verifier | Request key material [GFI-001] | Initiator | R | [\[GFI-001\]](GFI-001.html) | -| | Request Revocation status [GFI-003] | Initiator | R | [\[GFI-003\]](GFI-003.html) | -| | Request Access Token [GFI-004] | Responder | R | [\[GFI-004\]](GFI-004.html) | -| | Introspect Access Token [GFI-006] | Responder | O | [GFI-006] | -| Holder | Issue Claims \[GFI-002\] | Responder | O | [\[GFI-002\]](GFI-002.html) | -| | Request Access Token [GFI-004] | Initiator | R | [\[GFI-004\]](GFI-004.html) | -| | Authenticated Interaction [GFI-005] | Initiator | R | [GFI-005] | -| Issuer | Issue Claims [GFI-002] | Initiator | O | [GFI-002] | -| | Request key material [GFI-001] | Responder | R | [\[GFI-001\]](GFI-001.html) | -| | Request Revocation status [GFI-003] | Responder | R | [\[GFI-003\]](GFI-003.html) | -| Custodian | Authenticated Interaction [GFI-005] | Responder | R | [\[GFI-005\]](GFI-005.html) | -| | Introspect Access Token [GFI-006] | Initiator | O | [GFI-006] | +| Actor | Transaction | Initiator or Responder | Optionality | Reference | +| --------- | ----------------------------------------------------- | ---------------------- | ----------- | --------------------------- | +| Verifier | Request key material [GFI-001] | Initiator | R | [\[GFI-001\]](GFI-001.html) | +| | Request Revocation status [GFI-003] | Initiator | R | [\[GFI-003\]](GFI-003.html) | +| | Request Access Token [GFI-004] | Responder | R | [\[GFI-004\]](GFI-004.html) | +| | Introspect Access Token [GFI-006] | Responder | O | [GFI-006] | +| Holder | Issue Claims \[GFI-002\] | Responder | O | [\[GFI-002\]](GFI-002.html) | +| | Request Access Token [GFI-004] | Initiator | R | [\[GFI-004\]](GFI-004.html) | +| | Authenticated Interaction [\[GFI-005\]](GFI-005.html) | Initiator | R | [GFI-005] | +| Issuer | Issue Claims [GFI-002] | Initiator | O | [GFI-002] | +| | Request key material [GFI-001] | Responder | R | [\[GFI-001\]](GFI-001.html) | +| | Request Revocation status [GFI-003] | Responder | R | [\[GFI-003\]](GFI-003.html) | +| Custodian | Authenticated Interaction [GFI-005] | Responder | R | [\[GFI-005\]](GFI-005.html) | +| | Introspect Access Token [GFI-006] | Initiator | O | [GFI-006] | {: .grid .table-striped} From 534bd68e8fab92029cb8a198906c9689cde8fca8 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Tue, 7 Oct 2025 10:58:52 +0200 Subject: [PATCH 11/17] Add GFI-006 Token introspection --- input/images-source/gfi-006.plantuml | 16 +++ input/pagecontent/GFI-006.md | 164 +++++++++++++++++++++++++++ input/pagecontent/authentication.md | 28 ++--- sushi-config.yaml | 13 ++- 4 files changed, 202 insertions(+), 19 deletions(-) create mode 100644 input/images-source/gfi-006.plantuml create mode 100644 input/pagecontent/GFI-006.md diff --git a/input/images-source/gfi-006.plantuml b/input/images-source/gfi-006.plantuml new file mode 100644 index 0000000..3e94515 --- /dev/null +++ b/input/images-source/gfi-006.plantuml @@ -0,0 +1,16 @@ +@startuml GFI-006 + +skinparam roundcorner 20 +skinparam defaultFontName Arial +hide footbox +autoactivate on + +!pragma teoz true + +participant RS as "Resource Server" +participant AS as "Verifier" + +RS -> AS: Introspect Access Token Request +AS --> RS: Introspect Access Token Response + +@enduml diff --git a/input/pagecontent/GFI-006.md b/input/pagecontent/GFI-006.md new file mode 100644 index 0000000..0546f93 --- /dev/null +++ b/input/pagecontent/GFI-006.md @@ -0,0 +1,164 @@ +### 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 + +- [OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749) +- [OAuth 2.0 Token Introspection](https://datatracker.ietf.org/doc/html/rfc7662) +- [OAuth 2.0 Demonstration of Proof-of-Possession (DPoP)](https://datatracker.ietf.org/doc/html/rfc9449) + +### Messages + +1. Introspect Access Token Request +2. Introspect Access Token Response + +
+{% include GFI-006.svg %} +
+ +#### 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](https://datatracker.ietf.org/doc/html/rfc9449#section-6.2). + +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 seperately 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. diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index 5091ed5..2a56fec 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -69,20 +69,20 @@ The claims can be verified by the verifier without the need of a central authori **Table 7.2-1: GF Authentication - Actors and Transactions** -| Actor | Transaction | Initiator or Responder | Optionality | Reference | -| --------- | ----------------------------------------------------- | ---------------------- | ----------- | --------------------------- | -| Verifier | Request key material [GFI-001] | Initiator | R | [\[GFI-001\]](GFI-001.html) | -| | Request Revocation status [GFI-003] | Initiator | R | [\[GFI-003\]](GFI-003.html) | -| | Request Access Token [GFI-004] | Responder | R | [\[GFI-004\]](GFI-004.html) | -| | Introspect Access Token [GFI-006] | Responder | O | [GFI-006] | -| Holder | Issue Claims \[GFI-002\] | Responder | O | [\[GFI-002\]](GFI-002.html) | -| | Request Access Token [GFI-004] | Initiator | R | [\[GFI-004\]](GFI-004.html) | -| | Authenticated Interaction [\[GFI-005\]](GFI-005.html) | Initiator | R | [GFI-005] | -| Issuer | Issue Claims [GFI-002] | Initiator | O | [GFI-002] | -| | Request key material [GFI-001] | Responder | R | [\[GFI-001\]](GFI-001.html) | -| | Request Revocation status [GFI-003] | Responder | R | [\[GFI-003\]](GFI-003.html) | -| Custodian | Authenticated Interaction [GFI-005] | Responder | R | [\[GFI-005\]](GFI-005.html) | -| | Introspect Access Token [GFI-006] | Initiator | O | [GFI-006] | +| Actor | Transaction | Initiator or Responder | Optionality | Reference | +| --------- | --------------------------------------- | ---------------------- | ----------- | --------------------------- | +| Verifier | Request key material [GFI-001] | Initiator | R | [\[GFI-001\]](GFI-001.html) | +| | Request Revocation status [GFI-003] | Initiator | R | [\[GFI-003\]](GFI-003.html) | +| | Request Access Token [GFI-004] | Responder | R | [\[GFI-004\]](GFI-004.html) | +| | Introspect Access Token [GFI-006] | Responder | O | [\[GFI-006\]](GFI-006.html) | +| Holder | Issue Claims \[GFI-002\] | Responder | O | [\[GFI-002\]](GFI-002.html) | +| | Request Access Token [GFI-004] | Initiator | R | [\[GFI-004\]](GFI-004.html) | +| | Authenticated Interaction [\[GFI-005\]] | Initiator | R | [\[GFI-005\]](GFI-005.html) | +| Issuer | Issue Claims [GFI-002] | Initiator | O | [\[GFI-002\]](GFI-002.html) | +| | Request key material [GFI-001] | Responder | R | [\[GFI-001\]](GFI-001.html) | +| | Request Revocation status [GFI-003] | Responder | R | [\[GFI-003\]](GFI-003.html) | +| Custodian | Authenticated Interaction [GFI-005] | Responder | R | [\[GFI-005\]](GFI-005.html) | +| | Introspect Access Token [GFI-006] | Initiator | O | [\[GFI-006\]](GFI-006.html) | {: .grid .table-striped} diff --git a/sushi-config.yaml b/sushi-config.yaml index 55a70a2..296749f 100644 --- a/sushi-config.yaml +++ b/sushi-config.yaml @@ -59,19 +59,22 @@ pages: index.md: title: Home GFI-001.md: - title: 7:2.1 Request key material [GFI-001] + title: Request key material [GFI-001] generation: markdown GFI-002.md: - title: 7:2.2 Issue Claims [GFI-002] + title: Issue Claims [GFI-002] generation: markdown GFI-003.md: - title: 7:2.3 Request Revocation status [GFI-003] + title: Request Revocation status [GFI-003] generation: markdown GFI-004.md: - title: 7:2.4 Request Access Token [GFI-004] + title: Request Access Token [GFI-004] generation: markdown GFI-005.md: - title: 7:2.5 Authenticated Interaction [GFI-005] + title: Authenticated Interaction [GFI-005] + generation: markdown + GFI-006.md: + title: Token introspection [GFI-006] generation: markdown care-services.md: From 6c58b77e8588a185d343e40604248b39a04b6a61 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Tue, 7 Oct 2025 11:13:39 +0200 Subject: [PATCH 12/17] Fix TOC with subpages of Authz --- sushi-config.yaml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/sushi-config.yaml b/sushi-config.yaml index 296749f..922fd43 100644 --- a/sushi-config.yaml +++ b/sushi-config.yaml @@ -58,24 +58,6 @@ publisher: pages: index.md: title: Home - GFI-001.md: - title: Request key material [GFI-001] - generation: markdown - GFI-002.md: - title: Issue Claims [GFI-002] - generation: markdown - GFI-003.md: - title: Request Revocation status [GFI-003] - generation: markdown - GFI-004.md: - title: Request Access Token [GFI-004] - generation: markdown - GFI-005.md: - title: Authenticated Interaction [GFI-005] - generation: markdown - GFI-006.md: - title: Token introspection [GFI-006] - generation: markdown care-services.md: title: Care Services Directory @@ -94,6 +76,24 @@ pages: authentication.md: title: Authentication + GFI-001.md: + title: Request key material [GFI-001] + generation: markdown + GFI-002.md: + title: Issue Claims [GFI-002] + generation: markdown + GFI-003.md: + title: Request Revocation status [GFI-003] + generation: markdown + GFI-004.md: + title: Request Access Token [GFI-004] + generation: markdown + GFI-005.md: + title: Authenticated Interaction [GFI-005] + generation: markdown + GFI-006.md: + title: Token introspection [GFI-006] + generation: markdown authorization.md: title: Authorization From 0db84f29d4f0201f5b2a605eed02516293859e35 Mon Sep 17 00:00:00 2001 From: Roland Groen Date: Tue, 7 Oct 2025 11:50:27 +0200 Subject: [PATCH 13/17] Fix typo in authorization documentation: corrected "General Practioner" to "General Practitioner" and aligned diagram text accordingly. --- input/pagecontent/authorization.md | 52 +++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/input/pagecontent/authorization.md b/input/pagecontent/authorization.md index 7a00835..5d4eb98 100644 --- a/input/pagecontent/authorization.md +++ b/input/pagecontent/authorization.md @@ -16,13 +16,13 @@ A Care Plan is created by the Care Plan Service as the owner of a CarePlan. As t │ │ ┌───┴────┐ - │CarePlan┼───────────┬────────┐ - └───┬────┘ │ │ - │CPS │CPC │CPC - │ │ │ -┌────────┴─────────┐ ┌────┴───┐ ┌──┴───┐ -│General Practioner│ │Hospital│ │Physio│ -└──────────────────┘ └────────┘ └──────┘ + │CarePlan┼─────────────┬────────┐ + └───┬────┘ │ │ + │CPS │CPC │CPC + │ │ │ +┌────────┴───────────┐ ┌────┴───┐ ┌──┴───┐ +│General Practitioner│ │Hospital│ │Physio│ +└────────────────────┘ └────────┘ └──────┘ ``` ### A single context of care A Care Plan is bound to one single context, in the sense that, CSP assumes that all members of the CT are always allowed to access all relevant data. In the case they are not allowed to access all relevant data, they should not be part of the CT. This that case, a different CP should be created. If a patient is referred to another organization that should not have access to all relevant data of the patient, another (nested) CP should be created. @@ -34,25 +34,25 @@ A Care Plan is bound to one single context, in the sense that, CSP assumes that │ │ │ │ │ ┌───┴────┐ -│ │CarePlan┼───────────┬────────┐ -│ └───┬────┘ │ │ -│ │CPS │CPC │CPC -│ │ │ │ -│ ┌────────┴─────────┐ ┌────┴───┐ ┌──┴───┐ -│ │General Practioner│ │Hospital│ │Physio│ -│ └──────────────────┘ └────┬───┘ └──────┘ -│ │ -│ │CPS -│ │ -│ ┌───────┴───────┐ -└────────────────────┼Nested CarePlan│ - └───────┬───────┘ - │ - │CPC - ┌──────┴──────┐ - │Mental health│ - │care provider│ - └─────────────┘ +│ │CarePlan┼─────────────┬────────┐ +│ └───┬────┘ │ │ +│ │CPS │CPC │CPC +│ │ │ │ +│ ┌────────┴───────────┐ ┌────┴───┐ ┌──┴───┐ +│ │General Practitioner│ │Hospital│ │Physio│ +│ └────────────────────┘ └────┬───┘ └──────┘ +│ │ +│ │CPS +│ │ +│ ┌───────┴───────┐ +└──────────────────────┼Nested CarePlan│ + └───────┬───────┘ + │ + │CPC + ┌──────┴──────┐ + │Mental health│ + │care provider│ + └─────────────┘ ``` ### Model of Patients' consent From 79203ce93ddddb7f6c9d35400cf0744d8695153a Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Fri, 10 Oct 2025 10:46:31 +0200 Subject: [PATCH 14/17] Fix typos --- input/pagecontent/GFI-006.md | 2 +- input/pagecontent/authentication.md | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/input/pagecontent/GFI-006.md b/input/pagecontent/GFI-006.md index 0546f93..7b8b192 100644 --- a/input/pagecontent/GFI-006.md +++ b/input/pagecontent/GFI-006.md @@ -161,4 +161,4 @@ The response body contains an error message indicating the issue with the reques ###### DPoP Proof Validation -The authorization server does not check the validity of the DPoP proof. The resource server must validate the DPoP proof seperately 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. +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. diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index 2a56fec..82cdf07 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -20,7 +20,7 @@ There exists a multitude of authentication solutions, therefore it is important - Peer-2-peer trust which allows direct interactions between the involved parties without involvement of a third party - No single point of failure - Privacy by design -- Securty by design +- Security by design - Support for leveraging existing identity solutions #### Terminology @@ -44,7 +44,7 @@ Throughout this document the following terminology is used: #### Problem overview -A tipical scenario in healthcare is that a healthcare professional needs to access a resource (e.g. patient data) which is located at a different organisation (e.g. a hospital). +A typical scenario in healthcare is that a healthcare professional needs to access a resource (e.g. patient data) which is located at a different organisation (e.g. a hospital). In the Netherlands, the custodian of the patient data is by law forbidden to share the data with third parties. Several exceptions to that rule exists. One responsibility of the custodian is to ensure that the requesting party is authorized to access the data. In order to do so, the custodian needs to verify the identity of the requesting party. In practice, many of these data exchanges are not done directly between the healthcare professionals, but between computers and systems. Often these systems are operated by vendors on behalf of the care organisations. @@ -60,7 +60,7 @@ The custodian needs to verify the identity of the requesting healthcare professi ### Solution overview The solution is based on exchanging verifiable identity claims between the involved parties. -The claims can be flexibily combined to form a complete identity for a specific use-case. +The claims can be flexibly combined to form a complete identity for a specific use-case. The claims can be verified by the verifier without the need of a central authority, using cryptographic techniques. #### Actors and Transactions @@ -111,7 +111,7 @@ Once an entity has a verifiable identifier, it can use this identifier to link n ##### Choice of self-certifying identifier -The chosen solotion for the trust layer is the [Decentralized Identifiers v1.0 standard](https://www.w3.org/TR/did-1.0/) with the [did:web method](https://w3c-ccg.github.io/did-method-web/). This method uses a domain name as the identifier. The domain name is owned by the entity and ownership can be verified by the verifier by resolving the public key hosted at the domain. This method is secured by DNSSEC and HTTPS which gearentees the domainname resolves to the correct webservice and the traffic is not altered. +The chosen solution for the trust layer is the [Decentralized Identifiers v1.0 standard](https://www.w3.org/TR/did-1.0/) with the [did:web method](https://w3c-ccg.github.io/did-method-web/). This method uses a domain name as the identifier. The domain name is owned by the entity and ownership can be verified by the verifier by resolving the public key hosted at the domain. This method is secured by DNSSEC and HTTPS which guarantees the domainname resolves to the correct webservice and the traffic is not altered. #### Peer-to-peer layer @@ -121,7 +121,7 @@ The peer-to-peer layer defines the protocols and mechanisms to establish a secur Each entity needs a digital agent to act on its behalf. The digital agent is responsible for managing the SCID, establishing secure communication channels with other parties, receiving and presenting identity claims. -This layer describes the protocols and data standards which can be used between the digital agents of the involved parties to aqcuire, present, and verify identity claims. +This layer describes the protocols and data standards which can be used between the digital agents of the involved parties to acquire, present, and verify identity claims. The identifier of the underlaying trust layer is not that useful by itself. But when it is combined with identity claims it becomes useful. Identity claims are statements about an entity that can be used to verify its identity in a specific context. By combining the SCID with identity claims, an entity can prove the ownership of the claims. @@ -129,17 +129,17 @@ The identifier of the underlaying trust layer is not that useful by itself. But The dataformat to express identity claims is the [Verifiable Credentials Data Model 1.1](https://www.w3.org/TR/vc-data-model/). This standard defines how to express claims in a cryptographically verifiable way. The claims can be issued by an issuer and presented by a holder to a verifier. -To prove the ownership of a set of claims, the holder can create a [Verifiable Presentation](https://www.w3.org/TR/vc-data-model/#presentations-0) which contains one or more verifiable credentials. The verifiable presentation is signed by the holder key (which can be resolved using the method defined by the trusr layer) and can be verified by the verifier. +To prove the ownership of a set of claims, the holder can create a [Verifiable Presentation](https://www.w3.org/TR/vc-data-model/#presentations-0) which contains one or more verifiable credentials. The verifiable presentation is signed by the holder key (which can be resolved using the method defined by the trust layer) and can be verified by the verifier. -Verifiable credentials and presentations can be expressed in different formats. We here choose to use the JWT format, because it is widely used and supported by many libraries and tools and is comparetible with existing OAuth 2.0 and OpenID Connect implementations. +Verifiable credentials and presentations can be expressed in different formats. We here choose to use the JWT format, because it is widely used and supported by many libraries and tools and is compatible with existing OAuth 2.0 and OpenID Connect implementations. The protocol to request and issue verifiable credentials is [OpenID Connect for Verifiable Credential Issuance (OIDC4VCI)](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html). This protocol is based on OpenID Connect and OAuth 2.0 and defines how to request and issue verifiable credentials between a digital agent and an authoritative registry. The protocol to request access tokens is based on [RFC 7523](https://www.rfc-editor.org/rfc/rfc7523), an extension to the OAuth 2.x standard, which defines how to request access tokens using a JWT Authorization Grant combined with a Client Authentication assertion. The JWT Authorization Grant contains a Verifiable Presentation with the required identity claims. The Client Authentication assertion contains the identity of the client according, issued by an authoritative registry. -In order to prevent token theft, the access token must be bound to the client. This can be done using [DPoP (Demonstrating Proof-of-Possession at the Application Layer)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop). DPoP is a mechanism to bind an access token to a private key, which is used to sign an aditional DPoP access token which is uniquely created for each request to the resource server. +In order to prevent token theft, the access token must be bound to the client. This can be done using [DPoP (Demonstrating Proof-of-Possession at the Application Layer)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop). DPoP is a mechanism to bind an access token to a private key, which is used to sign an additional DPoP access token which is uniquely created for each request to the resource server. -Verifiable credentials have a long lifetime, often several years. In order to be able to revoke a verifiable credential, a revocation mechanism is needed. The chosen revocation mechanism is [StatusList 2021](https://w3c-ccg.github.io/vc-status-list/), which defines a standard for revoking verifiable credentials using a bitstring. The verifier periodically retrieves (and caches) the statuslist and verifies the existance of the credential in the statuslist. +Verifiable credentials have a long lifetime, often several years. In order to be able to revoke a verifiable credential, a revocation mechanism is needed. The chosen revocation mechanism is [StatusList 2021](https://w3c-ccg.github.io/vc-status-list/), which defines a standard for revoking verifiable credentials using a bitstring. The verifier periodically retrieves (and caches) the statuslist and verifies the existence of the credential in the statuslist. #### Identity claims @@ -150,7 +150,7 @@ These claims are usual managed by existing governance structures such as profess The identity claims layer can be seen as the "Identification" part of the Generic Funtion "Identification & Authentication". -This layer describes the information in the specific claim such as its schema. The isuer or issuers that are authorized to issue the claim and the trust framework in which the claim can be used. +This layer describes the information in the specific claim such as its schema. The issuer or issuers that are authorized to issue the claim and the trust framework in which the claim can be used. It also describes the assurance levels and the lifecycle of the claim. In order for use-case designers to choose from the available claims, a repository is needed that keeps track of the all available claims, their properties and governance bodies. @@ -222,7 +222,7 @@ The following steps are required to establish the identity of a healthcare organ ##### Setup for organisations - Choose a identity wallet provider -- Acuire identity claims +- Acquire identity claims - Choose a vendor and authorize it to act on your behalf for a specific use-case - Issue relationship credentials to each healthcare professional @@ -264,7 +264,7 @@ In the context of a use-case, several identity claims are required to be present - The resource server verifies the token status - The resource server verifies the identity claims and the relationships -### Sercurity considerations +### Security considerations #### Token binding From a51715440af18f276b8819f9aa8ee474f892f2f4 Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Fri, 10 Oct 2025 10:48:17 +0200 Subject: [PATCH 15/17] Fix typo --- input/pagecontent/GFI-001.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/pagecontent/GFI-001.md b/input/pagecontent/GFI-001.md index 8992704..de12c1b 100644 --- a/input/pagecontent/GFI-001.md +++ b/input/pagecontent/GFI-001.md @@ -33,7 +33,7 @@ A verifier needs to verify the authenticity of a signature on a verifiable crede ##### Message semantics A verifier initiates a resolve DID document request using a HTTP GET request to the DID web url. No further parameters are required. -The DID web url is constructed followint the rules as defined in the [DID Web Method](https://w3c-ccg.github.io/did-method-web/). +The DID web url is constructed following the rules as defined in the [DID Web Method](https://w3c-ccg.github.io/did-method-web/). ##### Example From 6e3dced0a6e341f7c7d66f4a0902d68cff46f97a Mon Sep 17 00:00:00 2001 From: stevenvegt Date: Fri, 10 Oct 2025 10:58:15 +0200 Subject: [PATCH 16/17] Fix typos --- input/pagecontent/GFI-004.md | 2 +- input/pagecontent/authentication.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/input/pagecontent/GFI-004.md b/input/pagecontent/GFI-004.md index 7a9b4f5..6232418 100644 --- a/input/pagecontent/GFI-004.md +++ b/input/pagecontent/GFI-004.md @@ -101,7 +101,7 @@ Verifiable Credentials and Verifiable Presentations must be encoded as JWTs as d ###### Request parameters -The reqest must include the following information: +The request must include the following information: - `grant_type`: Must be set to `urn:ietf:params:oauth:grant-type:jwt-bearer` - `assertion`: A JWT assertion in the form of a verifiable presentation containing the verifiable credentials offered by the holder. The JWT must be signed by the holder and the proof must contain the nonce obtained from the authorization server. diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index 82cdf07..484f5f1 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -6,7 +6,7 @@ The verified identity is often used downstream for authorization and accounting #### Requirements -There exists a multitude of authentication solutions, therefore it is important to define the requirements for a authentication in the context of healthcare. The requirements are: +There exists a multitude of authentication solutions, therefore it is important to define the requirements for authentication in the context of healthcare. The requirements are: - Work with identity claims from the authoritative sources - Support combinations of identity claims from different trusted issuers @@ -99,7 +99,7 @@ Because authentication is a complex topic, this IG tries to structure the soluti ##### Overview -The trust layer defines techniques and governance to establish trust between entities. Each entity needs an to be referenced by an identifier. +The trust layer defines techniques and governance to establish trust between entities. Each entity needs to be referenced by an identifier. In order to establish trust into an entity, a verifier must be able to verify the ownership of the identifier by the entity. Some identifiers are easier to verify than other. Identifiers that can be verified are called verifiable identifiers (VIDs). How a verifier can verify a VID depends on the type of identifier. Identifiers can either be externally verified by an authority (XVIDs), or self-certifying (SCIDs). Many identifiers we know are externally verified, such as your phone number or bank account. @@ -148,7 +148,7 @@ Identity claims contain information about the entity such as its name, role, and Identity claims can also be identifiers which can not be self-certified. These claims are usual managed by existing governance structures such as professional branches and governmental bodies. A chamber of commerce number is an result of such a governance structure. -The identity claims layer can be seen as the "Identification" part of the Generic Funtion "Identification & Authentication". +The identity claims layer can be seen as the "Identification" part of the Generic Function "Identification & Authentication". This layer describes the information in the specific claim such as its schema. The issuer or issuers that are authorized to issue the claim and the trust framework in which the claim can be used. It also describes the assurance levels and the lifecycle of the claim. @@ -167,7 +167,7 @@ The application layer defines requirements for specific use-cases in which authe To define the required identity claims, the [Digital Credential Query Language (DCQL)](https://identity.foundation/dcql/) can be used. This standard defines a way to express the required identity claims in a machine-readable way. The DCQL query can be used as a form of digital contract by the holder to gather the required claims from its wallet (or other sources) and by the verifier to verify the presented claims. -The DCQL language does not have to be implented directly by holders or verifiers, but can be used by specifications to define the required claims in a machine-readable way. +The DCQL language does not have to be implemented directly by holders or verifiers, but can be used by specifications to define the required claims in a machine-readable way. #### Summary of layers, technologies and standards From 7c47c9eb1883ac14d30317f5766f19f13222f091 Mon Sep 17 00:00:00 2001 From: Roland Groen Date: Fri, 10 Oct 2025 12:15:59 +0200 Subject: [PATCH 17/17] Correct grammar and spelling inconsistencies in authentication documentation; standardize "organization", align terminology, and improve readability. Use of American English like the other md files in this IG. --- input/pagecontent/authentication.md | 114 ++++++++++++++-------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/input/pagecontent/authentication.md b/input/pagecontent/authentication.md index 484f5f1..8b2d329 100644 --- a/input/pagecontent/authentication.md +++ b/input/pagecontent/authentication.md @@ -1,8 +1,8 @@ ### Introduction -Authentication is the process of verifying the identity of an entity. In the context of healthcare, authentication is used to verify the identity of healthcare professionals and care organisations. This is important to ensure that only authorized entities can access sensitive information and resources. +Authentication is the process of verifying the identity of an entity. In the context of healthcare, authentication is used to verify the identity of healthcare professionals and care organizations. This is important to ensure that only authorized entities can access sensitive information and resources. -The verified identity is often used downstream for authorization and accounting purposes. Authorization is the process of granting access to resources based on the identity of an entity. Accounting is the process of tracking the actions of an entity. +The verified identity is often used downstream for authorization and accounting. Authorization is the process of granting access to resources based on the identity of an entity. Accounting is the process of tracking the actions of an entity. #### Requirements @@ -10,12 +10,12 @@ There exists a multitude of authentication solutions, therefore it is important - Work with identity claims from the authoritative sources - Support combinations of identity claims from different trusted issuers -- Support for use-cases with and without a end-user (healthcare professional) -- Support for authorizing vendors to act on behalf of an (care) organisation -- Support for limiting the scope of an authorization of a vendor -- Support for authorizing (care) organisations to act on behalf of a healthcare professional +- Support for use-cases with and without an end-user (healthcare professional) +- Support for authorizing vendors to act on behalf of a (care) organization +- Support for limiting the scope of a vendor's authorization +- Support for authorizing (care) organizations to act on behalf of a healthcare professional - User-friendly solution for healthcare professionals -- Cost efficient solution for care organisations +- Cost-efficient solution for care organizations - Flexible solution that can be adapted to different use-cases - Peer-2-peer trust which allows direct interactions between the involved parties without involvement of a third party - No single point of failure @@ -27,10 +27,10 @@ There exists a multitude of authentication solutions, therefore it is important Throughout this document the following terminology is used: -- Entity: An actor in the system (person or organisation) +- Entity: An actor in the system (person or organization) - Agent: A digital representation of an entity that acts on its behalf, also often called an identity wallet -- Vendor: A party that offers Agents to its customers (care organisations and healthcare professionals) -- Identity: A set of claims about an entity (person or organisation) which is relevant in a specific context +- Vendor: A party that offers Agents to its customers (care organizations and healthcare professionals) +- Identity: A set of claims about an entity (person or organization) which is relevant in a specific context - Verifiable Identifier (VID): An identifier that can be (cryptographically) verified - Claim: A statement about an entity (e.g. name, role, affiliation) - Verifiable Claim: A claim that can be cryptographically verified @@ -44,23 +44,23 @@ Throughout this document the following terminology is used: #### Problem overview -A typical scenario in healthcare is that a healthcare professional needs to access a resource (e.g. patient data) which is located at a different organisation (e.g. a hospital). +A typical scenario in healthcare is that a healthcare professional needs to access a resource (e.g. patient data) which is located at a different organization (e.g. a hospital). In the Netherlands, the custodian of the patient data is by law forbidden to share the data with third parties. Several exceptions to that rule exists. One responsibility of the custodian is to ensure that the requesting party is authorized to access the data. In order to do so, the custodian needs to verify the identity of the requesting party. -In practice, many of these data exchanges are not done directly between the healthcare professionals, but between computers and systems. Often these systems are operated by vendors on behalf of the care organisations. +In practice, many of these data exchanges are not done directly between the healthcare professionals, but between computers and systems. Often vendors operate these systems on behalf of the care organizations. -On top of that, use-cases are often described and governed by a governing body. The governing body certifies healthcare organisations and vendors to operate in a specific use-case. The governing body defines the trust framework in which the use-case operates. The custodian also needs to verify that the entities operate within the trust framework of the use-case. +On top of that, use-cases are often described and governed by a governing body. The governing body certifies healthcare organizations and vendors to operate in a specific use-case. The governing body defines the trust framework in which the use-case operates. The custodian also needs to verify that the entities operate within the trust framework of the use-case. -The custodian needs to verify the identity of the requesting healthcare professional, working for an organisation which is a customer of a vendor. The custodian needs to verify the following: +The custodian needs to verify the identity of the requesting healthcare professional, working for an organization which is a customer of a vendor. The custodian needs to verify the following: -- The identity of the healthcare professional, identifier, role, and affiliation with the care organisation -- The identity of the care organisation, identifier, and its relationship with the healthcare professional -- The identity of the vendor, identifier, and its relationship with the care organisation +- The identity of the healthcare professional: identifier, role, and affiliation with the care organization +- The identity of the care organization: identifier and its relationship with the healthcare professional +- The identity of the vendor: identifier and its relationship with the care organization ### Solution overview The solution is based on exchanging verifiable identity claims between the involved parties. -The claims can be flexibly combined to form a complete identity for a specific use-case. +The claims can be flexible combined to form a complete identity for a specific use-case. The claims can be verified by the verifier without the need of a central authority, using cryptographic techniques. #### Actors and Transactions @@ -70,7 +70,7 @@ The claims can be verified by the verifier without the need of a central authori **Table 7.2-1: GF Authentication - Actors and Transactions** | Actor | Transaction | Initiator or Responder | Optionality | Reference | -| --------- | --------------------------------------- | ---------------------- | ----------- | --------------------------- | +|-----------|-----------------------------------------|------------------------|-------------|-----------------------------| | Verifier | Request key material [GFI-001] | Initiator | R | [\[GFI-001\]](GFI-001.html) | | | Request Revocation status [GFI-003] | Initiator | R | [\[GFI-003\]](GFI-003.html) | | | Request Access Token [GFI-004] | Responder | R | [\[GFI-004\]](GFI-004.html) | @@ -100,12 +100,12 @@ Because authentication is a complex topic, this IG tries to structure the soluti ##### Overview The trust layer defines techniques and governance to establish trust between entities. Each entity needs to be referenced by an identifier. -In order to establish trust into an entity, a verifier must be able to verify the ownership of the identifier by the entity. Some identifiers are easier to verify than other. Identifiers that can be verified are called verifiable identifiers (VIDs). +To establish trust into an entity, a verifier must be able to verify the ownership of the identifier by the entity. Some identifiers are easier to verify than others. Identifiers that can be verified are called verifiable identifiers (VIDs). How a verifier can verify a VID depends on the type of identifier. Identifiers can either be externally verified by an authority (XVIDs), or self-certifying (SCIDs). Many identifiers we know are externally verified, such as your phone number or bank account. -Self-certifying identifiers can be verified by a verifier without the need of a third party. An example category of a self-certifying identifiers are DIDs (Decentralized Identifiers). +Self-certifying identifiers can be verified by a verifier without the need of a third party. An example category of a self-certifying identifier is DIDs (Decentralized Identifiers). -Self-certifying identifiers are very useful in peer-to-peer scenarios, because they do not require a central authority to verify the identifier. This makes them suitable for use-cases where entities need to interact with each other without the need of a central authority. +Self-certifying identifiers are instrumental in peer-to-peer scenarios because they do not require a central authority to verify the identifier. This makes them suitable for use-cases where entities need to interact with each other without the need of a central authority. Once an entity has a verifiable identifier, it can use this identifier to link non-verifiable identifiers to its identity. This will be explained in the identity claims layer. @@ -123,7 +123,7 @@ Each entity needs a digital agent to act on its behalf. The digital agent is res This layer describes the protocols and data standards which can be used between the digital agents of the involved parties to acquire, present, and verify identity claims. -The identifier of the underlaying trust layer is not that useful by itself. But when it is combined with identity claims it becomes useful. Identity claims are statements about an entity that can be used to verify its identity in a specific context. By combining the SCID with identity claims, an entity can prove the ownership of the claims. +The identifier of the underlying trust layer is not that useful by itself. But when it is combined with identity claims, it becomes useful. Identity claims are statements about an entity that can be used to verify its identity in a specific context. By combining the SCID with identity claims, an entity can prove the ownership of the claims. ##### Choice of protocols and standards @@ -139,37 +139,37 @@ The protocol to request access tokens is based on [RFC 7523](https://www.rfc-edi In order to prevent token theft, the access token must be bound to the client. This can be done using [DPoP (Demonstrating Proof-of-Possession at the Application Layer)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop). DPoP is a mechanism to bind an access token to a private key, which is used to sign an additional DPoP access token which is uniquely created for each request to the resource server. -Verifiable credentials have a long lifetime, often several years. In order to be able to revoke a verifiable credential, a revocation mechanism is needed. The chosen revocation mechanism is [StatusList 2021](https://w3c-ccg.github.io/vc-status-list/), which defines a standard for revoking verifiable credentials using a bitstring. The verifier periodically retrieves (and caches) the statuslist and verifies the existence of the credential in the statuslist. +Verifiable credentials have a long lifetime, often several years. To be able to revoke a verifiable credential, a revocation mechanism is needed. The chosen revocation mechanism is [StatusList 2021](https://w3c-ccg.github.io/vc-status-list/), which defines a standard for revoking verifiable credentials using a bitstring. The verifier periodically retrieves (and caches) the status list and verifies the existence of the credential in the status list. #### Identity claims The identity claims layer defines the workings of specific identity claims. Identity claims contain information about the entity such as its name, role, and affiliation. -Identity claims can also be identifiers which can not be self-certified. -These claims are usual managed by existing governance structures such as professional branches and governmental bodies. A chamber of commerce number is an result of such a governance structure. +Identity claims can also be identifiers that cannot be self-certified. +These claims are usually managed by existing governance structures such as professional branches and governmental bodies. A chamber of commerce number is a result of such a governance structure. -The identity claims layer can be seen as the "Identification" part of the Generic Function "Identification & Authentication". +The identity claims layer can be seen as the "Identification" part of the Generic Function "Identification & Authentication." This layer describes the information in the specific claim such as its schema. The issuer or issuers that are authorized to issue the claim and the trust framework in which the claim can be used. It also describes the assurance levels and the lifecycle of the claim. -In order for use-case designers to choose from the available claims, a repository is needed that keeps track of the all available claims, their properties and governance bodies. +In order for use-case designers to choose from the available claims, a repository is needed that keeps track of all available claims, their properties, and governance bodies. This IG will not define specific claims. Eventually a national repository of available claims should be established which can be used in healthcare. -One of the challenges in architecture is crossing a gap between two technologies. Many existing identity claim technologies exist and are for example based on X.509 certificates or SAML assertions. These technologies are not directly compatible with the verifiable credentials technology. In order to bridge this gap, a mapping between the existing technologies and verifiable credentials is needed. +One of the challenges in architecture is crossing a gap between two technologies. Many existing identity claim technologies exist and are, for example, based on X.509 certificates or SAML assertions. These technologies are not directly compatible with the verifiable credentials technology. To bridge this gap, a mapping between the existing technologies and verifiable credentials is needed. -This layer can specify techniques to solve interoperability such as introducing custom proof types, introducing a trusted party which can map the information, or define custom verification methods. None of these solutions are ideal. Each solution has its own trade-offs. This layer can be used to specify building blocks to solve these interoperability challenges. +This layer can specify techniques to solve interoperability, such as introducing custom proof types, introducing a trusted party which can map the information, or define custom verification methods. None of these solutions are ideal. Each solution has its own trade-offs. This layer can be used to specify building blocks to solve these interoperability challenges. #### Application layer The application layer defines requirements for specific use-cases in which authentication and authorization are required. This includes the specific set of identity claims that are required to be presented, the trust framework in which the entities operate, and the protocols and mechanisms to establish a secure communication channel. It uses the lower layers of the stack to achieve this. -To define the required identity claims, the [Digital Credential Query Language (DCQL)](https://identity.foundation/dcql/) can be used. This standard defines a way to express the required identity claims in a machine-readable way. The DCQL query can be used as a form of digital contract by the holder to gather the required claims from its wallet (or other sources) and by the verifier to verify the presented claims. +To define the required identity claims, the [Digital Credential Query Language (DCQL)](https://identity.foundation/dcql/) can be used. This standard defines a way to express the required identity claims in a machine-readable way. The holder can use the DCQL query as a form of digital contract to gather the required claims from its wallet (or other sources) and by the verifier to verify the presented claims. The DCQL language does not have to be implemented directly by holders or verifiers, but can be used by specifications to define the required claims in a machine-readable way. -#### Summary of layers, technologies and standards +#### Summary of layers, technologies, and standards | Layer | Transaction | Technology / Standard | Description | | ------------------ | ----------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- | @@ -188,19 +188,19 @@ The DCQL language does not have to be implemented directly by holders or verifie Several identity claims are required to be presented. Which claims are required depends on the use-case. Each of the claims have different properties such as: -- Who can issue the claim -- How can the claim be verified -- What is the level of assurance of the claim -- Under which conditions can the claim be used +- Who can issue the claim? +- How can the claim be verified? +- What is the level of assurance of the claim? +- Under which conditions can the claim be used? - Lifecycle of the claim (expiration, revocation, renewal) -In order for use-case writers to define which claims are required, a repository is needed that keeps track of the claims and its properties. +In order for use-case writers to define which claims are required, a repository is needed that keeps track of the claims and their properties. #### Mechanics ### The actors -- Care organisation +- Care organization - Healthcare professional - Vendor - Verifier @@ -208,20 +208,20 @@ In order for use-case writers to define which claims are required, a repository #### Relations between the actors -Vendors get authorized by care organisations to act on their behalf. -The care organisation's identity can be represented by one of the trusted Vendors. +Vendors get authorized by care organizations to act on their behalf. +The care organization's identity can be represented by one of the trusted Vendors. ### Use-cases Different use-cases have different requirements for identity claims. -Each use-case requires its own governance in which it defines the needed identity claims and the trust framework in which the actors operate. +Each use-case requires its own governance in which it defines the necessary identity claims and the trust framework in which the actors operate. -The following steps are required to establish the identity of a healthcare organisation and professional in a specific use-case. +The following steps are required to establish the identity of a healthcare organization and professional in a specific use-case. -##### Setup for organisations +##### Setup for organizations -- Choose a identity wallet provider +- Choose an identity wallet provider - Acquire identity claims - Choose a vendor and authorize it to act on your behalf for a specific use-case - Issue relationship credentials to each healthcare professional @@ -230,8 +230,8 @@ The following steps are required to establish the identity of a healthcare organ - Choose a wallet - Acquire identity claims from DEZI and your branch organization -- Acquire relationship credentials from your care organisation -- authorize the organisation to act on your behalf for a limited amount of time (e.g. 1 day) +- Acquire relationship credentials from your care organization +- Authorize the organization to act on your behalf for a limited amount of time (e.g. 1 day) ##### Asserting identity @@ -246,21 +246,21 @@ In the context of a use-case, several identity claims are required to be present - Verify the verifiable presentation - Verify the nonce - - verify the signature - - verify the expiration date -- verify the claims + - Verify the signature + - Verify the expiration date +- Verify the claims - Verify the signatures - Verify the revocation status - - verify the issuer - - verify the expiration date + - Verify the issuer + - Verify the expiration date - Respond with a bearer token ##### Interacting with the resource server -- Present the bearer token to the resource server along side the request -- Check the DPoP proof (or other token binding mechanism) +- Present the bearer token to the resource server alongside the request +- Check the DPoP proof (or other token-binding mechanism) - The resource server verifies the bearer token by introspecting it at the oauth-authorization server -- The oauth-authorization server replies with the token status and the the provided identity claims +- The oauth-authorization server replies with the token status and the provided identity claims - The resource server verifies the token status - The resource server verifies the identity claims and the relationships @@ -268,12 +268,12 @@ In the context of a use-case, several identity claims are required to be present #### Token binding -#### No sharing of Private Keys of certificates +#### No sharing of private keys or certificates -#### use of TLS +#### Use of TLS Use of TLS for the vendor -#### replay attacks +#### Replay attacks nonce and timestamps