OpenID for Verifiable Credential Issuance
OpenID for Verifiable Credential Issuance (OID4VCI) is a protocol that enables the issuance of verifiable credentials from a credential issuer to a holder's wallet. The IDK implements OID4VCI with support for both the pre-authorized code flow and the authorization code flow, covering immediate and deferred credential issuance.
What is OID4VCI?
Where OID4VP handles presenting credentials to a verifier, OID4VCI handles the other side of the lifecycle: obtaining credentials in the first place. OID4VCI extends OAuth 2.0 with a credential issuance layer, allowing issuers to publish what credentials they offer through discoverable metadata, and wallets to request those credentials through a standardized protocol.
The protocol supports multiple credential formats, proof-of-possession mechanisms, and grant types, making it suitable for a wide range of issuance scenarios from government-issued identity documents to organizational membership cards.
The protocol uses the same role terminology as the broader verifiable credentials ecosystem:
| Role | Description |
|---|---|
| Issuer | The entity that creates and signs verifiable credentials |
| Holder (Wallet) | The entity that requests, receives, and stores credentials |
| Authorization Server | The OAuth 2.0 server that authenticates the holder and issues access tokens |
Together with OID4VP, this creates the complete credential lifecycle: Issuer → Holder → Verifier.
Protocol Flow
The most common OID4VCI flow uses a pre-authorized code, where the issuer initiates the process by creating a credential offer:
The flow begins when the issuer creates a credential offer and delivers it to the wallet, typically via a QR code or deep link. The wallet fetches the issuer's metadata to understand what credentials are available and how to request them, then exchanges the pre-authorized code for an access token. With the token, the wallet creates a proof of possession and requests the credential. The issuer responds with the credential immediately or provides a transaction ID for deferred retrieval.
Grant Types
OID4VCI supports two OAuth 2.0 grant types for obtaining access tokens:
Pre-Authorized Code
The issuer initiates the flow by generating a credential offer that includes a pre-authorized code. This is useful when the issuer has already authenticated the holder through an out-of-band process (e.g., in-person verification, existing account login). The offer may optionally require a transaction code (PIN) as an additional security measure.
Authorization Code
The wallet directs the holder to the authorization server for authentication. This follows the standard OAuth 2.0 authorization code flow with PKCE, making it suitable for scenarios where the holder needs to authenticate directly with the authorization server. The wallet builds an authorization URL, the user authenticates, and the wallet exchanges the resulting code for an access token.
Interactive Authorization Exchange (IAE)
IAE is an OID4VCI 1.1 extension that adds an interactive verification step to the authorization process. Before issuing an authorization code, the authorization server can challenge the holder to perform an additional action, typically presenting an existing credential via OID4VP.
This enables a "present-to-obtain" pattern: for example, a holder might need to present their national ID credential to receive a university degree credential. The issuer configures which interaction type and DCQL query to use per credential configuration. See the Holder and Issuer documentation for implementation details.
Architecture
The IDK's OID4VCI implementation is split into three modules:
The Holder module provides wallet-side functionality: parsing credential offers, exchanging tokens, creating proofs, requesting credentials, and handling deferred issuance with automatic polling.
The Issuer module provides server-side functionality: creating credential offers, publishing metadata, issuing nonces, handling credential requests, and managing deferred credentials. It uses an extensible format handler system to support multiple credential formats and can be configured through a Kotlin DSL or external configuration (YAML/environment variables).
The Common module contains shared data models and the metadata DSL used by both sides: credential offers, requests, responses, issuer metadata definitions, and DSL builders for constructing metadata programmatically.
Credential Formats
The IDK supports multiple credential formats within OID4VCI:
| Format | Description |
|---|---|
jwt_vc_json | JWT-encoded W3C Verifiable Credentials |
mso_mdoc | ISO/IEC 18013-5 mobile document format |
dc+sd-jwt | SD-JWT based verifiable credentials with selective disclosure |
The issuer declares supported formats in its metadata, and the holder specifies the desired format when requesting a credential. Each format has its own CredentialFormatHandler on the issuer side, making it straightforward to add support for additional formats.
Proof of Possession
When requesting a credential, the holder must prove it controls the key that the credential should be bound to. OID4VCI supports several proof types:
| Proof Type | Description |
|---|---|
jwt | JWT signed with the holder's key, containing the issuer URL and a nonce |
cwt | CBOR Web Token proof (for constrained environments) |
attestation | Attestation-based proof from a trusted entity |
The proof includes a c_nonce (credential nonce) provided by the issuer, which prevents replay attacks and ensures freshness. The IDK's holder automatically manages nonce acquisition when autoRequestNonce is enabled.
Deferred Issuance
Not all credentials can be issued immediately. The issuer may need time for background checks, manual approval, or asynchronous signing. OID4VCI handles this through deferred issuance:
- The issuer returns a
transaction_idinstead of a credential - The holder polls the deferred credential endpoint at a configured interval
- When the credential is ready, the issuer returns it in the polling response
The IDK holder includes a built-in polling orchestrator with configurable retry intervals and maximum attempts, so wallet developers don't need to implement polling logic manually.
Notifications
After receiving a credential, the holder can notify the issuer about the outcome. This is useful for the issuer to track issuance success rates and handle failure cases:
| Event | Description |
|---|---|
credential_accepted | The holder successfully stored the credential |
credential_failure | The holder encountered an error processing the credential |
credential_deleted | The holder deleted the credential from their wallet |
Security Features
OID4VCI in the IDK includes several security mechanisms:
Proof of Possession ensures the credential is bound to a key the holder controls. The issuer validates the proof signature and nonce before issuing the credential.
Transaction Codes provide an additional layer of security for pre-authorized code flows. The issuer can require the holder to enter a PIN or code received through a separate channel.
Signed Issuer Metadata allows the issuer to sign its metadata as a JWT, enabling holders to verify the metadata hasn't been tampered with.
DPoP (Demonstrating Proof-of-Possession) binds access tokens to the holder's key, preventing token theft and replay.
Credential Response Encryption allows the holder to request that the credential response be encrypted, protecting the credential in transit.
Core Components
- Android/Kotlin
- iOS/Swift
// Holder-side component for wallet operations
val holder: Oid4vciHolderService = session.graph.oid4vciHolderService
// Issuer-side component for credential provider operations
val issuer: Oid4vciIssuerService = session.graph.oid4vciIssuerService
// Holder-side component for wallet operations
let holder: Oid4vciHolderService = session.graph.oid4vciHolderService
// Issuer-side component for credential provider operations
let issuer: Oid4vciIssuerService = session.graph.oid4vciIssuerService
Next Steps
- Holder Implementation: Build wallet functionality for obtaining credentials
- Issuer Implementation: Create credential issuance services