Add user authentication - #69
Conversation
|
Heads up that I've started my reviewing process. |
|
@stevenvegt A question: it seems that the role labeled as By folding the two roles of |
|
|
||
| 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. |
There was a problem hiding this comment.
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? |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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?" |
There was a problem hiding this comment.
"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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
bold claims, depends entirely on the network and IDP
| [ | ||
| { | ||
| "type": "openid_credential", | ||
| "credential_configuration_id": "UserIdentityCredential" |
|
|
||
| {: .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. |
There was a problem hiding this comment.
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
|
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 |
rolandgroen
left a comment
There was a problem hiding this comment.
Conceptual Concerns
- 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.
- 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?
- 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
- 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
- Missing Discovery Flow
OpenID4VCI defines a discovery flow that clients must follow:
- Client fetches Credential Issuer metadata from .well-known/openid-credential-issuer
- Client discovers which Authorization Server(s) to use via authorization_servers array
- Client fetches AS metadata from .well-known/oauth-authorization-server
- Client performs authorization at the AS
- Client requests credential from the Credential Issuer's credential endpoint
This discovery mechanism is not mentioned in the document.
- 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
- 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.
|
@rolandgroen thanks for you review. Lets first focus on your main concern: the folding of 2 concerns:
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:
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? |
|
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. |
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