OID4VPPresentation Flows

Presentation Flows

OID4VP supports multiple presentation flows to accommodate different verification scenarios. The choice of flow depends on whether the wallet and verifier are on the same device and who initiates the interaction.

Flow Comparison

Optional
Type:

Optional
Type:

Optional
Type:

Same-Device Flow

In the same-device flow, both the relying party application and wallet are on the same device (typically mobile). The verifier triggers the wallet using a custom URL scheme or universal link.

Custom Scheme

openid4vp:// is the standard custom URL scheme. Wallets register to handle this scheme on the device.

Requires wallet app to be installed. May show app chooser if multiple wallets are registered.

Universal Links

Uses HTTPS URLs that wallets claim via apple-app-site-association (iOS) or assetlinks.json (Android).

More reliable and secure. Falls back to browser if wallet not installed.

Deep Link Examples

// iOS/Android Deep Link handling
// Custom scheme
openid4vp://authorize?
  response_type=vp_token
  &client_id=https://verifier.example.com
  &response_mode=direct_post
  &response_uri=https://verifier.example.com/callback
  &nonce=n-0S6_WzA2Mj
  &presentation_definition_uri=https://verifier.example.com/pd/age-check

// Universal Link (iOS) / App Link (Android)
https://wallet.example/verify?
  request_uri=https://verifier.example.com/request/xyz789

Cross-Device Flow

The cross-device flow handles scenarios where the user is browsing on one device (e.g., desktop) but their wallet is on another (e.g., mobile phone). A QR code bridges the gap.

QR Code Content

The QR code contains the authorization request, typically using request_uri to keep the QR code small and scannable.

// QR Code Content (Cross-Device)
openid4vp://authorize?
  request_uri=https://verifier.example.com/request/abc123
  &client_id=https://verifier.example.com

// Or using Universal Links
https://wallet.example/.well-known/openid4vp?
  request_uri=https://verifier.example.com/request/abc123
  &client_id=https://verifier.example.com

Session Synchronization

The browser session doesn't automatically know when the mobile wallet completes the presentation. Common approaches:

  • WebSocket: Real-time push notification
  • Server-Sent Events (SSE): One-way push
  • Polling: Periodic status checks (fallback)

Session Status Polling

// Verifier backend: Check presentation status
GET /presentation-status/abc123 HTTP/1.1
Host: verifier.example.com
Authorization: Bearer session-token

// Response (pending)
{
  "status": "pending",
  "expires_at": "2024-01-15T10:05:00Z"
}

// Response (completed)
{
  "status": "completed",
  "vp_token_hash": "sha256:abc123...",
  "verified_claims": {
    "age_over_21": true
  }
}

Wallet-Initiated Flow

In the wallet-initiated flow, the user proactively shares a credential from their wallet. The wallet discovers compatible verifiers and initiates the presentation without a prior request.

Use Cases

  • Proactively sharing proof of age at a venue
  • Presenting membership credentials at a facility
  • Sharing professional certifications with employers
  • Self-service credential verification kiosks

Wallet Metadata

Wallets can advertise their capabilities through metadata, enabling verifiers to craft compatible requests.

// Wallet metadata for discovery
{
  "authorization_endpoint": "openid4vp://authorize",
  "response_types_supported": ["vp_token"],
  "response_modes_supported": ["direct_post", "direct_post.jwt"],
  "vp_formats_supported": {
    "jwt_vp_json": {
      "alg_values_supported": ["ES256", "EdDSA"]
    },
    "mso_mdoc": {
      "alg_values_supported": ["ES256"]
    }
  },
  "request_object_signing_alg_values_supported": ["ES256", "EdDSA"]
}

Security Considerations

Same-Device Security

Cross-Device Security

Wallet-Initiated Security