oid4vcis2s September 2026
Oliver Standards Track [Page]
Workgroup:
OpenID Digital Credentials Protocols
Published:
Author:
G. Oliver
Google

OpenID for Verifiable Credential Issuance: Server to Server - Editor's draft

Abstract

This specification defines an API for the issuance and management of Verifiable Digital Credentials between a Wallet Server and Issuer Server, while keeping sensitive user data confidential between a Wallet Client Instance and the Issuer (i.e., not revealing it to the Wallet Server).

Table of Contents

1. Introduction

This specification defines a set of APIs and a protocol for credential issuance and lifecycle management. It is credential format agnostic so Credentials can be of any format. 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].

It is intended to be used to allow a Wallet to provide server infrastructure to facilitate improved reliability and security of credential issuance and lifecycle management, while adhering to principles of data minimization and user privacy.

The communication between the Wallet Server and the Wallet Client is out of scope of this specification.

2. Requirements Notation and Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

3. Terminology

This specification uses the terms "Credential", "Credential Configuration", "Credential Dataset", "Credential Format", "Holder", "Presentation", "Verifiable Credential" and "Verifiable Presentation" as defined in OpenID4VCI.

This specification defines the following terms. In the case where a term has a definition that differs, the definition below is authoritative for this specification.

Credential Issuer (or Issuer):
An entity that issues Verifiable Credentials. In the context of this specification, the Credential Issuer implements the Issuer Endpoints.
Credential Instance Identifier:
A unique identifier at an Issuer for a particular Credential Dataset on a particular Wallet Client Instance.
Issuer Server:
The server component used by an Issuer to implement the Issuer Endpoints as defined in this specification. It performs the verification, issuance and lifecycle management of credentials.
SessionId:
A globally unique identifier associated with a particular Issuance process between a Wallet Client Instance and an Issuer, persistent throughout the issuance process.
Verifiable Digital Credential (VDC):
Synonymous with Credential or Verifiable Credential.
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.
VerificationId:
An identifier generated by the Issuer for a particular verification session. Must be unique for a given SessionId.
Wallet:
An entity used by the Holder to request, receive, store, present, and manage Verifiable Digital Credentials and cryptographic key material. In the context of this specification it is split into two components: the Wallet Client and a Wallet Server.
Wallet Client:
A client application, that is under the control of the Holder, that Credentials will be installed on.
Wallet Client Instance:
A specific instance of a Wallet Client.
Wallet Encryption Key (WEK):
A key type provided by a Wallet Client Instance for the Issuer to encrypt sensitive data to.
Wallet Provider:
The entity who provides the technical solutions for the Wallet Client and the Wallet Server.
Wallet Server:
A server component that provides infrastructure to facilitate improved reliability and security of credential issuance and lifecycle management. In the context of this specification it is responsible for implementing the Wallet Server Endpoints, and communicating with the Wallet Client.
Wallet Signing Key (WSK):
An asymmetric key pair generated by a Wallet Client Instance used as a proof-of-origin for payload generated on the client for the Issuer.

4. Overview

This specification defines endpoints on both the Wallet Server and Credential Issuer Server to perform credential issuance and lifecycle management. This specification is designed for use with an architecture involving 3 components:

      +-------------------------------------------+
      |                  Wallet                   |
      |                                           |            +---------------+
      |  +-------------+         +-------------+  |            |     Issuer    |
      |  |             |         |             |  |            |               |
      |  |   Wallet    |         |   Wallet    |  |            | +-----------+ |
      |  |   Client    |<------->|   Server    |<--------------->|  Issuer   | |
      |  |             |  Out of |             |  | OpenID4VCI | |  Server   | |
      |  +-------------+  Scope  +-------------+  |  S2S API   | +-----------+ |
      |                                           |            |               |
      +-------------------------------------------+            +---------------+

{: #architecture-diagram title="Architecture Overview"}

The goal of this protocol is to enable a Wallet Server to improve the reliability, security and management of Credentials issued to the Holder while using application-layer encryption and wallet client authentication to minimize the sensitive user data unnecessarily exposed to the Wallet Server. Due to their distributed nature, Client applications are notoriously difficult to update, have poor connectivity, slower analytics and are a less trusted environment. An Issuer Server could work around these issues, but as the provider of both the Client and the Server, the Wallet Provider can be in a better position to alleviate these problems.

At a high level the protocol works as follows:

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:

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 Credential Configuration(s) to identify the type of credentials they wish issued.
    2. The Wallet provides a stable unique Session Id associated with the WSK and the Issuer provides a stable Verification Id to reference this session.
  2. 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.
  3. The Wallet Server calls The Issuer Server, passing Wallet Client-supplied Verification Data and, optionally, providing additional Wallet Server-supplied Verification Data.

    1. As an optimization, Verification Data can be provided in the initial call.
    2. Examples include risk and fraud signals or server collected verification data and evaluations.
  4. The Issuer Server decrypts and verifies the Verification Data using the WSK, and evaluates it along with any Wallet Server provided Verification Data.

    1. The Issuer can perform the evaluation asynchronously to support evaluations that are not immediate (such as human reviews).
    2. The Issuer Server can optionally repeat this process to trigger the collection of additional Verification.
  5. After reaching a verdict the Issuer Server updates the verification status and notifies the Wallet Server of the change.

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 authenticated the Holder.

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.
  2. The Wallet Client generates proofs for Presentation Keys and signs-then-encrypts them using the WSK and the Issuer encryption key. The Wallet Client also creates an encryption key and signs it with the WSK.
  3. The Wallet Server retrieves a batch of Credentials using the Credential Instance Identifiers and the client payload.

    1. The Credentials can be retrieved asynchronously by the Issuer Server returning a PENDING state.
  4. The Issuer verifies the keys originated on the correct client using the WSK, validates the proofs and creates the Credentials. The Credentials are encrypted using the Wallet Encryption Key before being sent back to the Wallet.

    1. Credential Metadata, such as display can optionally be returned as well.

This process is repeated to refresh the Credentials and to update them. Post initial issuance, Credentials lifecycle can be managed through the following processes:

5. Endpoints

This specification defines a series of endpoints on both the Wallet Server and the Issuer Server. Endpoints.

Table 1
Endpoint Path Implemented By Description
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.
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.
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.
Get Credential Metadata /credential/metadata Issuer Retrieves metadata for a specific credential configuration.
Get Credential Status /credential/status Both Bidirectional endpoint to query the current status of a credential instance.
Credential Management /credential/manage Both Handles ongoing management and lifecycle operations for a Credential Instance.
Event Notification /event/notify Both Bidirectional poke channel for action-based notifications.

The following requirements apply to all endpoints.

5.1. 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.

Issuers MUST associate a SessionId with the mTLS client identity that created it and reject requests for that SessionId from any other identity.

5.2. Transport

All requests to endpoints MUST use HTTPS (TLS 1.2+) with mutual authentication. All requests and response bodies are JSON and MUST use the media type application/json.

TODO: should add things about gRPC migration

5.3. API Versioning

The API uses header-based semantic versioning. The Client MUST include the desired API version in the Api-Version request header using the semantic version (e.g. 1.0.0).

Table 2
Header Direction Type Description
Api-Version Request String (semantic version) Required. Semantic version requested by the client (e.g., 1.0.0)
Api-Version Response String (semantic version) Required. The version used to process the request
Api-Supported-Versions Response String (comma-separated versions) Comma-separated list of versions the server supports
Sunset Response String (HTTP-date) HTTP-date as defined in [RFC8594] after which the requested version will be removed

Server MUST reject requests with an unsupported Api-Version with HTTP 400 and a Problem Details response, indicating the supported versions in the header.

5.4. Error Handling

This API uses Problem Details for HTTP APIs [RFC9457] for all error responses. Success responses return clean payloads without error wrappers.

Error responses use content type application/problem+json and MAY include:

Table 3
Field type Description
type URI Machine-readable error type identifier (e.g., urn:credential-api:error:verification-expired)
title string Short human-readable summary of the error type
status integer HTTP status code
detail string Human-readable explanation specific to this occurrence
instance URI URI identifying this specific error occurrence (for support/debugging)

Implementations MAY extend the Problem Details object with additional fields (e.g., errorCode for machine-readable application codes, retryable flag, validationErrors array for field-level issues). See Section 3.1 of [RFC9457] for more information.

5.4.1. Error Types

This specification defines the following error types:

  • urn:openid:dcp:s2s:invalid_encryption: Error type returned when a payload fails to decrypt.
  • urn:openid:dcp:s2s:invalid_client_authentication: Error type returned when a Client Encrypted Payload verification fails.

5.5. End to End Encryption

All application-layer encryption is performed using JWE [RFC7516] with HPKE [RFC9180] key encapsulation, as defined in [I-D.ietf-jose-hpke-encrypt].

5.5.1. JweEncryptedPayload

The JweEncryptedPayload is the data structure used to represent an encrypted payload in the API.

Table 4
Field Type Description
jwe string/object (JWE) REQUIRED: JWE structure as either compact or json serialized. When the origin is
origin string (Enum) REQUIRED: Identifies the origin of the encryption (one of WALLET_CLIENT, WALLET_SERVER, or ISSUER).
purpose string OPTIONAL: Optional purpose hint.
extensions object OPTIONAL: Implementation-specific extension fields.

The JWE MUST include the alg and enc parameters. Additionally, if the jwk used in encryption included a kid it MUST include the kid parameter. When the origin is WALLET_CLIENT then the content MUST be a JWS (as specified in Client Encrypted Payloads section).

5.5.2. Client Encrypted Payload

Client Encrypted Payloads are sign-then-encrypted, to provide confidentiality and sender authentication. This MUST be used when the origin is WALLET_CLIENT. This is achieved using a nested JWT. The outer JWT is a JWE as described above, whose plaintext is a JWS [RFC7515]. The JWS is signed using the Wallet Client signing key.

The aud claim of the JWS payload MUST be set to the base64url encoded JWK SHA-256 thumbprint [RFC7638] of the key that is used to encrypt the Client Encrypted Payload.

When receiving a payload containing Wallet Client Encryption the Issuer MUST process it as follows:

  • Decrypt the outer JWE.
  • Verify the signature of the JWS matches the previously established Wallet Signing Key.
  • Verify that the aud matches the base64url encoded JWK SHA-256 thumbprint used to encrypt the outer JWE.

If this process fails for any received Client Encrypted Payload the Issuer MUST reject the request.

5.5.3. KeyData

All keys are communicated between the Wallet and Issuer using this common key structure.

Table 5
Field Type Description
keyType string REQUIRED: Semantic use for the key.
client_public_key object (JWK) REQUIRED: The public key in the JWK format as defined in [RFC7517].
attestation Object (Proof) OPTIONAL: Attestation about the key. For example a platform-provided x509-chain or a keyattestation-jwt.
purpose string OPTIONAL: Human-readable purpose of the key.
extensions object OPTIONAL: Implementation-specific extension fields.

The publicKey MUST include the alg identifier and is RECOMMENDED to include a keyId.

This specification defines two key types:

  • WALLET_SIGNING_KEY: Key used by the Wallet Client Instance as a proof-of-origin
  • WALLET_ENCRYPTION_KEY: Key provided by the Wallet Client Instance for the Issuer to encrypt sensitive data to.

Implementations MAY define their own key types. It is RECOMMENDED that collision-resistant values are used, such as r-DNS or urns.

TODO: add post quantum

TODO: required curves

5.6. Content Reference

This section details how large content can be passed by reference to a downloadable URL, rather than by value.

Table 6
Field Type Description
downloadUrl string (URI) REQUIRED: The URL where the content can be downloaded.
contentDigest string (byte) REQUIRED: SHA-256 digest of the JWE content.
contentSize integer OPTIONAL: The size of the content in bytes.
expiresAt string (date-time) OPTIONAL: The timestamp after which the URL expires.
extensions object OPTIONAL: Implementation-specific extension fields.

5.7. Idempotency

All requests MUST include the x-request-id header (UUID). Duplicate requests with the same value MUST return the original response without re-executing the operation.

5.8. Rate Limiting

Clients receiving HTTP 429 MUST honor the Retry-After header. Exponential backoff is RECOMMENDED: 0–1s, 1.1–5s, 5.1–30s (max 3 retries).

5.9. Identifier Model

The API uses the following identifiers:

  • SessionId: An identifier associated with a particular Wallet Client Instance, persistent throughout the process.
  • VerificationId: An identifier for a particular verification session. A SessionId may have multiple VerificationIds associated with it over the course of it's lifetime (due to re-verification).
  • CredentialInstanceId: An identifier for a particular credential Data Set, on a particular Wallet Client Instance. A single SessionId and VerificationId may result in multiple CredentialInstanceIds being issued associated with that SessionId (e.g. multiple digital payment credentials all issued for a single bank account).
  • CredentialConfigurationId: An identifier for a particular type/configuration of a credential at an issuer. A single Verification Session can be used to issue multiple different Credential Configurations.

All identifiers are opaque strings assigned by the issuer unless otherwise noted. No format, prefix, or structure is enforced by this specification. Implementations may define conventions (e.g., prefixed UUIDs) but interoperability does not depend on identifier structure.

SessionId MUST be globally unique. CredentialInstanceId MUST be unique for an Issuer. VerificationId and CredentialInstanceIds MUST be unique for a given SessionId.

5.10. Verification Endpoints

The Verification endpoints are used to determine that a particular Wallet Client Instance authorized to have a Credential. This encompasses Identity Proofing, (e.g., document authentication, liveness detection, facial matching for government IDs), eligibility verification (e.g., fraud scoring, account standing checks for payment cards, access badges) as well as transferring Verification from another context (pre-auth code, device migration).

5.10.1. Engagement

There are five different flows we are considering in this specification:

  1. Wallet Initiated (Preknown Verification): Holder in a Wallet Client Instance, where the Issuer's required VerificationData is known in advance.
  2. Wallet Initiated (Negotiated Verification): Holder in a Wallet Client Instance, where the Issuer's required Verification Data is unknown
  3. Issuer Initiated (Authed Holder): Holder is in an Issuer Surface (e.g. Issuer App) where the holder is already authenticated. The Holder wishes to push one or more credentials to a Wallet Client Instance of their choosing.
  4. Issuer Initiate (Unauthed Holder): Holder is in an Issuer Surface (e.g. Issuer Website) but are not currently (sufficiently) authenticated. The Holder wishes to initiate a Wallet Client Instance and begin Issuance of some Credentials.
  5. Device Migration: Holder in a new Wallet Client Instance, but has previously performed Verification in another Wallet Client Instance.

All engagement is modeled as the Wallet receiving a Credential Offer payload from the Issuer.

This could be obtained:

  • Via a front-channel, such as DC API create, a deep-link or a QR code.
  • Via a back-channel call from the Issuer Server to the Wallet Server

    • Though this is currently out of scope of this specification
5.10.1.1. Credential Offer Payload Schema

TODO: Determine the best way to pass Pre-Auth/VerificationDataRequest/Issuer State, whether to re-use what is in canonical VCI or extend it

5.10.2. Verification Initiate

The path MUST be /verification/initiate. This endpoint is hosted by the Issuer Server only.

The Verification Initiate endpoint is the first endpoint called by the Wallet Server, and starts the verification process for a Wallet Client Instance.

5.10.2.1. Session Establishment

The Wallet Server provides a long-lived SessionId to associate with the WalletSigningKey. The Issuer provides the VerificationId in the response, which is used for follow-up calls to the Verification Endpoints.

CredentialInstanceIdentifiers are retrieved after verification through the Credential Provision endpoint.

5.10.2.2. 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.

Issuers MUST perform the following verification steps:

  • Verify the verificationNonce signature against the walletSigningKey included in the same request
  • Confirm the signed value matches the sessionId in the request
  • Confirm the sessionId has not been previously consumed

Because each sessionId is a unique UUID generated per verification session, a replayed request will be rejected — either the sessionId was already consumed, or a different sessionId will not match the original signature. Replay from a different device is also prevented, as only the holder of the private walletSigningKey can produce a valid signature.

5.10.2.3. Request Body Schema:
Table 7
Field Type Description
sessionId string(UUID) REQUIRED: Wallet Server-generated UUID for this session. Shared correlation identifier that threads verification and credential issuance.
credentialConfigurationIds Array (string) REQUIRED: Identifies the credential types/templates for the credentials being requested.Issuers use this to determine which credential type and configuration apply.
walletSigningKeyData object (KeyData) REQUIRED: Key Data belong to the Public Key for the Wallet Client Instance that is initiating this verification.Must be stored against this sessionId and used to verify this and subsequent requests originate from the same authenticated client instance.
verificationNonce string(bytes) REQUIRED: Signature over sessionId, providing replay protection and cryptographic binding to the session.
verificationData Object (VerificationDataResponse) OPTIONAL: VerificationDataResponse to allow for Wallets to combine providing evidence when it is known in advance.
supportedVerificationTypes Array(String) OPTIONAL: List of verificationTypes this Wallet Client Instance supports, that can be used with ADDITIONAL_INFO_REQUIRED
requestedDeviceCount integer >=1 (default 1) OPTIONAL: Number of devices the Wallet Server intends to provision for this verification session. The issuer uses this as input when determining authorizedDeviceCount in the approval response. If omitted, defaults to 1.
locale string OPTIONAL: Local of the Wallet Client Instance to use for localization. When absent, the Issuer chooses the locale.
extensions object OPTIONAL: Implementation-specific extension fields. Reserved for proprietary data elements needed by specific deployments.
5.10.2.4. Response Body Schema:

The Response Body schema contains all of the fields in the VerificationStatus schema.

5.10.3. Supplement

The path MUST be /verification/supplement. This endpoint is hosted by the Issuer Server only.

This is used to provide Verification Data for an ongoing Verification.

5.10.3.1. Request Body Schema
Table 8
Field Type Description
sessionId string(UUID) REQUIRED: Wallet-Generated id received in the initiate call.
verificationId string(UUID) REQUIRED: Issuer-generated id for the current verification session.
verificationDataPayload Object (VerificationDataResponse) REQUIRED: Containing verification data for this verification session.
extensions Object OPTIONAL: Implementation-specific extension fields.
5.10.3.2. Response Body Schema

The Response Body schema contains all of the fields in the VerificationStatus schema.

5.10.4. Verification Notification

The path MUST be /verification/notify. This endpoint is hosted by the Wallet Server only.

This is used by the Issuer to notify the Wallet that a Verification has changed status. The information provided here is also available at the Verification Status Endpoint.

5.10.4.1. Request Body Schema

The Request Body contains allOf the fields in the VerificationStatus schema.

5.10.4.2. Response Body Schema
Table 9
Field Type Description
sessionId string(UUID) REQUIRED: Wallet-Generated id received in the initiate call.
verificationId string(UUID) REQUIRED: Issuer-generated id for the current verification session.

5.10.5. Get Verification Status

The path MUST be /verification/status. This endpoint is hosted by the Issuer Server only.

5.10.5.1. Request Body Schema
Table 10
Field Type Description
sessionId string(UUID) REQUIRED: Wallet-Generated id received in the initiate call.
verificationId string(UUID) REQUIRED: Issuer-generated id for the current verification session.
extensions Object OPTIONAL: Implementation-specific extension fields.
5.10.5.2. Response Body Shema

The Response Body contains allOf the fields in the VerificationStatus schema.

5.10.6. Verification Cancellation

The path MUST be /verification/cancel. This endpoint is hosted by the Issuer Server only.

5.10.6.1. Request Body Schema
Table 11
Field Type Description
sessionId string(UUID) REQUIRED: Wallet-Generated id received in the initiate call.
verificationId string(UUID) REQUIRED: Issuer-generated id for the current session.
reason string REQUIRED: Indicates the reason for cancellation.
extensions Object OPTIONAL: Implementation-specific extension fields.
5.10.6.2. Response Body Schema
Table 12
Field Type Description
sessionId string(UUID) REQUIRED: Wallet-Generated id received in the initiate call.
verificationId string(UUID) REQUIRED: Issuer-generated id for the current session.

5.10.7. Verification Status

A Verification is often a long-lived process, and the VerificationStatus is used to represent the current state of the Verification. The Issuer Server is the single source of truth for the Verification.

The current VerificationStatus is returned from both the Initiate and Supplement Verification endpoints. Changes to the VerificationStatus are communicated using a poke model, where the Issuer notifies the Wallet Server on change, and the current status can also be polled by the Wallet Server.

The following JSON Schema is used at all endpoints:

5.10.7.1. VerificationStatus Schema
Table 13
Field Type Description
sessionId string(UUID) REQUIRED: Wallet-Generated id received in the initiate call.
verificationId string(UUID) REQUIRED: Issuer-generated id for the current session. The value MUST NOT change from the one returned in the initial response..
status string(VerificationStatus) REQUIRED: Enum identifier for the current verification status.
extensions Object OPTIONAL: Implementation-specific extension fields. Implementations may include proprietary decision details, additional credential metadata, or domain-specific status information.

Additional fields are specified based on the VerificationStatus. The following VerificationStatus values are defined by this specification:

Table 14
Status Description Next Step
"APPROVED" Verification Passed Wallet Server calls /credential/provision to fetch the credentialInstanceIds
"REJECTED" Most recent Verification Data was rejected. Wallet re-collects Verification Data and re-submit or cancel the verification
"DENIED" Verification Failed Flow ends
"ADDITIONAL_INFO_REQUIRED" Issuer requires more Verification Data Wallet Server calls verification/supplement with additional Verification Data.
"PENDING" Decision Deferred The wallet waits for status to change.
"EXPIRED" Verification Session Timed out Flow ends

The following fields are present based on type:

5.10.7.1.1. APPROVED Status Fields
Table 15
Field Type Description
credentialConfigurationIds Array (string) REQUIRED: Credential Configurations that
authorizedDeviceCount Integer (>=1), default=1 OPTIONAL: Maximum number of devices this SessionId/VerificationId can be used on, after which the Issuer SHOULD reject any further attempts.
5.10.7.1.2. REJECTED Status Fields
Table 16
Field Type Description
reasonCode string REQUIRED: Rejection reason code.
rejectedDetails string OPTIONAL: Details for logging.
5.10.7.1.3. DENIED Status Fields
Table 17
Field Type Description
reasonCode string REQUIRED: Denial reason code.
deniedMessage string REQUIRED: Message for the human.
5.10.7.1.4. ADDITIONAL_INFO_REQUIRED Status Fields
Table 18
Field Type Description
verificationDataRequest Object (VerificationDataRequest) REQUIRED: Used to collect additional information from the holder.

5.10.8. Verification Data

Verification Data is an extensible mechanism for a Wallet to provide the Issuer with Data used to determine that a Credential can be issued to the Wallet Client Instance. This can include information both originating from the Wallet Client and the Wallet Server. Examples include:

  • Verifiable Digital Credential presentations
  • Wallet-collected documents
  • Auth via a redirect to web or other issuer surface
  • Pre-auth bearer token binding this session to another
  • Previous SessionId/VerificationIds to associate this Wallet Client Instance with a previous one
  • Risk or other attestation signals from the Wallet Server

The flow is as follows:

  1. [upfront] Wallet communicates the supported_verification_types
  2. Issuer Server provides a VerificationDataRequest detailing the requested Data

    • This is optional if pre-known by the Wallet
  3. The Wallet Client performs the necessary actions to collect the required Data from the Holder, and passes it, encrypted, to the Wallet Server.
  4. The Wallet Server adds any additional VerificationData and provides a VerificationDataResponse to the Verification Supplement endpoint.
  5. The Issuer decrypts and verifies the clientPayload and then (asynchronously) processes the response.
  6. The Issuer repeats steps 2-5 until it reaches a final decision.
5.10.8.1. VerificationDataRequest Schema
Table 19
Field Type Description
verificationDataItems Array (VerificationDataItemRequest) REQUIRED: Array of items requested
deadline string (date-time) OPTIONAL: deadline for the request, after which the Verification will be DENIED.
maxAttempts integer OPTIONAL: Maximum number of attempts allowed, after which the Verification will be DENIED.
extensions object OPTIONAL: Implementation-specific extension fields
5.10.8.2. VerificationDataItemRequest Schema
Table 20
Field Type Description
type string REQUIRED: Type of the Verification item
id string REQUIRED: Unique identifier for the item
required boolean REQUIRED: Whether this VerificationDataItem MUST be provided.
extensions object OPTIONAL: Implementation-specific extension fields..

Additional type-specific fields MAY be required based on verification type. It is RECOMMENDED to use collision-resistance values for verification type such as URNs or r-DNS.

TODO: define default ones.

5.10.8.3. VerificationDataResponse Schema
Table 21
Field Type Description
clientEncryptedPayload Array (JweEncryptedPayload (VerificationDataItem)) OPTIONAL: Encrypted payload originating from the Wallet Client, containing a VerificationDataItem.
serverVerificationDataItem Array (VerificationDataItem) OPTIONAL: Verification items provided by the Wallet Server.
additionalAssessments Array (object) OPTIONAL: Additional risk or eligibility assessments from the Wallet Server.
extensions object OPTIONAL: Implementation-specific extension fields.

clientEncryptedPayload contains the WALLET_CLIENT originating VerificationDataItem, while serverVerificationDataItem contains ones that originate in the WALLET_SERVER backend. A VerificationDataItem MAY be present in both, in the case where part of the data comes from one system and part from another.

The Issuer MUST verify the clientEncryptedPayload using the WalletSigningKey in the active session before proceeding to evaluate the VerificationDataItem.

5.10.8.4. VerificationDataItem Schema
Table 22
Field Type Description
id string REQUIRED: Unique identifier for the item.
type string REQUIRED: Type of the Verification item.
extensions object OPTIONAL: Implementation-specific extension fields.

Additional type-specific fields MAY be required based on verification type. It is RECOMMENDED to use collision-resistance values for verification type such as URNs or r-DNS.

5.11. Credential Endpoints

These endpoints are used to initially retrieve a Credential onto a Holders device, as well as to fetch new Credentials as needed.

In addition they also control the lifecycle through the Get Credential Status and Manage Credential endpoints.

5.11.1. Provision Credential

This endpoint is used to fetch credential instance IDs after verification approval. The path MUST be /credential/provision.

5.11.1.1. Request Body Schema
Table 23
Field Type Description
sessionId string (UUID) REQUIRED: Wallet Server-generated UUID for this session.
verificationId string (UUID) REQUIRED: Issuer-generated id for the current session.
extensions object OPTIONAL: Implementation-specific extension fields.
5.11.1.2. Response Body Schema
Table 24
Field Type Description
CredentialInstances Array (object) REQUIRED: Array of objects containing credential configuration and instance IDs.
extensions object OPTIONAL: Implementation-specific extension fields.

Each CredentialInstances object contains:

  • credentialConfigurationId: (string, required)
  • credentialInstanceIds: (Array (string), required)

5.11.2. Get Credential

This endpoint is used to retrieve the verifiable credentials for a specific credential instance. The path MUST be /credential/get.

5.11.2.1. Request Body Schema
Table 25
Field Type Description
sessionId string REQUIRED: Identifier for the overarching Session.
credentialInstanceId string REQUIRED: Credential Identifier.
reason string REQUIRED.: Reason for the Wallet initiating the credential fetch, for debugging purposes.
walletEncryptionKey object (KeyData) REQUIRED: Key provided for the Issuer to encrypt sensitive data to.
clientEncryptedData object (ClientEncryptedPayload) OPTIONAL: Payload containing an object containing an array of presentmentKeys.
currentCredentialMetadataVersion string OPTIONAL: Current Version identifier for the credential metadata.
extensions object OPTIONAL: Implementation-specific extension fields.
5.11.2.2. Response Body Schema
Table 26
Field Type Description
credentialMetadata object (CredentialMetadata) OPTIONAL: Metadata for the specific credential configuration.
credentialVersion string REQUIRED: Unique identifier for the credential data set version.
credentials object (JWE) REQUIRED: JWE object whose plaintext is an Array of Credentials.
extensions object OPTIONAL: Implementation-specific extension fields.

5.11.3. Get Credential Metadata

This endpoint retrieves metadata for a specific credential configuration. The path MUST be /credential/metadata.

5.11.3.1. Request Body Schema
Table 27
Field Type Description
sessionId string REQUIRED: Identifier for the overarching Session.
credentialInstanceId string REQUIRED: Credential Identifier.
walletEncryptionKey object (KeyData) REQUIRED: Key provided for the Issuer to encrypt sensitive data to.
credentialMetadataVersion string OPTIONAL: Version identifier for the requested metadata.
extensions object OPTIONAL: Implementation-specific extension fields.
5.11.3.2. Response Body Schema
Table 28
Field Type Description
credentialMetadata object (CredentialMetadata) OPTIONAL: Metadata for the specific credential instance. Includes displayData as well as other relevant metadata.
extensions object OPTIONAL: Implementation-specific extension fields.

5.11.4. Get Credential Status

The Get Credential Status endpoint is a bidirectional endpoint that provides the current status from the perspective of that server.

The path MUST be /credential/status.

5.11.4.1. Reconciliation

The Wallet Server and the Issuer Server each have their own view on what the status of the credential should be. The Response provides sufficient information to allow the calling server to be aware as to what action should be taken to reconcile the different states.

(TODO: Add a grid defining what next step should be taken?).

5.11.4.2. Request Body Schema
Table 29
Field Type Description
sessionId string REQUIRED: Identifier for the overarching Session being queried.
credentialInstanceId string REQUIRED: Credential Identifier whose status is being queried.
extensions object OPTIONAL: Implementation specific extensions
5.11.4.3. Response Body Schema
Table 30
Field Type Description
currentStatus String (CredentialStatus) REQUIRED: The current status of the credential instance
currentVersion String REQUIRED: Unique identifier for the credential data set version.
lastStatusChangeTime String (HTTP-date) OPTIONAL: Date and time when the status was last updated
lastStatusChangeReason String OPTIONAL: Machine-readable reason for the status change
extensions Object OPTIONAL: Implementation-specific extension fields

The following Credential Status states are defined by this specification.

Table 31
Status Description
ACTIVE Credential is active and usable
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
CANCELLED Credential permanently invalidated
UNKNOWN Status cannot be determined

5.11.5. Credential Manage

This bi-directrional endpoint instructs the hosting party to perform an action for a particular credentialInstanceId. The path MUST be /credential/manage.

5.11.5.1. Request Body Schema
Table 32
Field Type Description
sessionId string (UUID) REQUIRED: Wallet Server-generated UUID for this session.
credentialInstanceId string REQUIRED: Credential Identifier associated with this management operation.
action string (Enum) REQUIRED: The management action to perform. One of: SUSPEND, RESUME, UNLINK.
reason string OPTIONAL: Machine-readable reason for the management action.
reasonDetail string OPTIONAL: Free-form additional context or details for the action.
timestamp string (date-time) OPTIONAL: ISO 8601 timestamp of when the request was initiated.
extensions object OPTIONAL: Implementation-specific extension fields.
5.11.5.2. Response Body Schema
Table 33
Field Type Description
sessionId string (UUID) REQUIRED: Wallet Server-generated UUID for this session.
credentialInstanceId string REQUIRED: Credential Identifier associated with this management operation.
currentStatus string (CredentialStatus) REQUIRED: The status of the credential instance after the operation.
previousStatus string (CredentialStatus) OPTIONAL: The status of the credential instance before the operation was initiated.
outcome string (Enum) REQUIRED: The outcome of the operation. One of: COMPLETED, SCHEDULED, FAILED, NO_CHANGE.
failureReason string OPTIONAL: Machine-readable reason for failure if the outcome is failed.
extensions object OPTIONAL: Implementation-specific extension fields.

5.12. Event Notification Endpoint

This endpoint is used to provide a bidirectional notification channel between the Wallet Server and the Issuer Server. All notifications follow the poke model, describing an action to be performed by the recipient, but not containing unrecoverable data.

The path MUST be /event/notify and implemented by both the Wallet Server and the Issuer Server.

5.12.1. Request Body Schema

Table 34
Field Type Description
sessionId string REQUIRED: Identifier for the overarching Session.
credentialInstanceId string REQUIRED: Credential Identifier associated with the event.
eventType string REQUIRED: The type of event being notified.
triggeringRequestId string (UUID) OPTIONAL: The x-request-id of the original request that triggered this event.
eventTimestamp string (date-time) REQUIRED: The timestamp when the event was created.
eventDetails object TYPE DEPENDENT: Implementation-specific details dependent on the eventType.
extensions object OPTIONAL: Implementation-specific extension fields.

5.12.2. Event Types

The following event types are defined by this specification:

Table 35
Event Origin Description
PROVISIONING_SUCCESS Wallet Server Credential successfully provisioned to device
PROVISIONING_FAILURE Wallet Server Credential provisioning failed
LIFECYCLE_SUCCESS Wallet Server Lifecycle action completed
LIFECYCLE_FAILURE Wallet Server Lifecycle action failed
UPDATE_SUCCESS Wallet Server Credential update applied to device
UPDATE_FAILURE Wallet Server Credential update failed
UPDATE_REMINDER Wallet Server Pending update awaiting delivery
CREDENTIAL_EXPIRING Wallet Server Credential approaching expiry
KEY_ROTATED Wallet Server Device generated new presentment keys
CREDENTIAL_READY Issuer Async credential is ready for retrieval
CREDENTIAL_UPDATE_AVAILABLE Issuer Updated credential data available for retrieval
DISPLAY_DATA_UPDATED Issuer Visual representation has changed

TODO: Add the detailed schemas by type

5.12.3. Response Body Schema

The response body schema optionally contains an acknowledged boolean to indicate that the event was processed.

6. Issuer Metadata

TODO: work out what needs to be configurable. E.g. issuer_server_url, configurations, supported_signing_algs, supported_encryption_algs, issuer_encryption_jwks, supported_extensions, and what comes from VCI spec s.a supported_proofs etc.

7. Security Considerations

7.1. Wallet Client Origin

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.

7.2. Wallet Client and Wallet Client Instance Trust

This specification delegates the decision about whether a Wallet Client, or a specific instance of it, can be trusted, and to what extent, to the Wallet Server. For example, the Wallet Server can securely verify the Wallet Client's integrity using platform-level hardware checks before executing any lifecycle actions. The exact mechanism for determining Wallet Client trust is out of scope for this specification, but must be considered by implementers.

7.3. Pre-authorization Code security measures

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.

8. Privacy Considerations

8.1. Data Minimization

By design, the Wallet Server is always aware of what types of Credentials and the Issuers that a Wallet Holder is interacting with. This is necessary for the Wallet Server to provide value to the Issuer and the Holder. The specification is however designed with the principle of Data Minimization, where application layer encryption combined with sender authentication (using the Wallet Signing Key) is used to ensure confidentiality of the sensitive portions of the payload that are not required by the Wallet Server.

9. Implementation Considerations

9.1. Asynchronous Endpoints

The APIs are designed so that the Verification and Credential endpoints operate asynchronously. Wallet Servers MUST support returning responses both immediately and asynchronously in the future. As notifications are unreliable, it's RECOMMENDED that Wallet Servers use both notifications and polling-with-backoff to receive results from these endpoints as quickly and reliably as possible.

Because these endpoints are asynchronous, Wallet Clients need to be able to handle receiving the results asynchronously as well. The API between the Wallet Client and Server is outside the scope of this specification, but it would be advisable to adopt a similar approach between the Wallet Client and Server.

9.2. Extensions

The API in this specification defines extension points throughout the protocol, using an extensions object. It is RECOMMENDED to use collision-resistant field names within the extension, such as r-DNS or urns. To maximize interoperability, Wallets and Issuers are RECOMMENDED to ignore unknown extensions, and process the Requests or Responses as though they aren't present

10. Normative References

[I-D.ietf-jose-hpke-encrypt]
Reddy.K, T., Tschofenig, H., Banerjee, A., Steele, O., and M. B. Jones, "Use of Hybrid Public Key Encryption (HPKE) with JSON Web Encryption (JWE)", Work in Progress, Internet-Draft, draft-ietf-jose-hpke-encrypt-22, , <https://datatracker.ietf.org/doc/html/draft-ietf-jose-hpke-encrypt-22>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC7515]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, , <https://www.rfc-editor.org/info/rfc7515>.
[RFC7516]
Jones, M. and J. Hildebrand, "JSON Web Encryption (JWE)", RFC 7516, DOI 10.17487/RFC7516, , <https://www.rfc-editor.org/info/rfc7516>.
[RFC7517]
Jones, M., "JSON Web Key (JWK)", RFC 7517, DOI 10.17487/RFC7517, , <https://www.rfc-editor.org/info/rfc7517>.
[RFC7638]
Jones, M. and N. Sakimura, "JSON Web Key (JWK) Thumbprint", RFC 7638, DOI 10.17487/RFC7638, , <https://www.rfc-editor.org/info/rfc7638>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8594]
Wilde, E., "The Sunset HTTP Header Field", RFC 8594, DOI 10.17487/RFC8594, , <https://www.rfc-editor.org/info/rfc8594>.
[RFC8705]
Campbell, B., Bradley, J., Sakimura, N., and T. Lodderstedt, "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens", RFC 8705, DOI 10.17487/RFC8705, , <https://www.rfc-editor.org/info/rfc8705>.
[RFC9180]
Barnes, R., Bhargavan, K., Lipp, B., and C. Wood, "Hybrid Public Key Encryption", RFC 9180, DOI 10.17487/RFC9180, , <https://www.rfc-editor.org/info/rfc9180>.
[RFC9457]
Nottingham, M., Wilde, E., and S. Dalal, "Problem Details for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, , <https://www.rfc-editor.org/info/rfc9457>.

11. Informative References

[I-D.ietf-oauth-sd-jwt-vc]
Terbu, O., Fett, D., and B. Campbell, "SD-JWT-based Verifiable Digital Credentials (SD-JWT VC)", Work in Progress, Internet-Draft, draft-ietf-oauth-sd-jwt-vc-19, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-sd-jwt-vc-19>.
[ISO.18013-5]
ISO/IEC JTC 1/SC 17 Cards and security devices for personal identification, "ISO/IEC 18013-5:2021 Personal identification — ISO-compliant driving licence — Part 5: Mobile driving licence (mDL) application", , <https://www.iso.org/standard/69084.html>.
[VC_DATA_2.0]
Sporny, M., Jr, T. T., Herman, I., and G. Cohen, "Verifiable Credentials Data Model 2.0", , <https://www.w3.org/TR/2025/REC-vc-data-model-2.0-20250515/>.

Appendix A. Verification Flow Examples

A.1. Wallet Initiated (Preknown Verification)

A non-normative example of a Wallet Initiated(Preknown Verification) Flow is:

┌────────┐            ┌───────────────┐       ┌───────────────┐               ┌───────────────┐
│ Holder │            │ Wallet Client │       │ Wallet Server │               │ Issuer Server │
└────┬───┘            └───────┬───────┘       └───────┬───────┘               └───────┬───────┘
     │                        │                       │                               │
     │     1. Selects a       │                       │                               │
     │  Credential to Issue   │                       │                               │
     │────────────────────────▶                       │                               │
     │                        │                       │                               │
     │                        ├───┐                   │                               │
     │                        │   │ Generates WSK &   │                               │
     │                        │   │ collects          │                               │
     │                        │   │ VerificationData  │                               │
     │                        ◀───┘                   │                               │
     │                        │                       │                               │
     │                        │                       │                               │
     │                        │                       │                               │
     │                        │       2. Sends        │                               │
     │                        │   Signed/Encrypted    │                               │
     │                        │  VerificationData +   │                               │
     │                        │   verificationNonce   │                               │
     │                        │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │
     │                        │                       │                               │
     │                        │                       ├───┐                           │
     │                        │                       │   │ Adds additional           │
     │                        │                       │   │ VerificationData          │
     │                        │                       ◀───┘                           │
     │                        │                       │                               │
     │                        │                       │                               │
     │                        │                       │           3. Calls            │
     │                        │                       │    'verification/initiate'    │
     │                        │                       │───────────────────────────────▶
     │                        │                       │                               │
     │                        │                       │                               ├───┐
     │                        │                       │                               │   │ Validates
     │                        │                       │                               │   │ verificationNonce &
     │                        │                       │                               │   │ encryptedClientPayload
     │                        │                       │                               ◀───┘
     │                        │                       │                               │
     │                        │                       │                               │
     │                        │                       │                               │
     │                        │                       │      4. status: PENDING       │
     │                        │                       ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│
     │                        │                       │                               │
     │                        │                       │                               ├───┐
     │                        │                       │                               │   │ Asynchronously
     │                        │                       │                               │   │ evaluates
     │                        │                       │                               ◀───┘ VerificationData
     │                        │                       │                               │
     │                        │                       │                               │
     │                        │                       │                               │
     │                    ┌opt [4.1. Additional Verification]─────────────────────────────┐
     │                    │   |                       │                               │   │
     │                    │   │                       │    'verification/notify':     │   │
     │                    │   │                       │   ADDITIONAL_INFO_REQUIRED    │   │
     │                    │   │                       ◀───────────────────────────────│   │
     │                    │   │                       │                               │   │
     │                    │   │   Sends additional    │                               │   │
     │                    │   │   Signed/Encrypted    │                               │   │
     │                    │   │   VerificationData    │                               │   │
     │                    │   │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │   │
     │                    │   │                       │                               │   │
     │                    │   │                       │  'verification/supplement':   │   │
     │                    │   │                       │          additional           │   │
     │                    │   │                       │       VerificationData        │   │
     │                    │   │                       │───────────────────────────────▶   │
     │                    │   │                       │                               │   │
     │                    └───────────────────────────────────────────────────────────────┘
     │                        │                       │                               │
     │                        │                       │                               ├───┐ Updates
     │                        │                       │                               │   │ Verification
     │                        │                       │                               ◀───┘ Status
     │                        │                       │                               │
     │                        │                       │                               │
     │                        │                       │              5.               │
     │                        │                       │    'verification/notify':     │
     │                        │                       │        APPROVED/DENIED        │
     │                        │                       ◀───────────────────────────────│
     │                        │                       │                               │
┌────┴───┐            ┌───────┴───────┐       ┌───────┴───────┐               ┌───────┴───────┐
│ Holder │            │ Wallet Client │       │ Wallet Server │               │ Issuer Server │
└────────┘            └───────────────┘       └───────────────┘               └───────────────┘
  1. Holder, in the Wallet Client Instance selects a Credential to Issue.
  2. The Wallet Client generates a WSK and sends the Signed/Encrypted VerificationData, along with the verificationNonce to the Wallet Server.
  3. The Wallet Server adds any additional necessary VerificationData and calls verification/initiate on the Issuer Server.
  4. The Issuer validates the verificationNonce and the encryptedClientPayload, and returns the PENDING status. The Issuer asynchronously verifies the VerificationData.

    1. Optionally: uses ADDITIONAL_INFO_REQUIRED via verification/notify to obtain more information, which the Wallet Client provides via verification/supplement.
  5. The Issuer updates the Verification Status based on the outcome and sends a notification to the Wallet Server with APPROVED/DENIED.

A.2. Wallet Initiated (Negotiated Verification)

┌────────┐            ┌───────────────┐             ┌───────────────┐               ┌───────────────┐
│ Holder │            │ Wallet Client │             │ Wallet Server │               │ Issuer Server │
└────┬───┘            └───────┬───────┘             └───────┬───────┘               └───────┬───────┘
     │                        │                             │                               │
     │      1. Selects        │                             │                               │
     │  Credential to Issue   │                             │                               │
     │────────────────────────▶                             │                               │
     │                        │                             │                               │
     │                        ├───┐                         │                               │
     │                        │   │ Generates WSK           │                               │
     │                        ◀───┘                         │                               │
     │                        │                             │                               │
     │                        │    2. Initiates session     │                               │
     │                        │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │
     │                        │                             │                               │
     │                        │                             │           3. Calls            │
     │                        │                             │    'verification/initiate'    │
     │                        │                             │───────────────────────────────▶
     │                        │                             │                               │
     │                        │                             │                               ├───┐
     │                        │                             │                               │   │ verifies
     │                        │                             │                               ◀───┘ verificationNonce
     │                        │                             │                               │
     │                        │                             │                               │
     │                        │                             │          4. status:           │
     │                        │                             │   ADDITIONAL_INFO_REQUIRED    │
     │                        │                             │   + VerificationDataRequest   │
     │                        │                             ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│
     │                        │                             │                               │
     │                        │         5. Forwards         │                               │
     │                        │  ADDITIONAL_INFO_REQUIRED   │                               │
     │                        ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│                               │
     │                        │                             │                               │
     │      6. Request        │                             │                               │
     │   VerificationData     │                             │                               │
     ◀────────────────────────│                             │                               │
     │                        │                             │                               │
     │      7. Provides       │                             │                               │
     │   VerificationData     │                             │                               │
     │────────────────────────▶                             │                               │
     │                        │                             │                               │
     │                        │          8. Sends           │                               │
     │                        │      Signed/Encrypted       │                               │
     │                        │      VerificationData       │                               │
     │                        │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │
     │                        │                             │                               │
     │                        │                             │           9. Calls            │
     │                        │                             │   'verification/supplement'   │
     │                        │                             │───────────────────────────────▶
     │                        │                             │                               │
     │                        │                             │                               ├───┐
     │                        │                             │                               │   │ Decrypts and verifies
     │                        │                             │                               │   │ WSK signature
     │                        │                             │                               ◀───┘
     │                        │                             │                               │
     │                        │                             │                               │
     │                        │                             │                               │
     │                        │                             │      10. status: PENDING      │
     │                        │                             ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│
     │                        │                             │                               │
     │                        │                             │                               ├───┐
     │                        │                             │                               │   │ Asynchronously verifies
     │                        │                             │                               │   │ VerificationData
     │                        │                             │                               ◀───┘
     │                        │                             │                               │
     │                        │                             │                               │
     │                        │                             │                               │
     │                    ┌opt [10.1. Additional Verification]──────────────────────────────────┐
     │                    │   |                             │                               │   │
     │                    │   │                             │    'verification/notify':     │   │
     │                    │   │                             │   ADDITIONAL_INFO_REQUIRED    │   │
     │                    │   │                             ◀───────────────────────────────│   │
     │                    │   │                             │                               │   │
     │                    │   │      Sends additional       │                               │   │
     │                    │   │      Signed/Encrypted       │                               │   │
     │                    │   │      VerificationData       │                               │   │
     │                    │   │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │   │
     │                    │   │                             │                               │   │
     │                    │   │                             │  'verification/supplement':   │   │
     │                    │   │                             │          additional           │   │
     │                    │   │                             │       VerificationData        │   │
     │                    │   │                             │───────────────────────────────▶   │
     │                    │   │                             │                               │   │
     │                    └─────────────────────────────────────────────────────────────────────┘
     │                        │                             │                               │
     │                        │                             │                               ├───┐ Updates
     │                        │                             │                               │   │ Verification
     │                        │                             │                               ◀───┘ Status
     │                        │                             │                               │
     │                        │                             │                               │
     │                        │                             │              11.              │
     │                        │                             │    'verification/notify':     │
     │                        │                             │        APPROVED/DENIED        │
     │                        │                             ◀───────────────────────────────│
     │                        │                             │                               │
┌────┴───┐            ┌───────┴───────┐             ┌───────┴───────┐               ┌───────┴───────┐
│ Holder │            │ Wallet Client │             │ Wallet Server │               │ Issuer Server │
└────────┘            └───────────────┘             └───────────────┘               └───────────────┘
  1. Holder, in the Wallet Client Instance, selects a Credential to Issue where the required VerificationData is unknown.
  2. The Wallet Client generates a WSK and initiates a session via the Wallet Server.
  3. The Wallet Server calls verification/initiate on the Issuer Server.
  4. The Issuer validates the verificationNonce and returns a status of ADDITIONAL_INFO_REQUIRED along with a VerificationDataRequest.
  5. The Wallet Server forwards the ADDITIONAL_INFO_REQUIRED status to the Wallet Client.
  6. The Wallet Client requests the VerificationData from the Holder.
  7. The Holder provides the VerificationData.
  8. The Wallet Client sends the Signed and Encrypted VerificationData to the Wallet Server.
  9. The Wallet Server calls verification/supplement on the Issuer Server.
  10. The Issuer decrypts and verifies the WSK signature, returns the PENDING status, and asynchronously verifies the VerificationData.

    1. Optionally: uses ADDITIONAL_INFO_REQUIRED to obtain more information.
  11. The Issuer updates the Verification Status based on the outcome and sends a notification to the Wallet Server.

A.3. Issuer Initiated (Authed Holder)

┌────────┐        ┌────────────────────┐       ┌───────────────┐       ┌───────────────┐               ┌───────────────┐
│ Holder │        │ Issuer App/Website │       │ Wallet Client │       │ Wallet Server │               │ Issuer Server │
└────┬───┘        └──────────┬─────────┘       └───────┬───────┘       └───────┬───────┘               └───────┬───────┘
     │                       │                         │                       │                               │
     │  1. Authenticates &   │                         │                       │                               │
     │    elects to push     │                         │                       │                               │
     │      credentials      │                         │                       │                               │
     │───────────────────────▶                         │                       │                               │
     │                       │                         │                       │                               │
     │                       │        2. push:         │                       │                               │
     │                       │  credential_offer (w/   │                       │                               │
     │                       │     pre-auth code)      │                       │                               │
     │                       │─────────────────────────▶                       │                               │
     │                       │                         │                       │                               │
     │                       │                         ├───┐                   │                               │
     │                       │                         │   │ Generates WSK     │                               │
     │                       │                         ◀───┘                   │                               │
     │                       │                         │                       │                               │
     │                       │                         │       3. Sends        │                               │
     │                       │                         │   Signed/Encrypted    │                               │
     │                       │                         │  VerificationData +   │                               │
     │                       │                         │   verificationNonce   │                               │
     │                       │                         │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │
     │                       │                         │                       │                               │
     │                       │                         │                       ├───┐                           │
     │                       │                         │                       │   │ Adds additional           │
     │                       │                         │                       │   │ VerificationData          │
     │                       │                         │                       ◀───┘                           │
     │                       │                         │                       │                               │
     │                       │                         │                       │                               │
     │                       │                         │                       │           4. Calls            │
     │                       │                         │                       │    'verification/initiate'    │
     │                       │                         │                       │───────────────────────────────▶
     │                       │                         │                       │                               │
     │                       │                         │                       │                               ├───┐
     │                       │                         │                       │                               │   │ Validates
     │                       │                         │                       │                               │   │ verificationNonce &
     │                       │                         │                       │                               │   │ payload
     │                       │                         │                       │                               ◀───┘
     │                       │                         │                       │                               │
     │                       │                         │                       │                               │
     │                       │                         │                       │                               │
     │                       │                         │                       │                               ├───┐
     │                       │                         │                       │                               │   │ Verifies pre-auth
     │                       │                         │                       │                               │   │ code
     │                       │                         │                       │                               ◀───┘
     │                       │                         │                       │                               │
     │                       │                         │                       │                               │
     │                       │                     ┌opt [4.1. Additional Verification]─────────────────────────────┐
     │                       │                     │   |                       │                               │   │
     │                       │                     │   │                       │    'verification/notify':     │   │
     │                       │                     │   │                       │   ADDITIONAL_INFO_REQUIRED    │   │
     │                       │                     │   │                       ◀───────────────────────────────│   │
     │                       │                     │   │                       │                               │   │
     │                       │                     │   │   Sends additional    │                               │   │
     │                       │                     │   │   Signed/Encrypted    │                               │   │
     │                       │                     │   │   VerificationData    │                               │   │
     │                       │                     │   │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │   │
     │                       │                     │   │                       │                               │   │
     │                       │                     │   │                       │  'verification/supplement':   │   │
     │                       │                     │   │                       │          additional           │   │
     │                       │                     │   │                       │       VerificationData        │   │
     │                       │                     │   │                       │───────────────────────────────▶   │
     │                       │                     │   │                       │                               │   │
     │                       │                     └───────────────────────────────────────────────────────────────┘
     │                       │                         │                       │                               │
     │                       │                         │                       │                               ├───┐
     │                       │                         │                       │                               │   │ Updates Verification
     │                       │                         │                       │                               │   │ Status
     │                       │                         │                       │                               ◀───┘
     │                       │                         │                       │                               │
     │                       │                         │                       │                               │
     │                       │                         │                       │              5.               │
     │                       │                         │                       │    'verification/notify':     │
     │                       │                         │                       │        APPROVED/DENIED        │
     │                       │                         │                       ◀───────────────────────────────│
     │                       │                         │                       │                               │
┌────┴───┐        ┌──────────┴─────────┐       ┌───────┴───────┐       ┌───────┴───────┐               ┌───────┴───────┐
│ Holder │        │ Issuer App/Website │       │ Wallet Client │       │ Wallet Server │               │ Issuer Server │
└────────┘        └────────────────────┘       └───────────────┘       └───────────────┘               └───────────────┘
  1. Holder is authenticated on an Issuer App/Website and elects to push credentials to a Wallet.
  2. The Issuer App/Website pushes the Credential Offer payload containing a pre-authorized_code or similar Pre-auth bearer token to the Wallet Client.
  3. The Wallet Client generates a WSK and sends the Signed/Encrypted VerificationData (including the pre-auth code), along with the verificationNonce to the Wallet Server.
  4. The Wallet Server adds any additional necessary VerificationData and calls verification/initiate on the Issuer Server. The Issuer validates the verificationNonce, payload, and verifies the pre-auth code.

    1. Optionally: uses ADDITIONAL_INFO_REQUIRED via verification/notify to obtain more information (e.g. an OTP).
  5. The Issuer updates the Verification Status based on the outcome and sends an APPROVED/DENIED notification to the Wallet Server.

A.4. Issuer Initiated (Unauthed Holder)

┌────────┐     ┌────────────────────┐   ┌───────────────┐             ┌───────────────┐               ┌───────────────┐
│ Holder │     │ Issuer App/Website │   │ Wallet Client │             │ Wallet Server │               │ Issuer Server │
└────┬───┘     └──────────┬─────────┘   └───────┬───────┘             └───────┬───────┘               └───────┬───────┘
     │                    │                     │                             │                               │
     │   1. Interacts     │                     │                             │                               │
     │  unauthenticated   │                     │                             │                               │
     │────────────────────▶                     │                             │                               │
     │                    │                     │                             │                               │
     │                    │      2. push:       │                             │                               │
     │                    │  credential_offer   │                             │                               │
     │                    │─────────────────────▶                             │                               │
     │                    │                     │                             │                               │
     │                    │                     ├───┐                         │                               │
     │                    │                     │   │ Generates WSK           │                               │
     │                    │                     ◀───┘                         │                               │
     │                    │                     │                             │                               │
     │                    │                     │    3. Initiates session     │                               │
     │                    │                     │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │
     │                    │                     │                             │                               │
     │                    │                     │                             │           4. Calls            │
     │                    │                     │                             │    'verification/initiate'    │
     │                    │                     │                             │───────────────────────────────▶
     │                    │                     │                             │                               │
     │                    │                     │                             │                               ├───┐
     │                    │                     │                             │                               │   │ Validates
     │                    │                     │                             │                               ◀───┘
     │                    │                     │                             │                               │
     │                    │                     │                             │                               │
     │                    │                     │                             │          5. status:           │
     │                    │                     │                             │   ADDITIONAL_INFO_REQUIRED    │
     │                    │                     │                             │   + VerificationDataRequest   │
     │                    │                     │                             ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│
     │                    │                     │                             │                               │
     │                    │                     │         6. Forwards         │                               │
     │                    │                     │  ADDITIONAL_INFO_REQUIRED   │                               │
     │                    │                     │          (proofing          │                               │
     │                    │                     │        requirements)        │                               │
     │                    │                     ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│                               │
     │                    │                     │                             │                               │
     │               7. Requests                │                             │                               │
     │            VerificationData              │                             │                               │
     ◀──────────────────────────────────────────│                             │                               │
     │                    │                     │                             │                               │
     │               8. Provides                │                             │                               │
     │            VerificationData              │                             │                               │
     │──────────────────────────────────────────▶                             │                               │
     │                    │                     │                             │                               │
     │                    │                     │          9. Sends           │                               │
     │                    │                     │      Signed/Encrypted       │                               │
     │                    │                     │      VerificationData       │                               │
     │                    │                     │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │
     │                    │                     │                             │                               │
     │                    │                     │                             │           10. Calls           │
     │                    │                     │                             │   'verification/supplement'   │
     │                    │                     │                             │───────────────────────────────▶
     │                    │                     │                             │                               │
     │                    │                     │                             │                               ├───┐
     │                    │                     │                             │                               │   │ Decrypts and
     │                    │                     │                             │                               ◀───┘ verifies WSK
     │                    │                     │                             │                               │     signature
     │                    │                     │                             │                               │
     │                    │                     │                             │                               │
     │                    │                     │                             │      11. status: PENDING      │
     │                    │                     │                             ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│
     │                    │                     │                             │                               │
     │                    │                     │                             │                               ├───┐
     │                    │                     │                             │                               │   │ Asynchronously
     │                    │                     │                             │                               ◀───┘ evaluates
     │                    │                     │                             │                               │     VerificationData
     │                    │                     │                             │                               │
     │                    │                     │                             │                               │
     │                    │                 ┌opt [11.1. Additional Verification]──────────────────────────────────┐
     │                    │                 │   |                             │                               │   │
     │                    │                 │   │                             │    'verification/notify':     │   │
     │                    │                 │   │                             │   ADDITIONAL_INFO_REQUIRED    │   │
     │                    │                 │   │                             ◀───────────────────────────────│   │
     │                    │                 │   │                             │                               │   │
     │                    │                 │   │      Sends additional       │                               │   │
     │                    │                 │   │      Signed/Encrypted       │                               │   │
     │                    │                 │   │      VerificationData       │                               │   │
     │                    │                 │   │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │   │
     │                    │                 │   │                             │                               │   │
     │                    │                 │   │                             │  'verification/supplement':   │   │
     │                    │                 │   │                             │          additional           │   │
     │                    │                 │   │                             │       VerificationData        │   │
     │                    │                 │   │                             │───────────────────────────────▶   │
     │                    │                 │   │                             │                               │   │
     │                    │                 └─────────────────────────────────────────────────────────────────────┘
     │                    │                     │                             │                               │
     │                    │                     │                             │                               ├───┐
     │                    │                     │                             │                               │   │ Updates
     │                    │                     │                             │                               │   │ Verification
     │                    │                     │                             │                               ◀───┘ Status
     │                    │                     │                             │                               │
     │                    │                     │                             │              12.              │
     │                    │                     │                             │    'verification/notify':     │
     │                    │                     │                             │        APPROVED/DENIED        │
     │                    │                     │                             ◀───────────────────────────────│
     │                    │                     │                             │                               │
┌────┴───┐     ┌──────────┴─────────┐   ┌───────┴───────┐             ┌───────┴───────┐               ┌───────┴───────┐
│ Holder │     │ Issuer App/Website │   │ Wallet Client │             │ Wallet Server │               │ Issuer Server │
└────────┘     └────────────────────┘   └───────────────┘             └───────────────┘               └───────────────┘
  1. Holder interacts with an Issuer App/Website but is not authenticated.
  2. The Issuer App/Website pushes the Credential Offer payload to the Wallet Client.
  3. The Wallet Client generates a WSK and initiates a session via the Wallet Server.
  4. The Wallet Server calls verification/initiate on the Issuer Server.
  5. The Issuer validates the verificationNonce and returns a status of ADDITIONAL_INFO_REQUIRED along with a VerificationDataRequest.
  6. The Wallet Server forwards the ADDITIONAL_INFO_REQUIRED status with the proofing requirements to the Wallet Client.
  7. The Wallet Client requests the VerificationData from the Holder.
  8. The Holder provides the VerificationData.
  9. The Wallet Client sends the Signed/Encrypted VerificationData to the Wallet Server.
  10. The Wallet Server calls verification/supplement on the Issuer Server.
  11. The Issuer decrypts and verifies the WSK signature, returns the PENDING status, and asynchronously verifies the VerificationData.

    1. Optionally: uses ADDITIONAL_INFO_REQUIRED to obtain more information.
  12. The Issuer updates the Verification Status based on the outcome and sends an APPROVED/DENIED notification to the Wallet Server.

A.5. Device Migration

┌────────┐      ┌───────────────────┐   ┌───────────────┐               ┌───────────────┐
│ Holder │      │ New Wallet Client │   │ Wallet Server │               │ Issuer Server │
└────┬───┘      └─────────┬─────────┘   └───────┬───────┘               └───────┬───────┘
     │                    │                     │                               │
     │  1. Sets up new    │                     │                               │
     │  Wallet Client &   │                     │                               │
     │     migrates       │                     │                               │
     │────────────────────▶                     │                               │
     │                    │                     │                               │
     │                    ├───┐                 │                               │
     │                    │   │ Generates WSK   │                               │
     │                    ◀───┘                 │                               │
     │                    │                     │                               │
     │                    │                     ├───┐                           │
     │                    │                     │   │ Identifies previous SessionId
     │                    │                     ◀───┘                           │
     │                    │                     │                               │
     │                    │                     │                               │
     │                    │                     │              2.               │
     │                    │                     │   'verification/initiate':    │
     │                    │                     │      (old SessionId, new      │
     │                    │                     │      SessionId, new WSK)      │
     │                    │                     │───────────────────────────────▶
     │                    │                     │                               │
     │                    │                     │                               ├───┐
     │                    │                     │                               │   │ Verifies relationship
     │                    │                     │                               ◀───┘  between instances
     │                    │                     │                               │
     │                    │                     │                               │
     │                    │                     │                               │
     │                ┌opt [2.1. Additional─────────────────────────────────────────┐
     │                │Verification]            │                               │   │
     │                │   │                     │    'verification/notify':     │   │
     │                │   │                     │   ADDITIONAL_INFO_REQUIRED    │   │
     │                │   │                     ◀───────────────────────────────│   │
     │                │   │                     │                               │   │
     │                │   │  Sends additional   │                               │   │
     │                │   │  Signed/Encrypted   │                               │   │
     │                │   │  VerificationData   │                               │   │
     │                │   │╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌▶                               │   │
     │                │   │                     │                               │   │
     │                │   │                     │  'verification/supplement':   │   │
     │                │   │                     │          additional           │   │
     │                │   │                     │       VerificationData        │   │
     │                │   │                     │───────────────────────────────▶   │
     │                │   │                     │                               │   │
     │                └─────────────────────────────────────────────────────────────┘
     │                    │                     │                               │
     │                    │                     │                               ├───┐
     │                    │                     │                               │   │ Approves new
     │                    │                     │                               ◀───┘ verification
     │                    │                     │                               │
     │                    │                     │                               │
     │                    │                     │              3.               │
     │                    │                     │    'verification/notify':     │
     │                    │                     │           APPROVED            │
     │                    │                     ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│
     │                    │                     │                               │
┌────┴───┐      ┌─────────┴─────────┐   ┌───────┴───────┐               ┌───────┴───────┐
│ Holder │      │ New Wallet Client │   │ Wallet Server │               │ Issuer Server │
└────────┘      └───────────────────┘   └───────────────┘               └───────────────┘
  1. Holder sets up a new Wallet Client Instance and wishes to migrate credentials from a previous instance. The Wallet Client generates a new WSK.
  2. The Wallet Server identifies the previous SessionId and calls 'verification/initiate' with the old SessionId, new SessionId, and new WSK. The Issuer verifies the relationship between the instances.

    1. Optionally: uses ADDITIONAL_INFO_REQUIRED to obtain more information from the Holder.
  3. The Issuer approves the new verification session and sends a notification with APPROVED.

Appendix B. Acknowledgements

We would like to thank Christian Bormann, George Fletcher, Martijn Haring, Hicham Lozi, Dima Postnikov, Kristina Yasuda, Rajvardhan S Deshmukh, David Zeuthen for their valuable feedback and contributions to this specification.

Appendix C. Notices

Copyright (c) 2026 The OpenID Foundation.

The OpenID Foundation (OIDF) grants to any Contributor, developer, implementer, or other interested party a non-exclusive, royalty free, worldwide copyright license to reproduce, prepare derivative works from, distribute, perform and display, this Implementers Draft, Final Specification, or Final Specification Incorporating Errata Corrections solely for the purposes of (i) developing specifications, and (ii) implementing Implementers Drafts, Final Specifications, and Final Specification Incorporating Errata Corrections based on such documents, provided that attribution be made to the OIDF as the source of the material, but that such attribution does not indicate an endorsement by the OIDF.

The technology described in this specification was made available from contributions from various sources, including members of the OpenID Foundation and others. Although the OpenID Foundation has taken steps to help ensure that the technology is available for distribution, it takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this specification or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any independent effort to identify any such rights. The OpenID Foundation and the contributors to this specification make no (and hereby expressly disclaim any) warranties (express, implied, or otherwise), including implied warranties of merchantability, non-infringement, fitness for a particular purpose, or title, related to this specification, and the entire risk as to implementing this specification is assumed by the implementer. The OpenID Intellectual Property Rights policy (found at openid.net) requires contributors to offer a patent promise not to assert certain patent claims against other contributors and against implementers. OpenID invites any interested party to bring to its attention any copyrights, patents, patent applications, or other proprietary rights that may cover technology that may be required to practice this specification.

Appendix D. Document History

[[ To be removed from the final specification ]]

-01

Author's Address

Gareth Oliver
Google