Verify Mobile Driver's Licenses (ISO/IEC 18013-7 mDL) via OID4VP
This guide provides a comprehensive walkthrough for verifying an mDL based on the ISO/IEC 18103-7 standard using the walt.id Enterprise Verifier API. The verification process will utilize the OID4VP protocol.
Enterprise Service Dependencies
To verify credentials, you need to have the following enterprise services setup:
- Verifier Service - Have a running verifier service. Setup instructions can be found here.
Verification Process
- Set mDL as the credential type to request from a user.
- Specify the claims from the mDL that are subject to presentation.
- Optionally provide a success and failure redirect URL, which the user will be redirected to after the verification process is completed.
After you have provided the required information, the Verifier API:
- Generates an appropriate Presentation Definition.
- Returns a URL which can passed to a compliant wallet to fulfill the request.
If you have provided a success or failure redirect URL, the user will be redirected to that URL. You can then access the verification results by using the id of the verification session, which can be found in the URL generated by the API, as well as in the query or path parameters of the redirect URL.
Example Verification Request
Endpoint: /v1/{target}/verifier-service-api/credentials/verify
| API Reference
Example Request
curl -X 'POST' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/verifier-service-api/credentials/verify' \
-H 'accept: */*' \
-H 'Authorization: Bearer {yourToken}' \
-H 'authorizeBaseUrl: mdoc-openid4vp://' \
-H 'responseMode: direct_post.jwt' \
-H 'successRedirectUri: https://example.com/success?id=$id' \
-H 'errorRedirectUri: https://example.com/error?id=$id' \
-H 'statusCallbackUri: https://example.com/verificationResult' \
-H 'statusCallbackApiKey: myAPIKey' \
-H 'stateId: myUniqueStateValue' \
-H 'Content-Type: application/json' \
-d '{
"request_credentials": [
{
"id": "mDL-request",
"input_descriptor": {
"id": "org.iso.18013.5.1.mDL",
"format": {
"mso_mdoc": {
"alg": [
"ES256"
]
}
},
"constraints": {
"fields": [
{
"path": [
"$['org.iso.18013.5.1']['birth_date']"
],
"intent_to_retain": false
},
{
"path": [
"$['org.iso.18013.5.1']['issue_date']"
],
"intent_to_retain": false
},
{
"path": [
"$['org.iso.18013.5.1']['expiry_date']"
],
"intent_to_retain": false
}
],
"limit_disclosure": "required"
}
}
}
],
"trusted_root_cas": [
"-----BEGIN CERTIFICATE-----\nMIIBtDCCAVmgAwIBAgIUAOXLkeu9penFRno6oDcOBgT1odYwCgYIKoZIzj0EAwIwKDELMAkGA1UEBhMCQVQxGTAXBgNVBAMMEFdhbHRpZCBUZXN0IElBQ0EwHhcNMjUwNjAyMDYzOTQ0WhcNNDAwNTI5MDYzOTQ0WjAoMQswCQYDVQQGEwJBVDEZMBcGA1UEAwwQV2FsdGlkIFRlc3QgSUFDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAZGrRN7Oeanhn7MOaGU6HhaCt8ZMySk/nRHefLbRq8lChr+PS6JqpCJ503sEvByXzPDgPsp0urKg/y0E+F7q9+jYTBfMB0GA1UdDgQWBBTxCn2nWMrE70qXb614U14BweY2azASBgNVHRMBAf8ECDAGAQH/AgEAMBoGA1UdEgQTMBGGD2h0dHBzOi8vd2FsdC5pZDAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSQAwRgIhAOM37BjC48KhsSlU6mdJwlTLrad9VzlXVKc1GmjoCNm1AiEAkFRJalpz62QCOby9l7Vkq0LAdWVKiFMd0DmSxjsdT2U=\n-----END CERTIFICATE-----\n"
],
"openid_profile": "ISO_18013_7_MDOC"
}'
Path Parameters
orgID
: Your organization ID (e.g.,test
fortest.enterprise-sandbox.waltid.dev
)target
: The verifier service target path (e.g.,waltid.verifier1
)
Header Parameters
- Authorization: Bearer token authentication is required for enterprise stack
- authorizeBaseUrl: Should be set to
mdoc-openid4vp://
for mDL verification - responseMode: Must be set to
direct_post.jwt
for mDL verification - successRedirectUri (optional): Used to redirect the user if verification is successful. You can use the
$id
placeholder to get access to the id of verification session in your application in order to retrieve the verification results. E.g./success?id=$id
will be replaced with/success?id=1234567890
- errorRedirectUri (optional): Used to redirect the user if verification is unsuccessful. You can use the
$id
placeholder to get access to the id of verification session in your application in order to retrieve the verification results. E.g./error?id=$id
will be replaced with/error?id=1234567890
- statusCallbackUri (optional): URL that should be called when the presentation request has been fulfilled by a
wallet. The request sent will be a
POST
including the whole presentation result. - statusCallbackApiKey (optional): If the endpoint you provide via
statusCallbackUri
is protected, you can use thestatusCallbackApiKey
to authenticate. The provided key will be appended as Authorization Header to the request. - stateId (optional): Overwrite the unique
state
value which gets created for each verification request with your own.
Body
{
"request_credentials": [
{
"id": "mDL-request",
"input_descriptor": {
"id": "org.iso.18013.5.1.mDL",
"format": {
"mso_mdoc": {
"alg": [
"ES256"
]
}
},
"constraints": {
"fields": [
{
"path": [
"$['org.iso.18013.5.1']['birth_date']"
],
"intent_to_retain": false
},
{
"path": [
"$['org.iso.18013.5.1']['issue_date']"
],
"intent_to_retain": false
},
{
"path": [
"$['org.iso.18013.5.1']['expiry_date']"
],
"intent_to_retain": false
}
],
"limit_disclosure": "required"
}
}
}
],
"trusted_root_cas": [
"-----BEGIN CERTIFICATE-----\nMIIBtDCCAVmgAwIBAgIUAOXLkeu9penFRno6oDcOBgT1odYwCgYIKoZIzj0EAwIwKDELMAkGA1UEBhMCQVQxGTAXBgNVBAMMEFdhbHRpZCBUZXN0IElBQ0EwHhcNMjUwNjAyMDYzOTQ0WhcNNDAwNTI5MDYzOTQ0WjAoMQswCQYDVQQGEwJBVDEZMBcGA1UEAwwQV2FsdGlkIFRlc3QgSUFDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAZGrRN7Oeanhn7MOaGU6HhaCt8ZMySk/nRHefLbRq8lChr+PS6JqpCJ503sEvByXzPDgPsp0urKg/y0E+F7q9+jYTBfMB0GA1UdDgQWBBTxCn2nWMrE70qXb614U14BweY2azASBgNVHRMBAf8ECDAGAQH/AgEAMBoGA1UdEgQTMBGGD2h0dHBzOi8vd2FsdC5pZDAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSQAwRgIhAOM37BjC48KhsSlU6mdJwlTLrad9VzlXVKc1GmjoCNm1AiEAkFRJalpz62QCOby9l7Vkq0LAdWVKiFMd0DmSxjsdT2U=\n-----END CERTIFICATE-----\n"
],
"openid_profile": "ISO_18013_7_MDOC"
}
Body Parameters
- request_credentials: An array of objects detailing the credentials to be requested from the user. For mDL credentials:
- id: A unique identifier for the credential request
- input_descriptor: Contains the credential specification
- id: Must be
"org.iso.18013.5.1.mDL"
for mDL credentials - format: Must be
"mso_mdoc"
for mDL credentials - constraints: Defines which fields to request and validation rules
- fields: Array of field specifications with paths to the requested data
- limit_disclosure: Set to
"required"
for mDL verification
- id: Must be
- trusted_root_cas: List of trusted IACA root certificates used to verify the authenticity of the presented mDL credential. These are PEM-encoded X.509 certificates.
- openid_profile: Must be set to
"ISO_18013_7_MDOC"
for mDL verification.
Example Response
The verification endpoint will return a presentation session with a URL that can be used to complete the verification process:
mdoc-openid4vp://authorize?client_id=waltid.verifier1&request_uri=https://test.enterprise-sandbox.waltid.dev/v1/waltid.verifier1/verifier-service-api/openid4vc/request&response_type=vp_token&response_mode=direct_post.jwt&scope=openid&state=1234567890
Presenting the Credential via walt.id Wallet
Using the URL returned by the verification request, we can fulfill the request using the hosted wallet by walt.id. Either show the URL as QR code and scan it with a camera or provide the URL as is in the text field below the camera once you click on "Scan to receive or present credentials" in the web wallet credentials overview page in the top right corner.
Retrieving the Verification Status
After the user presents the credential(s), you can verify the status by performing the following call with the
state
value obtained from the URL query params you shared with the user previously.
Example
mdoc-openid4vp://authorize...state=waltid.tenant1.verifier1.fb94470b-bcee-4ed7-93f5-906a4f5f585d...
Making the call to receive the verification result
curl -X 'GET' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/verifier-service-api/credentials/sessions/view' \
-H 'accept: */*'
-H 'Authorization: Bearer {yourToken}'
Path Parameters
orgID
: - When performing operations within an organization, it is essential to use the organization's Base URL or another valid host alias. For example, if your organization is namedtest
, your default Base URL will betest.enterprise-sandbox.walt.dev
when using the sandbox environment.target
: resourceIdentifier - The target indicates the organization + tenant + verifier service + sessionID to request ({organizationID}.{tenantID}.{verifierServiceID}.{sessionID}
), e.g.waltid.tenant1.verifier1.fb94470b-bcee-4ed7-93f5-906a4f5f585d