Skip to main content
Version: v0.13

OpenID for Verifiable Presentations

OpenID for Verifiable Presentations (OID4VP) is a protocol that enables the presentation of verifiable credentials over the internet. The IDK implements OID4VP 1.0 Final with DCQL (Digital Credentials Query Language) for credential requests.

What is OID4VP?

OID4VP extends OAuth 2.0 to support the presentation of verifiable credentials. It allows a holder to present credentials from their digital wallet to a verifier in a standardized, interoperable way. The protocol supports multiple credential formats including ISO mDoc, SD-JWT VC, and W3C Verifiable Credentials.

The protocol defines two primary roles:

RoleDescription
HolderThe entity possessing credentials in a wallet application
VerifierThe relying party requesting and validating credential presentations

Protocol Flow

A typical OID4VP presentation follows these steps:

OID4VP Protocol Flow

Request Modes

OID4VP supports multiple ways to deliver the authorization request:

Same-Device Flow

The authorization request is delivered directly via a URL or deep link. This is common when the user is already on a mobile device with their wallet app.

Cross-Device Flow

The authorization request is encoded in a QR code displayed by the verifier. The user scans this with their wallet app, creating a bridge between the verifier's session and the mobile wallet.

Request URI

Instead of embedding the full request in the URL, the verifier provides a request_uri pointing to the full request object. This keeps URLs short and allows for signed request objects.

Credential Formats

The IDK supports multiple credential formats within OID4VP:

FormatDescription
mso_mdocISO/IEC 18013-5 mobile driving license format
dc+sd-jwtSD-JWT based verifiable credentials
jwt_vc_jsonJWT-encoded W3C Verifiable Presentations

DCQL Queries

The verifier specifies what credentials it needs using DCQL (Digital Credentials Query Language). DCQL provides a structured way to describe:

  • Required credential types and formats
  • Specific claims/attributes needed
  • Which claims are required versus optional
  • Alternative credentials that can satisfy a requirement

See the DCQL documentation for detailed query syntax and examples.

Response Modes

OID4VP supports different response delivery mechanisms:

Response ModeDescription
direct_postResponse POSTed to verifier's endpoint (recommended)
direct_post.jwtJWT-secured response POSTed to verifier
fragmentResponse in URL fragment
queryResponse in URL query parameters

The direct_post mode is recommended for production as it provides better security and supports larger payloads.

Core Components

// Holder-side component for wallet operations
val holder: Oid4vpHolder = session.component.oid4vpHolder

// Verifier-side component for relying party operations
val rp: Oid4vpRpService = session.component.oid4vpRpService

Holder Operations

The holder processes authorization requests from verifiers:

// 1. Parse authorization request from QR or deep link
val parseResult = holder.parseAuthorizationRequest(
requestUri = "openid4vp://authorize?...",
walletConfig = WalletConfig(audience = "https://wallet.example.com")
)

// 2. Resolve request (fetch metadata, validate client)
val resolveResult = holder.resolveAuthorizationRequest(parseResult.value)

// 3. Create response with selected credentials
val responseResult = holder.createAuthorizationResponse(
request = resolveResult.value,
selectedCredentials = selectedCredentials
)

// 4. Submit response to verifier
val submitResult = holder.submitAuthorizationResponse(
resolvedRequest = resolveResult.value,
response = responseResult.value
)

Verifier Operations

The verifier creates requests and validates responses:

// 1. Create authorization request with DCQL query
val createResult = rp.createAuthorizationRequest(
CreateAuthorizationRequestArgs(
dcqlQuery = dcqlQuery,
clientId = "https://verifier.example.com",
responseUri = "https://verifier.example.com/response",
responseMode = ResponseMode.DIRECT_POST,
nonce = generateNonce()
)
)

// 2. Build URI for QR code or redirect
val uriResult = rp.buildAuthorizationRequestUri(
BuildAuthorizationRequestUriArgs(
request = createResult.value.request,
scheme = Oid4vpUriScheme.OPENID4VP
)
)

// 3. Parse incoming response
val parseResult = rp.parseAuthorizationResponse(parseArgs)

// 4. Validate response against request
val validateResult = rp.validateAuthorizationResponse(validateArgs)

// 5. Verify holder binding
val bindingResult = rp.verifyHolderBinding(bindingArgs)

Client ID Schemes

OID4VP supports multiple ways for verifiers to identify themselves:

SchemeDescription
redirect_uriClient ID equals the response URI
x509_san_dnsX.509 certificate with DNS SAN
x509_san_uriX.509 certificate with URI SAN
verifier_attestationAttestation JWT from trusted party
decentralized_identifierDID-based identity
openid_federationOpenID Federation entity

Security Features

OID4VP in the IDK includes several security mechanisms:

Request Object Signing ensures the authorization request hasn't been tampered with. The holder validates the signature against the verifier's published keys.

Response Encryption protects the presented credentials from interception when using direct_post.jwt mode.

Client ID Scheme Validation verifies the verifier's identity according to the declared scheme.

Nonce Binding prevents replay attacks by binding the presentation to a specific transaction.

Response Code Protection for direct_post mode prevents response theft via one-time codes.

Next Steps