DC API Verifier Playground (France Identite)¶
A developer‑oriented playground to test Digital Credentials API flows with:
- OpenID4VP (unsigned) over
dc_api.jwt - ISO 18013‑7 (DeviceRequest over DC API) for mdoc
It focuses on ISO/IEC 18013‑5 mdoc parsing and extraction for wallet interoperability testing. This is a demo (not production‑ready).
| Verifier | Open Verifier |
| Source code | GitHub |
Browser Support¶
- Chrome / Chromium: OpenID4VP (
dc_api.jwt) and ISO 18013‑7 (org-iso-mdoc). - Safari: ISO 18013‑7 only. OpenID4VP over DC API is not supported.
Quick Overview¶
Supported Protocols
1. OpenID4VP (unsigned) over DC API (response_mode=dc_api.jwt)
2. ISO 18013‑7 DeviceRequest over DC API (protocol=org-iso-mdoc)
Supported Credentials (mdoc)
1. PID eu.europa.ec.eudi.pid.1
2. Age Verification eu.europa.ec.av.1
What This Verifier Does¶
OpenID4VP (Unsigned) via DC API
- Builds DCQL requests
- Invokes the wallet in a compatible browser
- Accepts JWE/JWS dc_api.jwt responses
ISO 18013‑7 (DeviceRequest over DC API)
- Builds ISO 18013‑5 DeviceRequest (CBOR, base64url)
- Encrypts/Decrypts using the Annex C DC API profile
Verification & Display
- Parses mdoc DeviceResponse
- Verifies IssuerAuth signatures
- Verifies valueDigests when present
- Displays extracted attributes and issuer certificate
Developer Tools - Request JSON editor - CBOR debug section - UI console with backend logs - Annex C / HPKE debug traces
Architecture¶
Backend - CBOR parsing - ISO 18013‑5 mdoc parsing - IssuerAuth + valueDigest verification - DeviceAuth parsing (full verification requires SessionTranscript)
Frontend - Static HTML / CSS / JS - Step‑based flow UI - DCQL request builder
Protocols Explained¶
Digital Credentials API (DC API)¶
DC API is the browser‑facing transport to invoke a wallet and exchange request/response payloads. It does not define the credential format — it only transports it.
In this playground, DC API transports:
- OpenID4VP (unsigned) via
dc_api.jwt - ISO 18013‑7 via
protocol=org-iso-mdoc
ISO/IEC 18013‑5 (mdoc)¶
ISO 18013‑5 defines the mdoc data model and cryptographic structures:
DeviceResponse→ containsdocuments- Each
Document→docType,issuerSigned, optionallydeviceSigned issuerSignedcontains:issuerAuth(COSE_Sign1 over the MSO)nameSpaces(arrays ofIssuerSignedItemBytes)valueDigestsallow per‑item integrity verification
This verifier extracts attributes from IssuerSignedItemBytes and verifies issuer signatures/digests when available.
ISO 18013‑7 (DeviceRequest over DC API)¶
ISO 18013‑7 defines how an mdoc DeviceRequest is sent via DC API and how the encrypted response is returned.
Annex C DC API profile (simplified):
- Request:
deviceRequest(CBOR, base64url)encryptionInfo(CBOR, base64url)- Response:
EncryptedResponse = ["dcapi", { enc: bstr, cipherText: bstr }]
Encryption uses HPKE single‑shot (RFC 9180):
- KEM: DHKEM(P‑256)
- KDF: HKDF‑SHA256
- AEAD: AES‑128‑GCM
The HPKE info is the CBOR‑encoded SessionTranscript (see below). aad is empty.
OpenID4VP (Unsigned) over DC API¶
OpenID4VP is an OAuth‑style protocol to request credentials. In this playground:
- Requests are unsigned (dev mode)
- DCQL describes requested claims
- Wallet returns a
dc_api.jwtresponse (JWE/JWS) - For mdoc, the
vp_tokencontains a base64url CBORDeviceResponseorDocument
SessionTranscript (Annex C)¶
The SessionTranscript binds the request and origin to the cryptographic session:
SessionTranscript = [
null,
null,
["dcapi", dcapiInfoHash]
]
dcapiInfo = [Base64EncryptionInfo, SerializedOrigin]
dcapiInfoHash = SHA-256(CBOR(dcapiInfo))
Base64EncryptionInfo= base64url CBOR ofencryptionInfoSerializedOrigin= ASCII serialization of the origin
This CBOR structure is used as HPKE info for ISO 18013‑7 encryption/decryption.
OpenID4VP vs ISO 18013‑7 (At a Glance)¶
| Aspect | OpenID4VP | ISO 18013‑7 |
|---|---|---|
| Request | OAuth/DCQL | DeviceRequest (CBOR) + encryptionInfo |
| Response | dc_api.jwt (JWE/JWS) |
EncryptedResponse with HPKE ciphertext |
| Crypto | JWT container | HPKE single‑shot + AES‑128‑GCM |
| Parsing | JWT -> vp_token -> CBOR |
HPKE decrypt -> DeviceResponse |
Getting Started (Local)¶
Open:
Some DC API implementations require a secure context (https). Use a local HTTPS proxy if needed.
Using the App¶
- Build request: choose protocol, credential type, attributes
- Send request: invoke the wallet via DC API
- Receive response: paste the wallet JSON response
- Verify: issuer signature and value digest checks
- Display: extracted attributes and portrait
ISO 18013‑5 Notes¶
Value Digests
Digest computed over:
DeviceAuth Full DeviceAuth verification requires the correct SessionTranscript. The demo parses DeviceAuth but does not fully verify it without transcript bytes.
Debugging (ISO 18013‑7 / Annex C)¶
The UI console mirrors backend logs. With debug enabled, the server emits Annex C tracing:
enc(ephemeral public key) hexcipherTexthexdcapiInfoCBOR hexdcapiInfoHashhexSessionTranscriptCBOR hexaadhex (empty)- HPKE intermediate secrets (when available):
sharedSecret,aeadKey,baseNonce
Enable debug logs:
DEBUG=1 node server.js
DEBUG=1 DEBUG_ANNEXC=1 node server.js
DEBUG=1 DEBUG_ANNEXC=1 DEBUG_ANNEXC_SECRETS=1 node server.js
Known Limitations¶
- Not production‑hardened
- DeviceAuth full verification requires SessionTranscript
- No certificate trust chain validation
- HTTPS not enforced by default