Skip to main content
Version: v0.25.0 (Latest)

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

MethodPathDescription
POST/sessionsCreate 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/codeExchange 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-authorizedExchange 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/credentialsRequest 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/nonceRequest 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/requestBuild 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

build.gradle.kts
dependencies {
implementation("com.sphereon.idk:services-oid4vci-holder-rest:0.25.0")
}

Configuration

The holder service is configured through Oid4vciHolderConfig:

PropertyDefaultDescription
clientIdnullOAuth 2.0 client identifier sent in token requests
preferredFormatnullPreferred credential format (e.g., dc+sd-jwt, mso_mdoc)
autoRequestNoncetrueAutomatically fetch a c_nonce before creating proofs
defaultDeferredPollingInterval5Seconds between deferred credential polling attempts
maxDeferredPollingAttempts60Maximum polling attempts before giving up
requireVerifiedSignedMetadatafalseRequire 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

PropertyValue
Base imageeclipse-temurin:21-jre
Docker imagesphereon/idk-oid4vci-holder:latest
Exposed port8080
Config location/app/config/

Next Steps

  • Services Overview for an introduction to all available IDK services and the CommandBackedHttpAdapter pattern
  • 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