First draft of OpenId4VCI-S2S#753
Conversation
This is the first draft of the s2s variant of credential issuance. In an early state, and still needs a lot of polish. Before this is ready to review there needs to be: - Flow Diagrams - Example flows for Credential Lifecycle Notable missing features: - Atomic Credential Sets - Specified VerificationData for common uses - Reverification - Schemas Additionally, before the first implementors draft a convergence effort with existing VCI needs to be undertaken including: - Credential Offer - IAE - Credential Endpoint - Notifications - Encryption - Issuer and Credential Metadata
|
|
||
| .# Abstract | ||
|
|
||
| This specification defines an API for the issuance and management of Verifiable Digital Credentials between a Wallet Server and Issuer Server, while enabling sensitive user data to remain confidential between a Wallet Client Instance and the Issuer. |
There was a problem hiding this comment.
| This specification defines an API for the issuance and management of Verifiable Digital Credentials between a Wallet Server and Issuer Server, while enabling sensitive user data to remain confidential between a Wallet Client Instance and the Issuer. | |
| This specification defines an API for the issuance and management of Verifiable Credentials between a Wallet Server and Issuer Server, while keeping sensitive user data confidential between a Wallet Client Instance and the Issuer without revealing it to the Wallet Server. |
There was a problem hiding this comment.
do we want to change terminology to Verifiable Digital Credentials..?
| This specification defines the contract between a Wallet Server and one or more | ||
| Credential Issuer Servers for credential issuance and lifecycle management. It | ||
| is credential format agnostic so Credentials can be of any format, including, | ||
| but not limited to, IETF SD-JWT VC [@I-D.ietf-oauth-sd-jwt-vc], ISO mdoc | ||
| [@ISO.18013-5], and W3C VCDM [@VC_DATA_2.0]. |
There was a problem hiding this comment.
| This specification defines the contract between a Wallet Server and one or more | |
| Credential Issuer Servers for credential issuance and lifecycle management. It | |
| is credential format agnostic so Credentials can be of any format, including, | |
| but not limited to, IETF SD-JWT VC [@I-D.ietf-oauth-sd-jwt-vc], ISO mdoc | |
| [@ISO.18013-5], and W3C VCDM [@VC_DATA_2.0]. | |
| This specification defines a set of APIs used by the Wallet Server | |
| for credential issuance and lifecycle management. It | |
| is credential format agnostic. Credentials can be of any format, including, | |
| but not limited to, IETF SD-JWT VC [@I-D.ietf-oauth-sd-jwt-vc], ISO mdoc | |
| [@ISO.18013-5], and W3C VCDM [@VC_DATA_2.0]. |
There was a problem hiding this comment.
"contract" did not feel descriptive enough
There was a problem hiding this comment.
"protocol"? It's really a sequence of API calls, no?
There was a problem hiding this comment.
Actually, it's probably both: "a set of APIs and a protocol".
| Credential (or Verifiable Digital Credential (VDC)): | ||
| : An instance of a Credential Configuration with a particular Credential Dataset, that is signed by an Issuer and can be cryptographically verified. An Issuer may provide multiple Credentials as separate instances of the same Credential Configuration and Credential Dataset but with different cryptographic values. In this specification, the term "Verifiable Digital Credential" is also referred to as "Credential". |
There was a problem hiding this comment.
why redefine what is already defined in VCI..? because calling it a VDC is very important?
| CredentialInstanceId: | ||
| : A unique identifier at an Issuer for a particular Credential Dataset on a particular Wallet Client Instance. |
There was a problem hiding this comment.
this looks like a parameter name... I'd suggest either define "Credential Instance Identifier" or remove CredentialInstanceId from terminology.
| VerificationId: | ||
| : An identifier generated by the Issuer for a particular verification session. Must be unique for a given SessionId. |
There was a problem hiding this comment.
same comment as for CredentialInstanceId. looks like a parameter name... I'd suggest either define "verification Identifier" or remove it from terminology.
| Verification: | ||
| : Verification in this specification refers to the process by which an Issuer determines that a Wallet Client Instance is authorized to have particular Credentials issued to it. |
There was a problem hiding this comment.
Verification is way too generic as a term to be defined. either be more specific "Wallet Client Instance Verification", but i'd rather not define this as a term
There was a problem hiding this comment.
We really need some term to cover the first phase where the WSK is established and the Issuer determines the eligibility of Issuance of the Credentials. Due to the broad range of types of credentials that can be issued, it's naturally a pretty inclusive step.
Other names that have come up in small group discussion:
- User Authentication
- Enrollment
- Proofing
This is functionally the same as what occurs in IAE. I guess we could call it 'Interactive Authorization' but that is also an awful name IMO so.
Leaving comment open to have naming debate in call today, be good to start with a name that people are somewhat in agreement with, even if we can change later.
There was a problem hiding this comment.
Note from group: kinda has to be something generic. Some preference for 'Enrollment'. Will open an issue to track name choice and leave as is for now.
| SessionId: | ||
| : A globally unique identifier associated with a particular Wallet Client Instance, persistent throughout the issuance process. |
There was a problem hiding this comment.
same comment as for CredentialInstanceId. looks like a parameter name... I'd suggest either define "Session Identifier", which is way too obvious to be defined IMHO or remove it from terminology.
There was a problem hiding this comment.
This reads a bit dangerous
| SessionId: | |
| : A globally unique identifier associated with a particular Wallet Client Instance, persistent throughout the issuance process. | |
| SessionId: | |
| : A globally unique identifier associated with a particular Issuance process between a Wallet Client Instance and an Issuer, persistent throughout the issuance process. |
|
|
||
| At a high level the protocol works in two phases; Verification and Credential Management. | ||
|
|
||
| Verification is as follows: |
There was a problem hiding this comment.
| Verification is as follows: | |
| Issuer verifies Wallet Client Instance in the following steps: |
| Verification is as follows: | ||
|
|
||
| - The Wallet Server and Issuer Server mutually authenticate with each other using mTLS, prior to any endpoint interaction. | ||
| - As part of initiating verification of the Wallet Client Instance, the Wallet Client establishes an attested public key (WSK) which is used to authenticate payloads originating on Wallet Client. |
There was a problem hiding this comment.
| - As part of initiating verification of the Wallet Client Instance, the Wallet Client establishes an attested public key (WSK) which is used to authenticate payloads originating on Wallet Client. | |
| - As part of initiating verification of the Wallet Client Instance, the Wallet Client establishes an attested public key (WSK) which is later used to authenticate payloads originating on Wallet Client. |
| - As part of initiating verification of the Wallet Client Instance, the Wallet Client establishes an attested public key (WSK) which is used to authenticate payloads originating on Wallet Client. | ||
| - VerificationData is collected on the Wallet Client and encrypted to the Issuer Server to demonstrate the | ||
| - The Wallet Server MAY also contribute additional VerificationData | ||
| - This process is potentially asynchronous, while the Issuer evaluates the outcome. |
There was a problem hiding this comment.
either mark this as a to-do, or be more assertive
| - This process is potentially asynchronous, while the Issuer evaluates the outcome. | |
| - This process is can be asynchronous, while the Issuer evaluates the outcome. |
| - The Wallet Server MAY also contribute additional VerificationData | ||
| - This process is potentially asynchronous, while the Issuer evaluates the outcome. | ||
|
|
||
| After the Wallet Client Instance has been authenticated and is determined as authorized to have the particular Credential Instance. This works as follows: |
There was a problem hiding this comment.
| After the Wallet Client Instance has been authenticated and is determined as authorized to have the particular Credential Instance. This works as follows: | |
| After the Wallet Client Instance has been authenticated and is authorized to have the particular Credential Instance. This works as follows: |
|
|
||
| After the Wallet Client Instance has been authenticated and is determined as authorized to have the particular Credential Instance. This works as follows: | ||
|
|
||
| - The authorized CredentialInstanceIds per Credential DataSet are retrieved from the Provision Credential endpoint. Each Credential Instance MAY be managed independently. |
There was a problem hiding this comment.
I'd rather we define all endpoints upfront before using them in the sentence
There was a problem hiding this comment.
also, should be Credential Provisioning Endpoint to be more descriptive
for strictly unchanged definitions.
re-written the original overview to be more of a high level description of the flow.
| This is done as follows: | ||
|
|
||
| 1. The Wallet Client Instance generates a WSK, and the Wallet Server initiates the Verification on the Issuer Server. | ||
| 1. The Wallet provides a stable unique Session Id associated with the WSK and the Issuer provides a stable Verification Id to reference this session. |
There was a problem hiding this comment.
should this be "Wallet Client Instance"?
There was a problem hiding this comment.
Could be, or could be the Wallet Server that generates it and provides it to the Wallet Client. It's just a UUID, so doesn't really matter.
|
|
||
| On successful completion the Issuer Server now has a WSK that can be used to authenticate payloads as originating on a particular Wallet Client Instance, and have established which Credentials can be issued. | ||
|
|
||
| The Wallet retrieves the credentials as follows: |
There was a problem hiding this comment.
what's the purpose of this phase?
|
|
||
| In advance of any communication, the Wallet Server and Issuer Server authenticate via mTLS, which is used at all endpoints. The Wallet Server is responsible for authenticating the Wallet Client and ensuring it is in a good state before communicating with the Issuer Server. | ||
|
|
||
| Issuance begins with a Verification phase. This phase serves two purposes: |
There was a problem hiding this comment.
is there issuer metadata retrieval step? How does the issuer know which credential wallet instance is asking for to know which verification data is needed?
| The Wallet retrieves the credentials as follows: | ||
|
|
||
| 1. The Wallet Server retrieves the Credential Instance Identifiers from the Wallet Server using the Session Id and Verification Id. | ||
| 1. The Wallet Client generates proofs for Presentation Keys and signs-then-encrypts them using the WSK. The Wallet Client also creates an encryption key and signs it with the WSK. |
There was a problem hiding this comment.
signs-then-encrypts them using the WSK. The Wallet Client also creates an encryption key and signs it with the WSK.
WSK is used for signing and encryption? but then another encryption key is generated?
| | Verification Initiate | /verification/initiate | Issuer | Starts the verification process for a Wallet Client Instance for a particular set of credential configurations. | | ||
| | Verification Supplement | /verification/supplement | Issuer | Provides additional verification data for an ongoing verification session. | |
There was a problem hiding this comment.
why can't this be the same endpoint like with IAE?
There was a problem hiding this comment.
It could be. The design trade-offs are:
- There is a (non-zero) stand-up cost for endpoints
- polymorphic endpoints can be harder to reason about
- separating endpoints can make analytics and monitoring easier when you have distinct expected behavior for each endpoint.
I (personally) think having non-polymorphic endpoints is better. It is harder/impossible for IAE to split their endpoint (because it is attempting to build on oauth, which has a single endpoint as you are meant to only call it once with the same payload), so at least (IMO) IAE is making a necessary compromise.
As part of harmonizing with canonical VCI we could consider merging endpoints for consistence, but there are likely to be sufficient other differences that we may be better merging messages on level down (this is why the VerificationDataRequest/Response Schemas exist).
Leaving topic open for further discussion
| | Provision Credentials | /credential/provision | Issuer | Fetches credential instance IDs after verification approval. | | ||
| | Get Credential | /credential/get | Issuer | Retrieves the verifiable credentials for a particular credential instance. | |
There was a problem hiding this comment.
what's the difference of these two endpoints?
There was a problem hiding this comment.
provision returns what data sets (as identifier) the Wallet Client Instance can have issued. Get returns the particular VDC instances for a given credential data set instance.
| | Get Verification Status | /verification/status | Issuer | Queries the current status of a verification session. | | ||
| | Verification Notification | /verification/notify | Wallet | Allows the Issuer to notify the Wallet of a verification status change. | | ||
| | Verification Cancellation | /verification/cancel | Issuer | Cancels an ongoing verification session. | |
There was a problem hiding this comment.
why can't this be one endpoint implemented by Both like Credential management endpoint? like Verification management endpoint or something?
There was a problem hiding this comment.
It's not bi-directional because the Issuer can't tell the Wallet server to cancel an in-progress verification, it just tell the Wallet about the result.
The Cancel step is mostly there for clean-up purposes.
In the Credential Lifecycle case, we want to be able to initiate the state changes from both sides and still continue the management of the credential which is a good reason for it to have the bi-directional.
At the end of the day they are all kinda notifications, so we could just make notify bi-directional, but we currently don't have enough different types to justify that. Worth thinking about though.
|
|
||
| ### KeyData | ||
|
|
||
| All keys are communicated between the Wallet and Issuer using this common key structure. |
There was a problem hiding this comment.
is this JWK..? Field where?
There was a problem hiding this comment.
to be consistent with already defined client_public_key, keyType should probably be key_type.
attestations is very generic, key_attestation is what is meant?
| - Via a back-channel call from the Issuer Server to the Wallet Server | ||
| - Though this is currently out of scope of this specification |
There was a problem hiding this comment.
Good question: we could put it in scope. I left it as out of scope as it is out of scope of canonical VCI, but I guess we do have a channel...
dpostnikov
left a comment
There was a problem hiding this comment.
Some preliminary thoughts, questions, and editorial tweaks.
| 1. The Wallet Client Instance generates a WSK, and the Wallet Server initiates the Verification on the Issuer Server. | ||
| 1. The Wallet provides a stable unique Session Id associated with the WSK and the Issuer provides a stable Verification Id to reference this session. | ||
| 1. The Wallet Client Instance collects Verification Data and signs-then-encrypts it using the WSK and the Issuer Encryption Key. | ||
| 1. Examples include digital credential presentations, auth on web, wallet collected documents and liveness/selfie checks. |
There was a problem hiding this comment.
| 1. Examples include digital credential presentations, auth on web, wallet collected documents and liveness/selfie checks. | |
| 1. Examples include digital credential presentations, authentication on web, wallet-collected documents and liveness/selfie checks. |
There was a problem hiding this comment.
'Auth on web' is coming from VCI/IAE, it's referring to a flow where you redirect to an issuer website, perform to the auth and then redirect back.
Issue #757 is tracking defining our set of verification types, which we should also likely unify with IAE.
| This specification defines the contract between a Wallet Server and one or more | ||
| Credential Issuer Servers for credential issuance and lifecycle management. It | ||
| is credential format agnostic so Credentials can be of any format, including, | ||
| but not limited to, IETF SD-JWT VC [@I-D.ietf-oauth-sd-jwt-vc], ISO mdoc | ||
| [@ISO.18013-5], and W3C VCDM [@VC_DATA_2.0]. |
There was a problem hiding this comment.
Actually, it's probably both: "a set of APIs and a protocol".
| | SUSPENDED_ISSUER | Suspended by the credential issuer | | ||
| | SUSPENDED_WALLET | Suspended by the wallet operator | | ||
| | UNLINKED | Credential removed from device | | ||
| | IN_PROCESS | Provisioning or lifecycle operation in progress | |
There was a problem hiding this comment.
What does it mean? Cannot be used?
INACTIVE, INACTIVE_IN_PROGRESS, or PENDING?
There was a problem hiding this comment.
A state change is occurring, so currently unknown (basically a try-again-later). It should only be relevant for particular complex credential sets.
| | UNLINKED | Credential removed from device | | ||
| | IN_PROCESS | Provisioning or lifecycle operation in progress | | ||
| | CANCELLED | Credential permanently invalidated | | ||
| | UNKNOWN | Status cannot be determined | |
There was a problem hiding this comment.
Can it not find a credential? 404?
Or is it that the Wallet Client hasn't been live or synced for X period of time?
Or?
| |-----------------------------|---------------|-------------------------------------------------| | ||
| | PROVISIONING_SUCCESS | Wallet Server | Credential successfully provisioned to device | | ||
| | PROVISIONING_FAILURE | Wallet Server | Credential provisioning failed | | ||
| | LIFECYCLE_SUCCESS | Wallet Server | Lifecycle action completed | |
There was a problem hiding this comment.
how different is it from the events below?
| | eventDetails | object | **TYPE DEPENDENT**: Implementation-specific details dependent on the eventType. | | ||
| | extensions | object | **OPTIONAL**: Implementation-specific extension fields. | | ||
|
|
||
| ### Event Types |
There was a problem hiding this comment.
INACTIVE or PENDING... Maybe there is another spec we can refer to...
Can draw something like this in ASCII, of course.
There was a problem hiding this comment.
Created #772 to track this. In practice when I've drawn these in the past they often end up every state able to transition to every other state and so are a bit infeasible (and so a representative example of primary flows is more useful).
|
|
||
| This specification makes use of a Wallet Signing Key to authenticate payloads originating from the Wallet Client. As part of Verification, the Wallet Signing Key signs-and-encrypts Verification Data, demonstrating to the Issuer that the Verification Data was collected in the presence of the Wallet Signing Key. How strongly that Data types the Wallet Signing Key depends on the specifics of the issuance process and is outside the scope of this specification. | ||
|
|
||
| # Privacy Considerations {#privacy-considerations} |
There was a problem hiding this comment.
| # Privacy Considerations {#privacy-considerations} | |
| ## Pre-authorization Code security measures {#preauth-security} | |
| It is important to note that anyone with a valid Pre-Authorized Code, without additional security measures, can receive a Credential from the Credential Issuer. Implementers MUST implement the mitigations most suitable to the use case. | |
| # Privacy Considerations {#privacy-considerations} |
Co-authored-by: Dima Postnikov <dima@postnikov.net>
Co-authored-by: Kristina <52878547+Sakurann@users.noreply.github.com>
Co-authored-by: Kristina <52878547+Sakurann@users.noreply.github.com>
Co-authored-by: Kristina <52878547+Sakurann@users.noreply.github.com>
Co-authored-by: Kristina <52878547+Sakurann@users.noreply.github.com>
Co-authored-by: Kristina <52878547+Sakurann@users.noreply.github.com>
Co-authored-by: Dima Postnikov <dima@postnikov.net>
Co-authored-by: Dima Postnikov <dima@postnikov.net>
Co-authored-by: Dima Postnikov <dima@postnikov.net>
|
|
||
| - An Issuer Server operated by the Issuer | ||
| - A Wallet Server operated by the Wallet Provider | ||
| - A Wallet Client provided by the Wallet Provider and under the control of the |
There was a problem hiding this comment.
Update this to be less normative of what it is, but be precise about capabilities and the mental model.
|
|
||
| ### Error Types | ||
|
|
||
| This specification defines the following error types: |
There was a problem hiding this comment.
why do error types need to be URNs..?
|
|
||
| ## Content Reference {#content-reference} | ||
|
|
||
| This section details how large content can be passed by-reference to a downloadable URL, rather than in-band. |
There was a problem hiding this comment.
| This section details how large content can be passed by-reference to a downloadable URL, rather than in-band. | |
| This section details how large content can be passed by reference to a downloadable URL, rather than by value. |
by reference vs by value are the terms usually used i think
|
|
||
| ## Content Reference {#content-reference} | ||
|
|
||
| This section details how large content can be passed by-reference to a downloadable URL, rather than in-band. |
There was a problem hiding this comment.
also, content of what? fields below are fields of what? please define clearly
| SessionId: | ||
| : A globally unique identifier associated with a particular Wallet Client Instance, persistent throughout the issuance process. |
There was a problem hiding this comment.
This reads a bit dangerous
| SessionId: | |
| : A globally unique identifier associated with a particular Wallet Client Instance, persistent throughout the issuance process. | |
| SessionId: | |
| : A globally unique identifier associated with a particular Issuance process between a Wallet Client Instance and an Issuer, persistent throughout the issuance process. |
|
|
||
| #### Replay Protection | ||
|
|
||
| This endpoint is protected against replay attacks through a signed nonce mechanism. The wallet produces a digital signature over the sessionId using the walletSigningKey and includes this signature as the verificationNonce field in the request. |
There was a problem hiding this comment.
I might be wrong, but given the current definitions, how are we guaranteeing freshness / preventing replay - I don't see an issuer provided input currently (since sessionID is potentially long-lasting)?
|
|
||
| ## Server Authentication {#server-authentication} | ||
|
|
||
| All endpoints MUST use mutual TLS (mTLS) as the authentication method between the Wallet and Issuer Servers, as described by [@!RFC8705]. Both servers present X.509 client certificates during the TLS handshake. Certificate management is outside of scope of this specification. |
There was a problem hiding this comment.
We probably want to bind between SessionId and `server authentication?
| All endpoints MUST use mutual TLS (mTLS) as the authentication method between the Wallet and Issuer Servers, as described by [@!RFC8705]. Both servers present X.509 client certificates during the TLS handshake. Certificate management is outside of scope of this specification. | |
| All endpoints MUST use mutual TLS (mTLS) as the authentication method between the Wallet and Issuer Servers, as described by [@!RFC8705]. Both servers present X.509 client certificates during the TLS handshake. Certificate management is outside of scope of this specification. | |
| Issuers MUST associate a SessionId with the mTLS client identity that created it and reject requests for that SessionId from any other identity. |

This is the first draft of the s2s variant of credential issuance.
In an early state, and still needs a lot of polish, creating poll request to allow visibility given the size and for S2S WG discussion.
Before this is ready to review there needs to be:
Notable missing features:
Additionally, before the first implementors draft a convergence effort with existing VCI needs to be undertaken including: