Skip to content

Add user authentication - #69

Draft
stevenvegt wants to merge 4 commits into
mainfrom
user-authn
Draft

Add user authentication#69
stevenvegt wants to merge 4 commits into
mainfrom
user-authn

Conversation

@stevenvegt

@stevenvegt stevenvegt commented Jan 12, 2026

Copy link
Copy Markdown
Member

This PR adds a proposal for user authentication using trusted IDP's which can issue consent credentials which can be used in the GFI-004 transaction with other VCs in a VP.

Build: https://build.fhir.org/ig/nuts-foundation/nl-generic-functions-ig/branches/user-authn/user-authentication.html

@rolandgroen

Copy link
Copy Markdown
Contributor

Heads up that I've started my reviewing process.

@rolandgroen

Copy link
Copy Markdown
Contributor

@stevenvegt A question: it seems that the role labeled as IdP plays the role of Credential Issuer in the OID4VCI framework. Why is this role attributed to the IdP? Does this mean that IdP's in GFs need to be enhanced with OID4VCI functionality?

By folding the two roles of Authorization Server and Credential Issuer of the OID4VCI framework into the IdP, the IdP needs to ask for consent something like: "Do you want to authorize [Credential Subject] to act on your behalf". It makes a lot more sense to separate the roles and have a combo of the two [DigID + nuts-knoopunt] or [DigID + DEZI] as Authorization Server and Credential Issuer into this framework.


User authentication establishes the identity of an end-user (typically a healthcare professional) in cross-organizational data exchanges. While the [Authentication](authentication.html) section describes how organizations and service providers authenticate using Verifiable Credentials, this section extends that model to include authenticated end-users.

The result of user authentication is a **User Consent Credential** - a short-lived Verifiable Credential issued by a trusted Identity Provider (IDP) that attests that an authenticated user has authorized their organization to act on their behalf. This credential can be included in the Verifiable Presentation sent to an Authorization Server as part of the [Request Access Token \[GFI-004\]](GFI-004.html) transaction.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "user authentication" in itself is not the consent credential but whatever authenticated the user (Dezi). So I think we need another/more describing term for this

Healthcare professionals need to access patient data across organizational boundaries. The receiving organization's Authorization Server must verify:

1. **Organization identity** - Which care organization is requesting access?
2. **User identity** - Which healthcare professional is initiating the request?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether we're limiting ourselves here to person-must-be-requesting-it scenarios. E.g. an asynchronous message-based API Gateway that fetches eOverdracht resources after a doctor/nurse accepted the transfer.

I think, "liveness" could be a level (according to NIST *AL's); separation between, request is on behalf of the user, request was initiated by the user, ...

- Users should not authenticate for every access token request (user experience)
- Users may work for multiple healthcare organizations
- Users may have different roles at different organizations
- User authentication must prove "liveness" - that the user is actively present

@reinkrul reinkrul Jan 16, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or should there be enough assertion that it was the user that triggered/intiated the request (onder verantwoordelijkheid van)? Since not every use case might be a case of "fetch the data and show it to the user".


The user authentication solution must:

- **Integrate with the existing VC/VP model** - User identity is expressed as a Verifiable Credential that can be combined with other credentials in a Verifiable Presentation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can drop "existing"


#### Consent Model

When a user at Organization A accesses resources at Organization B, the fundamental question is: "Is Organization A authorized to act on behalf of this user?"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"act on behalf of" is a different assurance level from "user is at the keyboard"

{% include user-authentication.svg %}
</div>

**Note**: Steps 10-12 (the authorization redirect for credential issuance) are near-instant if the user has a valid browser session with the IDP and has previously consented. The user may only see a brief loading indicator.

@reinkrul reinkrul Jan 16, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user gave consent once, theoretically we could use the refresh-credential API with the id_token as grant? (just calling /token)

Since a recent id_token would prove liveness?


User authentication establishes the identity of an end-user (typically a healthcare professional) in cross-organizational data exchanges. While the [Authentication](authentication.html) section describes how organizations and service providers authenticate using Verifiable Credentials, this section extends that model to include authenticated end-users.

The result of user authentication is a **User Consent Credential** - a short-lived Verifiable Credential issued by a trusted Identity Provider (IDP) that attests that an authenticated user has authorized their organization to act on their behalf. This credential can be included in the Verifiable Presentation sent to an Authorization Server as part of the [Request Access Token \[GFI-004\]](GFI-004.html) transaction.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aren't we missing a UserIdentityCredential, containing the wrapped id_token?


The Authorization Code Flow is used for credential issuance because it:

- **Guarantees user liveness** - The browser redirect proves the user is present at the time of credential issuance.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MITM on the vendor side could still steal the session cookie, so there's some guarantees, but it's not 100%

- **Guarantees user liveness** - The browser redirect proves the user is present at the time of credential issuance.
- **Enables explicit consent** - The IDP can display what identity information will be shared and with whom.
- **Is near-instant with active session** - If the user has a valid browser session with the IDP, the redirects happen in milliseconds. The user may only see a brief loading state.
- **Uses standard protocols** - Built on OAuth 2.0 and OpenID4VCI, widely supported.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd not call OpenID4VCI widely supported

{% include openid4vci-consent-issuance.svg %}
</div>

With an active session and pre-approved consent, steps 2-5 complete in milliseconds.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bold claims, depends entirely on the network and IDP

[
{
"type": "openid_credential",
"credential_configuration_id": "UserIdentityCredential"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consent?


{: .grid .table-striped}

The `prompt=none` option (silent authentication) is not appropriate for consent credentials, as the user should be aware when authorizing their organization to act on their behalf.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

none could be honoured if consent session is still valid, the IDP is free to either ask for login or consent again. prompt is only a request from the client which doesn't need to be honoured

@reinkrul

Copy link
Copy Markdown
Member

In fact, if we're going to use OpenID4VCI anyways, shouldn't result user authentication in a CareProfessionalCredential (or something) anyway instead of a Dezi id_token?

@rolandgroen rolandgroen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conceptual Concerns

  1. IdP Role Confusion

An Identity Provider's role is to provision and attest to identity, not to capture consent for delegation. The document requires the IdP to ask the user "Do you want to authorize [Organization] to act on
your behalf?" - this is an authorization decision, not identity provisioning.

This conflates two distinct concerns:

  • Identity: "Who is this user?" (IdP's role)
  • Delegation consent: "Does the user authorize this organization to act on their behalf?" (not the IdP's role)

The entity capturing delegation consent should arguably be separate from the identity provider, or this role expansion should be explicitly justified.

  1. Future Compatibility with NL-Wallet / EUDI Wallet

The document doesn't address how this proposal fits with the future where end-users will have a government-provisioned digital wallet (NL-Wallet / EUDI Wallet). In that model:

  • Users hold their own identity credentials in their personal wallet
  • Users can present credentials directly or delegate through their wallet
  • The wallet itself could capture consent for delegation

How will this proposal evolve or integrate when users have their own wallets? Should this be designed with that transition in mind?

  1. Privacy Contradiction

The document contains contradictory statements about consent scope:

  • Privacy section states: "Consent should be specific to the intended recipient"
  • Consent Scope section argues for "broad delegation" without audience restriction

These positions should be reconciled or the intended trade-off clarified.

OpenID4VCI Compliance

  1. Missing Authorization Server / Credential Issuer Separation

OpenID4VCI clearly distinguishes two roles:
┌──────────────────────┬───────────────────────────────────────────────┬────────────────────────────────────────┐
│ Component │ Responsibility │ Metadata │
├──────────────────────┼───────────────────────────────────────────────┼────────────────────────────────────────┤
│ Authorization Server │ OAuth 2.0 authorization, issues access tokens │ .well-known/oauth-authorization-server │
├──────────────────────┼───────────────────────────────────────────────┼────────────────────────────────────────┤
│ Credential Issuer │ Issues Verifiable Credentials │ .well-known/openid-credential-issuer │
└──────────────────────┴───────────────────────────────────────────────┴────────────────────────────────────────┘
The document conflates these into a single "IDP" without:

  • Credential Issuer metadata (.well-known/openid-credential-issuer)
  • The authorization_servers reference linking Credential Issuer to AS
  • Any mention of the discovery mechanism
  1. Missing Discovery Flow

OpenID4VCI defines a discovery flow that clients must follow:

  1. Client fetches Credential Issuer metadata from .well-known/openid-credential-issuer
  2. Client discovers which Authorization Server(s) to use via authorization_servers array
  3. Client fetches AS metadata from .well-known/oauth-authorization-server
  4. Client performs authorization at the AS
  5. Client requests credential from the Credential Issuer's credential endpoint

This discovery mechanism is not mentioned in the document.

  1. Missing c_nonce Flow

OpenID4VCI typically requires:

  • Token response includes a c_nonce (credential nonce)
  • Proof JWT in credential request must include this nonce claim

The document's proof JWT example has no nonce claim, and the token response doesn't show c_nonce. This should either be included or the deviation from the spec should be justified.

Document Issues

  1. Naming Inconsistency

The credential is called "UserConsentCredential" throughout the document, but in the authorization_details examples it uses credential_configuration_id: "UserIdentityCredential". These should be
consistent.

@stevenvegt

Copy link
Copy Markdown
Member Author

@rolandgroen thanks for you review. Lets first focus on your main concern: the folding of 2 concerns:

  • Identity: "Who is this user?" (IdP's role)
  • Delegation consent: "Does the user authorize this organization to act on their behalf?" (not the IdP's role)

I agree with you on this, they are 2 different concerns and the second one is not strictly taken the task of the IdP. But the question remains, who's role it is?

I've deliberately wrote the IG implementation independent. But it might help us to plot this on the most obvious use-case: Dezi.

In this situation Dezi is the authentic source of the Dezi-identifier (the Dutch identity for health care workers) and also the relationship between healthcare organizations and the healthcare worker.

DigID (or other services) will take the role of IdP.

What is now left to delegate is the task to register consent. It would make sense to attribute this to Dezi as well. We need some trusted party for this, so the care provider itself could have that role.

For the IG we can split the responsibility into the following explicit roles:

  • Authentic source for the Dezi identity and relationship with the care provider
  • Authentic source for (registering) consent of health care workers to share their identity information and act in their behalf
  • IdP for authenticating with Dezi and the consent-registration.

We need to come up with a generic name for Dezi, something like Healthcare Identity registry (a trusted party to assert a national healthcare identity).

Would this address your concerns?

@stevenvegt
stevenvegt marked this pull request as draft July 17, 2026 08:01
@stevenvegt

Copy link
Copy Markdown
Member Author

Since the GF POCs are now completed, this subject has a lower priority. Set it back to draft status. Lets see if and how we can use this when there is more energy on the subject.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants