OID4VCI Holder Service
The OID4VCI Holder service provides wallet-side endpoints for acquiring credentials. It acts as a backend-for-frontend service: a mobile wallet or web wallet calls these endpoints to orchestrate the entire issuance flow without implementing the OID4VCI protocol directly. The service handles offer parsing, issuer metadata resolution, token exchange, proof creation, credential requests, and deferred polling.
Holder (Wallet) Endpoints
| Method | Path | Description |
|---|---|---|
POST | /sessions | Create a new issuance session from a credential offer URI. Parses the openid-credential-offer:// URI, fetches the issuer's metadata from its .well-known endpoint, and returns a session object with resolved metadata, available credentials, and grant information. |
POST | /auth/code | Exchange an authorization code for tokens. Used after the user authenticates through the authorization code flow. Accepts the code, PKCE code verifier, and redirect URI. Returns an access token and optional c_nonce. |
POST | /auth/pre-authorized | Exchange a pre-authorized code for tokens. Used when the issuer provides a pre-authorized code grant. Accepts the code and optional transaction code (PIN). Returns an access token and optional c_nonce. |
POST | /credentials | Request a credential from the issuer. Builds the proof-of-possession JWT, sends the credential request to the issuer's credential endpoint, and returns either the issued credential or a transactionId for deferred issuance. |
POST | /nonce | Request a fresh c_nonce from the issuer's nonce endpoint. Typically called automatically when autoRequestNonce is enabled, but available as an explicit endpoint for flows that need manual nonce management. |
POST | /auth/request | Build an authorization request URL for the authorization code flow. Returns the URL the wallet should open in a browser, along with the PKCE code verifier to store for the token exchange step. |
Including in Your Server
dependencies {
implementation("com.sphereon.idk:services-oid4vci-holder-rest:0.25.0")
}
Configuration
The holder service is configured through Oid4vciHolderConfig:
| Property | Default | Description |
|---|---|---|
clientId | null | OAuth 2.0 client identifier sent in token requests |
preferredFormat | null | Preferred credential format (e.g., dc+sd-jwt, mso_mdoc) |
autoRequestNonce | true | Automatically fetch a c_nonce before creating proofs |
defaultDeferredPollingInterval | 5 | Seconds between deferred credential polling attempts |
maxDeferredPollingAttempts | 60 | Maximum polling attempts before giving up |
requireVerifiedSignedMetadata | false | Require cryptographic verification of signed issuer metadata |
When requireVerifiedSignedMetadata is enabled, the holder rejects issuer metadata with an invalid or missing signature. This is recommended for production wallets that need to verify issuer authenticity.
See OID4VCI Holder for the full guide, including authorization code flow, pre-authorized code flow, IAE (Interactive Authorization Exchange), deferred polling, and notification handling.
Docker
Each service ships with a Dockerfile and docker-compose configuration in its container/ directory.
Building the image
# Build the fat JAR first
./gradlew :services-oid4vci-holder-rest:buildFatJar
# Build the Docker image
docker compose -f services/oid4vci-holder/container/docker-compose.yaml build
Running with Docker Compose
docker compose -f services/oid4vci-holder/container/docker-compose.yaml up
The service starts on port 8080. Configuration is loaded from container/config/ inside the image. Override settings via environment variables in a .env file next to the docker-compose.yaml.
Image details
| Property | Value |
|---|---|
| Base image | eclipse-temurin:21-jre |
| Docker image | sphereon/idk-oid4vci-holder:latest |
| Exposed port | 8080 |
| Config location | /app/config/ |
Next Steps
- Services Overview for an introduction to all available IDK services and the
CommandBackedHttpAdapterpattern - OID4VCI Holder Guide for the full guide on authorization code flow, pre-authorized code flow, and deferred polling
- OID4VCI Issuer for the holder-facing issuer endpoints and issuer-side integration surface
- Ktor Integration for details on installing and configuring the
KotlinInjectPlugin