Skip to content

Responses and vp_token

An OpenID4VP authorization response returns the requested verifiable presentations. The key parameter is vp_token.

The response uses vp_token to return one or more verifiable presentations.

For direct_post response modes, the wallet sends an HTTPS POST to the verifier’s response_uri.

The POST body can contain:

  • A successful response with vp_token
  • An error response with error and error_description

When the verifier configures a redirect_uri, Vidos appends a one-time response_code (opaque random identifier) to that redirect URL after the wallet submission is processed.

https://verifier.example/callback?response_code=<random-id>

The client application forwards this code to the verifier backend, and the backend exchanges it with the authorizer using POST /openid4/vp/v1_0/response-code/resolve.

The response_code pattern helps cross-device flows complete safely without exposing long-lived authorization identifiers in browser redirects.

sequenceDiagram
    participant Wallet
    participant Authorizer
    participant Browser
    participant ClientApp as Client application
    participant VerifierBackend as Verifier backend

    Wallet->>Authorizer: POST direct_post (vp_token or error)
    Authorizer-->>Wallet: redirect_uri?response_code=...
    Wallet->>Browser: Open redirect_uri
    Browser->>ClientApp: Load callback route with response_code
    ClientApp->>VerifierBackend: Send response_code
    VerifierBackend->>Authorizer: POST /openid4/vp/v1_0/response-code/resolve
    Authorizer-->>VerifierBackend: { authorization_id, status }

OpenID4VP section 14.2 describes a session fixation risk for cross-device flows. A short-lived, single-use response_code mitigates that risk by proving the browser redirect is correlated with the wallet submission context. In Vidos, each code is invalid after first resolution and expires after five minutes.

When the request uses DCQL, vp_token is a JSON object mapping credential query identifiers to one or more verifiable presentations that satisfy each query.

Example (shape only):

{
"state": "af0ifjsldkj",
"vp_token": {
"photo_id": ["<presentation-1>", "<presentation-2>"]
}
}

In direct_post.jwt, the wallet returns an encrypted JWT response.

In Vidos’ Authorizer implementation, the encrypted response is received as:

{ "response": "<jwe>" }

The Authorizer decrypts the JWE using the request’s nonce, validates the decrypted payload against the expected response schema, and then processes vp_token.

Vidos validates OpenID4VP direct-post responses:

  • Successful responses use the DCQL vp_token mapping shape.
  • Error responses use error and optional error_description.

Vidos also enforces correlation checks:

  • The callback URL must match the expected request URL.
  • If state is present, it must match the authorization record.