---
title: "Issue Mobile Driver's Licenses (ISO/IEC 18013-5 mDL) via OID4VCI"
description: "Sign and issue mDLs (ISO/IEC 18103-5) with the walt.id Enterprise Stack Issuer API."
stack: "Enterprise Stack (commercial) — version 0.21.0"
stack_version: "0.21.0"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/enterprise-stack/services/issuer-service/credential-issuance/mdl-oid4vc
generated: 2026-07-20
---
# How to Issue Mobile Driver's Licenses (ISO/IEC 18013-5 mDLs) via OID4VCI with walt.id Enterprise

This guide provides a comprehensive walkthrough for issuing an mDL credential based on
the [ISO/IEC 18103-5 standard](https://www.iso.org/standard/69084.html) using the walt.id Enterprise Issuer API.
The issuance process will utilize the
[OID4VCI protocol](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0-ID1.html).

## Enterprise Service Dependencies

To issue a credential, you need to have the following enterprise services setup:

1. [Issuer Service](https://docs.walt.id/enterprise-stack/services/issuer-service/overview.md) - Have a running issuer service. Setup instructions can be found [here](https://docs.walt.id/enterprise-stack/services/issuer-service/setup.md).
2. [KMS Service](https://docs.walt.id/enterprise-stack/services/key-management-service/overview.md) - Have a running KMS service. Setup instructions can be
   found [here](https://docs.walt.id/enterprise-stack/services/key-management-service/overview.md).

## Preparing for Issuance: Key Components

The mobile driver's license (mDL) ecosystem builds on established PKI principles that employ X.509 digital
certificates, while introducing domain-specific roles and data models. Its main components are:

1. **IACA — Issuing Authority Certification Authority**: This is an authority that serves as the root of trust
   vouching for authorized credential issuers and is represented by a self-signed X.509 digital certificate that is
   published to verifiers.

2. **DS — Document Signer (Credential Issuer)**: This is the entity that issues and cryptographically signs mDL
   credential(s). It holds a private key and an X.509 digital certificate issued by an IACA.
   Typically, DS certificates are short-lived and are rotated periodically.

3. **The mDL Claims**: The mDL is a verifiable credential that contains claims about the subject (holder), such as
   name, birthdate and driving privileges. The [ISO/IEC 18103-5 standard document](https://www.iso.org/standard/69084.html)
   defines a set of mandatory fields (e.g., `family_name`, `birth_date`) that must be included in every mDL, as well
   as a set of optional fields (e.g., `age_over_NN` attestations, `height`, `weight`, `sex`).

### Example mDL Credential in JSON format:

```json
{
  "family_name": "Doe",
  "given_name": "John",
  "birth_date": "1986-03-22",
  "issue_date": "2019-10-20",
  "expiry_date": "2024-10-20",
  "issuing_country": "AT",
  "issuing_authority": "AT DMV",
  "document_number": "123456789",
  "portrait": [ 141, 12 ],
  "driving_privileges": [
    {
      "vehicle_category_code": "A",
      "issue_date": "2018-08-09",
      "expiry_date": "2024-10-20"
    },
    {
      "vehicle_category_code": "B",
      "issue_date": "2017-02-23",
      "expiry_date": "2024-10-20"
    }
  ],
  "un_distinguishing_sign": "AT"
}
```

**Note**: mDLs are encoded in CBOR, which is a binary format and is shown in JSON representation above for readability
purposes. Claims values that are encoded as JSON integer arrays, e.g., the `portrait` claim's value, represent byte
arrays.

## Issuing an mDL

In this section, we'll walk through the steps required to successfully issue an mDL using the Enterprise Stack Issuer API.

**Note**: At the moment, you can only use `secp256r1` keys to issue mDLs.

### Prerequisites

Before issuing mDLs, you need to have:

1. **IACA and Document Signer Certificates**: The Enterprise Stack does not provide onboarding endpoints for IACA and Document Signer certificates. You need to obtain these certificates through external means or use the Community Stack onboarding functionality.

   **For IACA and Document Signer onboarding**, you can:
    - Use the [Community Stack mDL onboarding guide](https://docs.walt.id/community-stack/issuer/credential-issuance/mdl-oid4vc.md) to generate the required certificates
    - Import existing certificates into your Enterprise Stack key management system
    - Use external PKI services to generate the required certificates

2. **Issuer Service Configuration**: Ensure your issuer service is properly configured with the required mDL signing keys.

### Step 1: Configure mDL Credential Type

First, ensure your issuer service supports the mDL credential type. When creating an issuer service, include the mDL configuration:

```json
{
  "type": "issuer",
  "baseUrl": "https://your-issuer.example.com",
  "kms": "your-kms-service",
  "tokenKeyId": "your-signing-key",
  "supportedCredentialTypes": {
    "org.iso.18013.5.1.mDL": {
      "format": "mso_mdoc",
      "credentialDefinition": {
        "type": ["org.iso.18013.5.1.mDL"]
      },
      "docType": "org.iso.18013.5.1.mDL"
    }
  }
}
```

### Step 2: Issue an mDL Credential

Use the Enterprise Stack credential issuance endpoint to issue mDL credentials:

**Option: CURL**

**Endpoint:** `/v1/{target}/issuer-service-api/credentials/issue` | [API Reference](https://enterprise.sandbox.walt.id/swagger/index.html#/Issuer%20Service/post_v1__target__issuer_service_api_credentials_issue)

**Example Request**

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/issuer-service-api/credentials/issue' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -d '{
  "issuerKeyId": "your-signing-key-id",
  "credentialConfigurationId": "org.iso.18013.5.1.mDL",
  "credentialData": {
  "issuerKeyId": "waltid.tenant2.kms1.secp-r1",
  "credentialConfigurationId": "org.iso.18013.5.1.mDL",
  "credentialData": {
    "org.iso.18013.5.1": {
      "family_name": "Doe",
      "given_name": "John",
      "birth_date": "1986-03-22",
      "issue_date": "2019-10-20",
      "expiry_date": "2024-10-20",
      "issuing_country": "AT",
      "issuing_authority": "AT DMV",
      "document_number": "123456789",
      "portrait": [
        141,
        182,
        121,
        111,
        238,
        50,
        120,
        94,
        54,
        111,
        113,
        13,
        241,
        12,
        12
      ],
      "driving_privileges": [
        {
          "vehicle_category_code": "A",
          "issue_date": "2018-08-09",
          "expiry_date": "2024-10-20"
        },
        {
          "vehicle_category_code": "B",
          "issue_date": "2017-02-23",
          "expiry_date": "2024-10-20"
        }
      ],
      "un_distinguishing_sign": "AT"
    }
  },
  "x5Chain": [
    "-----BEGIN CERTIFICATE-----\nMIICCDCCAa2gAwIBAgIUDo8kr194t6sttt6KL3YcnMtcaYYwCgYIKoZIzj0EAwIwJDELMAkGA1UEBhMCVVMxFTATBgNVBAMMDEV4YW1wbGUgSUFDQTAeFw0yNTA1MjkwNzE4MzlaFw0yNjA4MjkwNzE4MzlaMCIxCzAJBgNVBAYTAlVTMRMwEQYDVQQDDApFeGFtcGxlIERTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGWKpdL3jPoPJ5wKgSA+jxS2jgp+ZUDE6sIQbeB86vF0XfEDAf3r/FVyJXuYVCyVT95FCA/7mlJmI1/xuMygZ+qOBvjCBuzAfBgNVHSMEGDAWgBSMIxGx+iVN4rkOzoyo5aPk3HTUFDAdBgNVHQ4EFgQU7S49LSeg/e0onfT44FVbL/rSKnswDgYDVR0PAQH/BAQDAgeAMCMGA1UdEgQcMBqGGGh0dHBzOi8vaWFjYS5leGFtcGxlLmNvbTAVBgNVHSUBAf8ECzAJBgcogYxdBQECMC0GA1UdHwQmMCQwIqAgoB6GHGh0dHBzOi8vaWFjYS5leGFtcGxlLmNvbS9jcmwwCgYIKoZIzj0EAwIDSQAwRgIhAMuSq75BPBXXBWGtIMd57fhRqpKf3Yzl3ldDdoQsK2xEAiEA/dmWLMLiJPV3UzmQS5MUHtn611z0VlL/k3YAdaVJ51c=\n-----END CERTIFICATE-----\n"
  ],
  "mDocNameSpacesDataMappingConfig": {
    "org.iso.18013.5.1": {
      "entriesConfigMap": {
        "birth_date": {
          "type": "string",
          "conversionType": "stringToFullDate"
        },
        "issue_date": {
          "type": "string",
          "conversionType": "stringToFullDate"
        },
        "expiry_date": {
          "type": "string",
          "conversionType": "stringToFullDate"
        },
        "portrait": {
          "type": "string",
          "conversionType": "base64StringToByteString"
        },
        "driving_privileges": {
          "type": "array",
          "arrayConfig": [
            {
              "type": "object",
              "entriesConfigMap": {
                "issue_date": {
                  "type": "string",
                  "conversionType": "stringToFullDate"
                },
                "expiry_date": {
                  "type": "string",
                  "conversionType": "stringToFullDate"
                }
              }
            },
            {
              "type": "object",
              "entriesConfigMap": {
                "issue_date": {
                  "type": "string",
                  "conversionType": "stringToFullDate"
                },
                "expiry_date": {
                  "type": "string",
                  "conversionType": "stringToFullDate"
                }
              }
            }
          ]
        }
      }
    }
  }
}'
```

**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 named `test`, your default Base URL will
  be `test.enterprise-sandbox.walt.dev` when using the sandbox environment.
- `target`: _resourceIdentifier_ - The target indicates the organization + tenant + issuer service with which to execute
  the credential issuance (`{organizationID}.{tenantID}.{issuerServiceID}`), e.g. `waltid.tenant1.issuer1`

**Body**
```json
{
  "issuerKeyId": "your-signing-key-id",
  "credentialConfigurationId": "org.iso.18013.5.1.mDL",
  "credentialData": {
    "org.iso.18013.5.1": {
      "family_name": "Doe",
      "given_name": "John",
      "birth_date": "1986-03-22",
      "issue_date": "2019-10-20",
      "expiry_date": "2024-10-20",
      "issuing_country": "AT",
      "issuing_authority": "AT DMV",
      "document_number": "123456789",
      "portrait": [
        141,
        182,
        121,
        111,
        238,
        50,
        120,
        94,
        54,
        111,
        113,
        13,
        241,
        12,
        12
      ],
      "driving_privileges": [
        {
          "vehicle_category_code": "A",
          "issue_date": "2018-08-09",
          "expiry_date": "2024-10-20"
        },
        {
          "vehicle_category_code": "B",
          "issue_date": "2017-02-23",
          "expiry_date": "2024-10-20"
        }
      ],
      "un_distinguishing_sign": "AT"
    }
  },
  "x5Chain": [
    "-----BEGIN CERTIFICATE-----\nMIICCDCCAa2gAwIBAgIUDo8kr194t6sttt6KL3YcnMtcaYYwCgYIKoZIzj0EAwIwJDELMAkGA1UEBhMCVVMxFTATBgNVBAMMDEV4YW1wbGUgSUFDQTAeFw0yNTA1MjkwNzE4MzlaFw0yNjA4MjkwNzE4MzlaMCIxCzAJBgNVBAYTAlVTMRMwEQYDVQQDDApFeGFtcGxlIERTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGWKpdL3jPoPJ5wKgSA+jxS2jgp+ZUDE6sIQbeB86vF0XfEDAf3r/FVyJXuYVCyVT95FCA/7mlJmI1/xuMygZ+qOBvjCBuzAfBgNVHSMEGDAWgBSMIxGx+iVN4rkOzoyo5aPk3HTUFDAdBgNVHQ4EFgQU7S49LSeg/e0onfT44FVbL/rSKnswDgYDVR0PAQH/BAQDAgeAMCMGA1UdEgQcMBqGGGh0dHBzOi8vaWFjYS5leGFtcGxlLmNvbTAVBgNVHSUBAf8ECzAJBgcogYxdBQECMC0GA1UdHwQmMCQwIqAgoB6GHGh0dHBzOi8vaWFjYS5leGFtcGxlLmNvbS9jcmwwCgYIKoZIzj0EAwIDSQAwRgIhAMuSq75BPBXXBWGtIMd57fhRqpKf3Yzl3ldDdoQsK2xEAiEA/dmWLMLiJPV3UzmQS5MUHtn611z0VlL/k3YAdaVJ51c=\n-----END CERTIFICATE-----\n"
  ],
  "mDocNameSpacesDataMappingConfig": {
    "org.iso.18013.5.1": {
      "entriesConfigMap": {
        "birth_date": {
          "type": "string",
          "conversionType": "stringToFullDate"
        },
        "issue_date": {
          "type": "string",
          "conversionType": "stringToFullDate"
        },
        "expiry_date": {
          "type": "string",
          "conversionType": "stringToFullDate"
        },
        "portrait": {
          "type": "string",
          "conversionType": "base64StringToByteString"
        },
        "driving_privileges": {
          "type": "array",
          "arrayConfig": [
            {
              "type": "object",
              "entriesConfigMap": {
                "issue_date": {
                  "type": "string",
                  "conversionType": "stringToFullDate"
                },
                "expiry_date": {
                  "type": "string",
                  "conversionType": "stringToFullDate"
                }
              }
            },
            {
              "type": "object",
              "entriesConfigMap": {
                "issue_date": {
                  "type": "string",
                  "conversionType": "stringToFullDate"
                },
                "expiry_date": {
                  "type": "string",
                  "conversionType": "stringToFullDate"
                }
              }
            }
          ]
        }
      }
    }
  }
}
```

**Body Parameters**

- `issuerKeyId`: _String_ - The ID of the signing key to use for credential issuance
- `credentialConfigurationId`: _String_ - Must be `"org.iso.18013.5.1.mDL"` for mDL credentials
- `credentialData`: _JSON_ - The mDL credential data containing all required and optional fields
- `authenticationMethod`: _String_ - Authentication method for the issuance session (default: `"PRE_AUTHORIZED"`)
- `expiresInSeconds`: _Number_ - Session expiration time in seconds (default: 300)
- `x5Chain`: _Array of Strings_ - Array of Strings - The X.509 certificate chain for the Document Signer, starting with the DS certificate.
- `mDocNameSpacesDataMappingConfig`: _JSON_ - The mapping configuration for the mDoc name spaces data. This allows us to use non-primitive data types in the mDoc claims.

---

**Example Response**

The issuance endpoint will return a credential offer URL that can be used to complete the issuance process:

```json
openid-credential-offer://waltid.enterprise.test.waltid.cloud/?credential_offer_uri=https%3A%2F%2Fwaltid.enterprise.test.waltid.cloud%2Fv1%2Fwaltid.tenant2.issuer-mdl%2Fissuer-service-api%2Fopenid4vc%2Fdraft13%2Fcredential-offer%3Fid%3D38672f8b-bed0-4e29-b6db-c0e2580a7fa0
```

## Step 4: Receive the Credential Offer

Now you can receive the credential offer via the wallet service API. See [Receive Credential Offer](https://docs.walt.id/enterprise-stack/services/wallet-service/credential-receiving/legacy-draft13/mdl-oid4vci.md) for more details.

🎉 Congratulations, you've issued a mDL using OID4VCI! 🎉
