Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ISO/IEC 18013-7 — mDoc Online Presentation

This reference covers ISO/IEC 18013-7, the standard for presenting mobile driving licences (mDLs) and generic mDocs over the internet, and its relationship with the OpenID4VP profiles used in the EUDI ecosystem.


Overview

ISO/IEC 18013-7 extends the proximity-based protocols of ISO/IEC 18013-5 to remote presentation over the internet. It defines three annexes, each with a different transport and invocation mechanism:

AnnexNameTransportWallet Adoption
Annex AREST API (Device Retrieval)HTTP POST with raw CBOR❌ None of the major EUDI wallets
Annex BOpenID4VP (Online Presentation)openid4vp:// URIs, direct_post✅ All major EUDI wallets
Annex CW3C Digital Credentials APInavigator.credentials.get()✅ All major EUDI wallets

Terminology note: In the France Identité ecosystem and other national mDL deployments, “ISO 18013-7 (Annex B)” is used as an umbrella term for the entire online mDoc presentation flow. Annex C defines the ["dcapi", ...] CBOR wrapper that carries the DeviceRequest/DeviceResponse inside the browser API — it is the encoding layer, not a standalone profile.


Annex A: REST API (Device Retrieval)

Pure HTTP-based remote device retrieval: the verifier sends a CBOR-encoded DeviceRequest via HTTP POST to a wallet endpoint or proxy server, and receives a CBOR DeviceResponse in the HTTP response.

AspectDetail
InvocationHTTP POST directly to wallet endpoint or proxy
RequestCBOR DeviceRequest (ISO 18013-5)
ResponseCBOR DeviceResponse
EncryptionNetwork-layer session encryption (no standardised protocol)
TrustNo global trust list; verifier authenticates via TLS
Developer impactRequires CBOR parsing, COSE cryptography, and session key establishment at network layer
Wallet supportNone — France Identité, EUDI Wallet DE, IT Wallet, Spanish EUDIW do not implement Annex A

Implementation status in ewQwe: ❌ Not implemented. No wallet supports Annex A; the standard is not used by any major EUDI wallet.


Annex B: OpenID4VP (Online Presentation)

Standardises mDoc presentation over the OAuth 2.0 / OpenID Connect framework. The verifier acts as an OAuth 2.0 client, building an Authorization Request URI that the wallet processes.

Flow

sequenceDiagram
    participant RP as Relying Party
    participant Wallet as Wallet

    RP->>Wallet: openid4vp:// URI (QR / link)<br/>(or request_uri fetch)
    Note over Wallet: User selects credential,<br/>consents to release
    Wallet-->>RP: POST /direct_post (VP Token)<br/>(optionally JWE-encrypted)
    Note over RP: Validate signatures + nonce
    Note over RP: RP processes credential claims
AspectDetail
InvocationUniversal / deep links (openid4vp://), request_uri fetch, HTTP direct_post
RequestDCQL query (JSON); legacy PEX supported as fallback
Responsevp_token containing mDoc or SD-JWT, optionally JWE-encrypted (direct_post.jwt)
Request signingJAR (JWT Secured Authorization Request, RFC 9101)
Trust modelVerifier identity verified via X.509 certificates or redirect URI matching
Developer impactRequires JWT/JWE handling, DCQL evaluation, OpenID4VP state management
Wallet supportAll major EUDI wallets

Profiles Using Annex B

Two profiles use Annex B transport — see OpenID4VP Profiles below.


Annex C: W3C Digital Credentials API (DC API)

Moves the request mechanism into the client-side browser using navigator.credentials.get(). The browser and OS handle wallet invocation.

Flow

sequenceDiagram
    participant RP as Relying Party (Browser)
    participant Wallet as Wallet (OS-level)

    RP->>Wallet: navigator.credentials.get()<br/>{ digital: { requests: [{<br/>    protocol: "org-iso-mdoc",<br/>    data: { encryptionInfo,<br/>           deviceRequest }<br/>  }] } }
    Note over Wallet: User selects credential,<br/>consents to release
    Wallet-->>RP: Promise resolves with CBOR<br/>["dcapi", { enc, cipherText }]
    Note over RP: HPKE-decrypt DeviceResponse<br/>Verify signatures
    Note over RP: RP processes credential claims
AspectDetail
InvocationBrowser API: navigator.credentials.get({ digital: ... })
Request payload["dcapi", { nonce, recipientPublicKey }] + CBOR DeviceRequest
Response payloadHPKE-encrypted mDoc inside ["dcapi", { enc, cipherText }]
EncryptionHPKE (X25519 + HKDF-SHA256 + AES-128-GCM)
TransportBrowser/OS handles wallet invocation; BLE proximity checks + relay servers for cross-device
Trust modelTrust based on web origins and platform-verified App Links
Developer impactMinimal — browser handles wallet discovery and session binding
Wallet supportAll major EUDI wallets (wraps OpenID4VP request as dc_api.jwt)

Annex C Request Format

The request is two base64url-encoded CBOR blobs:

encryptionInfo — tells the wallet how to encrypt the response:

["dcapi", { nonce: bstr, recipientPublicKey: COSE_Key }]

deviceRequest — what to present, per ISO 18013-5:

{
  "version": "1.0",
  "docRequests": [{
    "docType": "eu.europa.ec.av.1",
    "itemsRequest": {
      "nameSpaces": {
        "eu.europa.ec.av.1": { "age_over_18": true }
      }
    }
  }]
}

Annex C Response Format

The wallet returns an HPKE-encrypted response:

["dcapi", { enc: bstr, cipherText: bstr }]

The RP HPKE-decrypts using its private key to obtain the CBOR DeviceResponse.


OpenID4VP Profiles

Two profiles use Annex B transport. For a detailed comparison see the Protocols & Formats Summary.

  • EU Age Verification (EU-AV) Blueprint — privacy-preserving age checks driven by the DSA. Uses Annex B as a fallback with redirect_uri scheme, no JAR, plain direct_post. The primary method is Annex C (DC API).
  • High Assurance Interoperability Profile (HAIP) — high-security credential exchange for PID and mDL. Requires strict JAR signing with X.509 certificates (x509_san_dns or x509_hash), and JWE-encrypted responses (direct_post.jwt).

References