Skip to main content

OpenID4VC

Learn how to configure OpenID4VC.

Overview

OpenID for Verifiable Credentials (OID4VC) is a protocol specification that extends OpenID Connect to enable the secure issuance and presentation of Verifiable Credentials. Built on widely-adopted OpenID Connect infrastructure, it provides standardized flows for three key parties: issuers who create credentials, holders who receive and store them, and verifiers who request and validate credentials.

The protocol defines two primary interactions: the Credential Issuance flow, which governs how credentials are securely issued to holders, and the Verifiable Presentation flow, which enables holders to present their credentials to verifiers. OID4VC supports multiple credential formats, flexible authentication methods, and privacy-preserving selective disclosure capabilities, making it a versatile solution for digital credential ecosystems.

The two flows are split into separate standards: OpenID for Verifiable Credential Issuance (OID4VCI) and OpenID for Verifiable Presentations (OID4VP). This page explains how to configure OID4VC for issuance, holding and verification.

For the full list of supported options, check the configuration reference.

Issue with OID4VCI

To enable OID4VCI, ensure at least one instance of an OID4VCI draft is configured and enabled in the issuanceProtocol object of the configuration. See the reference for a complete reference of supported options.

Several components of OID4VCI can be set in the configuration:

  • Encryption key
  • Nonce block
  • Timelines for codes and tokens
  • Redirect URIs

Example configuration

Here's an example configuration with explanations below:

issuanceProtocol:
OPENID4VCI_DRAFT13:
display: "exchange.openid4vciDraft13"
order: 1
type: "OPENID4VCI_DRAFT13"
params:
public:
preAuthorizedCodeExpiresIn: 300
tokenExpiresIn: 86400
refreshExpiresIn: 7776000
redirectUri:
enabled: true
allowedSchemes: ["https"]
private:
encryption: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
OPENID4VCI_FINAL1:
display: exchange.openIdFinal1
order: 3
type: "OPENID4VCI_FINAL1"
params:
public:
preAuthorizedCodeExpiresIn: 300
tokenExpiresIn: 86400
refreshExpiresIn: 7776000
redirectUri:
enabled: true
allowedSchemes: ["https"]
private:
encryption: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
nonce:
signingKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
expiration: 300
leeway: 60

This configuration enables issuance using both the final version of OpenID4VCI and draft 13.

Encryption key

An encryption key must be set for each instance of OID4VCI. This key is used for creating tokens. See Required encryption keys for details on providing an encryption key.

Nonce block

Starting in v1.0, OpenID4VCI uses nonces for exchanges. Provide a symmetric key, an expiration, and a leeway.

Token and code expiration

Use the following parameters to configure elements of the pre-authorized code flow of OID4VCI:

  • preAuthorizedCodeExpiresIn: Controls how long, in seconds, a pre-authorized code remains valid for obtaining access tokens during the OpenID4VCI credential issuance flow. This window needs to be long enough for users to complete their wallet interaction, but short enough to minimize security risks.
  • tokenExpiresIn: Controls how long, in seconds, an access token remains valid for credential retrieval during the OpenID4VCI flow. This window must accommodate network latency, potential retry attempts, and your expected user interaction patterns.

Redirect URIs

URIs can be set for holders to be redirected to when they accept your credential offer. You must specify the allowed schemes. The redirect URI is then set on a per-credential basis during credential creation.

URL scheme

By default, all OpenID4VCI providers use openid-credential-offer as the URL scheme, as specified in the standard. You can set a custom scheme via the urlScheme configuration parameter if needed.

If you want to support multiple URL schemes simultaneously (for example, both the standard scheme and a custom one), configure one protocol instance for each URL scheme. You can then reference the specific instance at the API level during credential creation to use one scheme or the other.

Upgrading to version 1.0

If you already have instances configured for earlier drafts, you can add a new v1.0 instance alongside them.

The configuration for OpenID4VCI v1.0 follows the same structure as earlier drafts. However, v1.0 requires two additional elements:

  • Type field: Set type: "OPENID4VCI_FINAL1" to designate this instance as v1.0 compliant. This tells the system to route requests to your v1.0 provider implementation.
  • Nonce configuration: Configure nonce generation and validation with two settings:
    • nonce.signingKey: A symmetric key used to cryptographically sign the nonce
    • nonce.expiration: Time in seconds that the nonce remains valid
    • nonce.leeway: Time tolerance in seconds when validating nonce timestamps in OpenID4VCI flows

The nonce ensures that credential issuance requests are fresh and prevents replay attacks.

Use OID4VCI to issue ISO mdoc

For mdoc issuance, add the following parameter to your configuration:

  • refreshExpiresIn: Controls how long, in seconds, wallets can wait to renew their expired mdoc credentials without going through the full issuance process again. As long as the wallet requests a new token before this time has elapsed it will be reissued, assuming the credential has not been suspended or revoked. Consider your security requirements when setting this value - a longer window provides more convenience for users but increases the lifetime of the original issuance tokens.

The expiration duration of the mdoc credential itself is configured in credential format configuration.

Related guide: mdoc validity

Receive and present with OID4VC

A wallet needs both an issuance protocol and a verification protocol configured and enabled to receive credentials and share presentations.

Example configuration

Here's an example configuration, with explanations below:

issuanceProtocol:
OPENID4VCI_DRAFT13:
display: 'exchange.openid4vciDraft13'
order: 1
type: 'OPENID4VCI_DRAFT13'
OPENID4VCI_FINAL1:
display: 'exchange.openIdFinal1'
order: 2
type: 'OPENID4VCI_FINAL1'
verificationProtocol:
OPENID4VP_DRAFT20:
display: 'exchange.openid'
order: 1
type: 'OPENID4VP_DRAFT20'
params:
public:
holder:
supportedClientIdSchemes:
[
redirect_uri,
verifier_attestation,
did,
x509_san_dns,
]
OPENID4VP_DRAFT25:
display: 'exchange.openid4vp25'
order: 2
type: 'OPENID4VP_DRAFT25'
params:
public:
holder:
supportedClientIdSchemes:
[
redirect_uri,
verifier_attestation,
did,
x509_san_dns
]
OPENID4VP_FINAL1:
display: "exchange.openid4vpFinal1"
order: 3
type: "OPENID4VP_FINAL1"
params:
public:
holder:
supportedClientIdSchemes:
[
redirect_uri,
verifier_attestation,
decentralized_identifier, # replaces `did` from earlier drafts
x509_san_dns,
]

OID4VCI for wallets

To enable OID4VCI, ensure at least one instance of an OID4VCI draft is configured and enabled in the issuanceProtocol object of the configuration. See the reference for supported options.

Authorization Code Flow for wallets

To enable the issuer-initiated version of the Authorization Code Flow, you need to specify a credentialIssuer object in your configuration. This lets you specify the client ID the wallet should use for a given issuer:

credentialIssuer:
EUDI_PID_FLOW:
display:
en: EUDI Issuer
de: EUDI Issuer
order: 1
enabled: true
params:
public:
logo: ...
issuer: https://issuer.eudiw.dev
private:
clientId: my-wallet-id

Create a new entry for each issuer you want to accept credential offers from.

URL scheme

By default, the wallet uses openid-credential-offer as the URL scheme for receiving credential offers, as specified in the OpenID4VCI standard.

To handle a custom URL scheme, create an issuance protocol instance and specify the scheme in the configuration. The wallet will automatically look for a provider that can handle that scheme when processing incoming credential offers.

OID4VP for wallets

To enable OID4VP, ensure at least one instance of an OID4VP draft is configured and enabled in the verificationProtocol object of the configuration. See the reference for a complete reference of supported options.

Client Identifier Schemes for wallets

Client Identifier Schemes (also known as "Client Identifier Prefixes") define how the wallet validates the authenticity of verifiers during presentation exchanges. When a verifier sends a proof request, the scheme determines how the wallet should interpret the verifier's identity and verify that the request is legitimate.

Different schemes provide different levels of trust assurance. For example, redirect_uri provides no cryptographic verification of the verifier's identity, while x509_san_dns requires the verifier to prove control of a domain through certificate validation.

Use the holder.supportedClientIdSchemes parameter to specify which schemes the wallet accepts. The wallet will reject proof requests from verifiers using schemes not in this list.

note

For a reference of all supported client ID schemes, see the verification protocols configuration reference.

Use OID4VP to present ISO mdoc

Wallets can be configured to present and exchange ISO mdocs using OID4VP. A few configurations need to be set to enable this:

  • Set the URL scheme
  • Define the accepted CA certificates
  • Set the Client Identifier Scheme

Because of these differences, it is recommended to configure a second instance of the relevant OID4VP verification protocol. This allows the wallet to parse incoming proof requests by their URL scheme and then use the appropriate flavor of OID4VP for the exchange.

Here's an example configuration, with explanations below:

verificationProtocol:
MDOC_OPENID4VP:
display: "exchange.mdocOpenid"
order: 2
type: "OPENID4VP_DRAFT20"
params:
public:
urlScheme: mdoc-openid4vp # Flag this instance of OID4VC to be used when this URL scheme is encountered
holder:
supportedClientIdSchemes: [x509_san_dns] # Use the Client Identifier Scheme supported by the standard

URL scheme

By default instances of OID4VP use openid4vp as the URL scheme, to follow the OID4VP standard. You can change the URL scheme via the urlScheme parameter. For the mdoc flavor of OID4VP we use mdoc-openid4vp as the URL scheme, to follow the ISO 18013-7 standard.

Client Identifier Scheme for ISO mdoc holding

The 18013-7 standard specifies the use of x509_san_dns as the Client Identifier Scheme for mdoc exchange. Set this as the only supported scheme for presenting mdocs.

Verify with OID4VP

To enable OID4VP, ensure at least one instance of an OID4VP draft is configured and enabled in the verificationProtocol object of the configuration. See the reference for supported options.

Several components of OID4VP can be set in the configuration:

  • Request URI enabling
  • Client Identifier Schemes
  • Redirect URI

Example configuration

Here's an example configuration, with explanations below:

verificationProtocol:
OPENID4VP_DRAFT25:
display: 'exchange.openid4vp25'
order: 1
type: 'OPENID4VP_DRAFT25'
params:
public:
useRequestUri: true
verifier:
useDcql: true
supportedClientIdSchemes:
[
redirect_uri,
verifier_attestation,
did,
x509_san_dns,
]
redirectUri:
enabled: true
allowedSchemes: ['https']
OPENID4VP_FINAL1:
display: "exchange.openid4vpFinal1"
order: 2
type: "OPENID4VP_FINAL1"
params:
public:
useRequestUri: true
verifier:
supportedClientIdSchemes:
[
verifier_attestation,
redirect_uri,
decentralized_identifier, # replaces `did` from previous drafts
x509_san_dns,
]
redirectUri:
enabled: true
allowedSchemes: ["https"]

Request URI

When you create a proof request, a URI is generated. This URI can either contain the complete proof request information within it, or it can contain a request URI instead. If it contains a request URI, the wallet must make an HTTP request to fetch the complete proof request information.

Set to true if:

  • The proof request will be shared as a QR code. Using a request URI shortens the URL significantly, making it more suitable for use with a QR code.

Set to false if:

  • The proof request is small and will be shared as a hyperlink.

Query languages (DCQL)

OpenID4VP uses a query language to define which credentials and claims are requested from the holder; this language specifies how the verifier describes what they are requesting and facilitates the wallet in searching through credentials to find suitable responses.

Presentation Exchange vs. DCQL

Early drafts of OpenID4VP adopt "Presentation Exchange 2.0" from the Decentralized Identity Foundation (DIF). Starting in Draft 22, OpenID4VP defines a new query language: Digital Credentials Query Language, or "DCQL" (pronounced "DOCK-uhl"). With the publication of Draft 26, Presentation Exchange is no longer supported and DCQL must be used to be compliant with the specification.

OpenID4VP versionSystem query language
OPENID4VP_DRAFT20Presentation Exchange
OPENID4VP_DRAFT25DCQL (default)
or
Presentation Exchange
OPENID4VP_FINAL1
and after
DCQL

If you need to use Presentation Exchange with Draft 25 for interoperability reasons, set useDcql to false:

verificationProtocol:
OPENID4VP_DRAFT25:
display: "exchange.openid4vp25"
order: 3
type: "OPENID4VP_DRAFT25"
params:
public:
useRequestUri: true
verifier:
useDcql: false

DCQL implementation details

The system implements DCQL as defined in OpenID4VP Draft 29 and supports the following credential formats:

  • IETF SD-JWT VCs, filtered by vct
  • ISO 18013 mdocs, filtered by doctype
  • W3C JSON-LD & JWT VCs, filtered by type

Supported DCQL features:

Claim sets
  • Wallet: can parse an OR-list defining acceptable combinations of claims
  • Verifier: generates an OR-list defining acceptable combinations of claims derived from your choices of what is and what is not required
multiple flag
  • Wallet: can submit multiple credentials for the same query (for example, multiple PIDs for one request)
  • Verifier: can parse multiple credentials when submitted but cannot set a multiple flag using the API
Filter by claim values
  • Wallet: can parse verifier requests for credentials where a specific claim matches any of the values in a list
  • Verifier: can parse values flag when submitted but cannot filter by claims value using the API
Require cryptographic
binding flag
  • Wallet: can submit a raw credential (as opposed to a signed presentation) when the verifier's request sets this flag to false
  • Verifier: by default sets this value to true (and thus always requires a signed presentation) but can parse and validate raw credentials
Array selection
  • Wallet: can submit individual items within arrays when requested
  • Verifier: can parse individual items in an array but when creating proof schemas can only select an array in its entirety

Unsupported DCQL features

  • credential_sets: setting logical combinations of accepted credentials
  • trusted_authorities: issuer trust anchors

Client Identifier Schemes for verifiers

Client Identifier Schemes (also known as "Client Identifier Prefixes") define how wallets validate the authenticity of your verification requests. When you send a proof request, the scheme you use determines how the wallet verifies that the request is legitimate and actually comes from you.

Different schemes provide different levels of trust assurance. For example, redirect_uri provides no cryptographic verification of your identity, while x509_san_dns requires you to prove control of a domain through certificate validation.

Use verifier.supportedClientIdSchemes to specify which schemes your system supports. For any given interaction, you can choose which scheme to use by passing the clientIdScheme parameter when creating the share URL. If no scheme is specified, the system selects the first compatible scheme from your list.

note

For a reference of all supported client ID schemes, see the verification protocols configuration reference.

Redirect URI

URIs can be set for holders to be redirected to when they accept your proof request. You must specify the allowed schemes. The redirect URI is then set on a per-proof request basis during the proof request creation process.

Use OID4VP to verify ISO mdoc

The system can be configured to verify ISO mdocs using OID4VP. A few configurations need to be set to enable this:

  • Set the URL scheme
  • Set the Client Identifier Scheme
  • Set the redirect URI (if desired)

Because of these differences, it is recommended to configure a second instance of the relevant OID4VP verification protocol. These settings enable wallets to parse incoming requests and use the appropriate flavor of OID4VP for the exchange.

Here's an example configuration, with explanations below:

MDOC_OPENID4VP:
display: 'exchange.mdocOpenid'
order: 2
type: 'OPENID4VP_DRAFT20'
params:
public:
useRequestUri: true
urlScheme: mdoc-openid4vp
verifier:
supportedClientIdSchemes: [x509_san_dns]
redirectUri:
enabled: true
allowedSchemes: ['https']

URL scheme

By default instances of OID4VP use openid4vp as the URL scheme, to follow the OID4VP standard. You can change the URL scheme via the urlScheme parameter. For the mdoc flavor of OID4VP we use mdoc-openid4vp as the URL scheme, to follow the ISO 18013-7 standard.

Client Identifier Scheme for ISO mdoc verification

The 18013-7 standard specifies the use of x509_san_dns as the Client Identifier Scheme for mdoc exchange. Set this as the only supported scheme for verifying mdocs.

Redirect URI

If you configure a second instance of OID4VP for ISO mdocs, be sure to set your redirect preferences and schemes.