mdoc second-edition use cases
This guide turns the integration questions that commonly arise when testing an
enterprise mdoc deployment into reusable examples. The values are generic and
sanitized. issuer.example.com, anchor ids, key aliases, and identifiers are
examples; never copy a private key, client secret, or customer identifier into
an example.
The end-to-end shape
An mdoc issuance flow and a device retrieval flow are separate protocol layers:
- Configure an
mso_mdoccredential and its issuer signing key/certificate. - Issue an
IssuerSignedmdoc through OID4VCI. - The holder answers a
DeviceRequestwith aDeviceResponse. - The verifier validates the MSO, device binding, reader authentication, and any status or VICAL references.
The fixed version rule matters: the MSO structure remains version 1.0; a
second-edition DeviceRequest uses version 1.1 when second-edition request
information is present. This is not a wire version 2.0 migration.
- Overview
- Request
- Response
Create Mdl offer
Endpoint: POST /api/oid4vci/v1/backend/credential/offers
Captured response: 201 Created
This captured endpoint is shown from the E2E run; it is not mapped to one of the generated EDK REST API reference pages.
Connect an environment to rewrite this call to real service bases and run it.
The captured offer proves the HTTP issuance setup only. It is not a device retrieval or wallet-presentation result.
A second-edition DeviceRequest
The following is diagnostic JSON for the CBOR request, included to make the
selection rules visible. The wire request is CBOR, not JSON. requestInfo is
what makes this a second-edition request in the version-presence rule.
{
"version": "1.1",
"docRequests": [
{
"itemsRequest": {
"docType": "org.iso.18013.5.1.mDL",
"nameSpaces": {
"org.iso.18013.5.1": {
"family_name": false,
"given_name": false,
"document_number": false
}
},
"requestInfo": {
"alternativeDataElements": [
["org.iso.18013.5.1", "portrait"],
["org.iso.18013.5.1", "signature_usual_mark"]
],
"issuerIdentifiers": ["base64url-authority-key-identifier"],
"uniqueDocSetRequired": true,
"maximumResponseSize": 65536
}
}
}
]
}
The useful implementation questions are answered as follows:
| Question | Integration rule |
|---|---|
| Which alternative is selected? | The first complete alternative set available in the original document wins. |
| What is an issuer identifier? | An X.509 AuthorityKeyIdentifier keyIdentifier, not a DER certificate. |
| Can one document satisfy two sets? | Only when uniqueDocSetRequired is false. |
| When is size checked? | After response construction, using the same codec used for transport. |
| What happens when a required use case is unsupported? | The holder fails closed; an optional unsatisfied use case may be skipped. |
A second-edition DeviceResponse
DeviceResponse carries the selected document responses and a status. The
second-edition status values relevant to this guide are:
{
"version": "1.0",
"status": 0,
"documents": ["IssuerSigned", "DeviceSigned"]
}
This is again a diagnostic view. The actual response is CBOR and the document
and device signatures are binary. A non-zero status must not carry ordinary,
encrypted, or ZK response documents. 10 is a general error, 11 identifies
an unknown document request, and 12 means the request is not supported.
The repository keeps fixed, source-traceable byte vectors for the request and response. Use the vector provenance note and the Multipaz Annex D fixtures for cross-language codec checks. The vectors are not customer traffic and do not prove a deployed release or a live wallet session by themselves.
An MSO with Token Status List CWT status
Status is MSO metadata, not an ordinary namespace claim. A status-list reference is represented diagnostically like this:
{
"status": {
"status_list": {
"idx": 42,
"uri": "https://issuer.example.com/public/statuslists/mdoc-revocation",
"certificate": "<base64 DER certificate, when the profile requires it>",
"aggregation_uri": "https://issuer.example.com/public/statuslists/aggregate"
}
}
}
The holder or verifier resolves the URI as a signed, one-bit Token Status List
and evaluates index 42. Missing, expired, mismatched, unavailable, or
unverifiable status data is a validation error under the mdoc fail-closed
policy. The certificate is public trust material; it is not a private key.
Fixed vectors and what they prove
| Fixture | Demonstrates | Evidence boundary |
|---|---|---|
Multipaz Annex D DeviceRequest | CBOR request decoding and second-edition request structure | Codec/interoperability evidence; not a live wallet session |
Multipaz Annex D DeviceResponse | Issuer-signed and device-signed response decoding | COSE verification against the supplied DS certificate; no IACA chain claim |
| OWF mdoc-ts Ubique response | Cross-language DeviceResponse decoding | External fixture compatibility; not VICAL or browser evidence |
| Local CWT status tests | Signed CWT, application/statuslist+cwt, status transition, and fail-closed unavailable publication | Library/product test evidence; not RC4 deployment evidence |
What is intentionally separate
mso_mdoccredential issuance is OID4VCI; device retrieval is ISO/IEC 18013-5 transport and CBOR.- Regular OID4VP/DCQL and the ISO restricted presentation profile use separate wallet entry points and deep links.
- A VICAL is an ISO mdoc trust artifact. It is not an ETSI TS 119 602 trust list, a DSC, an IACA, or a status-list token.
- ZK request negotiation can be represented and rejected safely when no proof provider exists; this guide does not claim a proof-generation backend.
Test the boundary, not just the happy path
Add negative cases for an issuer-identifier mismatch, duplicate document-set selection, response-size overflow, unsupported required use case, wrong document type, invalid reader authentication, invalid device signature, stale or unavailable CWT status, and an untrusted VICAL signer. A successful HTTP offer or a decoded fixture is not evidence that the complete wallet and verifier exchange succeeded.