Overview
The MdocApi provides methods for working with mobile documents (mdoc) following the ISO 18013-5 standard, commonly used for mobile driver’s licenses (mDL) and other identity documents.
const mdoc = await agent.mdoc.sign({
docType: 'org.iso.18013.5.1.mDL',
issuerCertificate: certificate,
validityInfo: {
validFrom: new Date(),
validUntil: new Date('2025-12-31'),
},
namespaces: {
'org.iso.18013.5.1': {
family_name: 'Smith',
given_name: 'Alice',
birth_date: '1990-01-01',
},
},
})
Methods
sign()
Create and sign a new mdoc with specific doctype, namespaces, and validity info.
const mdoc = await agent.mdoc.sign({
docType: 'org.iso.18013.5.1.mDL',
issuerCertificate: x5c,
holderKey: holderPublicKey,
namespaces: {
'org.iso.18013.5.1': {
family_name: 'Doe',
given_name: 'John',
birth_date: '1985-03-15',
issue_date: '2024-01-15',
expiry_date: '2029-01-15',
document_number: 'DL123456789',
portrait: portraitBytes,
driving_privileges: [
{
vehicle_category_code: 'A',
issue_date: '2024-01-15',
expiry_date: '2029-01-15',
},
],
},
},
validityInfo: {
signed: new Date('2024-01-15'),
validFrom: new Date('2024-01-15'),
validUntil: new Date('2029-01-15'),
expectedUpdate: new Date('2025-01-15'),
},
})
const base64 = mdoc.base64Url
Document type identifier (e.g., ‘org.iso.18013.5.1.mDL’ for mobile driver’s license)
options.issuerCertificate
string | X509Certificate
required
X.509 certificate for the issuer
Holder’s public key for device authentication
options.namespaces
Record<string, Record<string, unknown>>
required
Data elements organized by namespace
Validity information:
signed: Date when mdoc was signed
validFrom: Date from which mdoc is valid
validUntil: Date until which mdoc is valid
expectedUpdate: Expected next update date (optional)
Returns: Promise<Mdoc>
verify()
Verify an mdoc’s signature and validity.
const result = await agent.mdoc.verify(mdoc, {
trustedCertificates: [issuerRootCert],
})
if (result.verified) {
console.log('Mdoc verified successfully')
console.log('Issuer:', result.issuer)
console.log('Valid until:', result.validityInfo.validUntil)
} else {
console.log('Verification failed:', result.error)
}
options.trustedCertificates
Array<string | X509Certificate>
Array of trusted root/intermediate certificates
Date to check validity against (defaults to current time)
Returns: Promise<MdocVerificationResult>
Result includes:
verified: boolean
issuer: Issuer information
validityInfo: Validity information
error: Error message if verification failed
fromBase64Url()
Create an Mdoc instance from a base64url encoded string.
const mdoc = agent.mdoc.fromBase64Url(
'omppc3N1ZXJBdXRohEOhASajGCGCWQLBMIICvTCCAaSgAwIBAgIB...'
)
console.log('DocType:', mdoc.docType)
console.log('Namespaces:', mdoc.namespaces)
Base64url encoded mdoc issuer-signed structure
Returns: Mdoc
store()
Store an mdoc in the wallet.
const record = await agent.mdoc.store({
mdoc: mdoc.base64Url,
docType: 'org.iso.18013.5.1.mDL',
})
console.log('Stored mdoc:', record.id)
Document type for indexing
Returns: Promise<MdocRecord>
getById()
Retrieve a stored mdoc by ID.
const record = await agent.mdoc.getById(recordId)
const mdoc = agent.mdoc.fromBase64Url(record.base64Url)
Returns: Promise<MdocRecord>
Throws: RecordNotFoundError if not found
getAll()
Retrieve all stored mdocs.
const records = await agent.mdoc.getAll()
console.log(`Found ${records.length} mdocs`)
Returns: Promise<MdocRecord[]>
findAllByQuery()
Find mdocs by query.
const driverLicenses = await agent.mdoc.findAllByQuery(
{ docType: 'org.iso.18013.5.1.mDL' },
{ limit: 10 }
)
query
Query<MdocRecord>
required
Query object
Query options (limit, offset)
Returns: Promise<MdocRecord[]>
deleteById()
Delete a stored mdoc by ID.
await agent.mdoc.deleteById(recordId)
Returns: Promise<void>
update()
Update a stored mdoc record.
const record = await agent.mdoc.getById(recordId)
record.metadata.set('lastUsed', new Date())
await agent.mdoc.update(record)
Returns: Promise<void>
Example Usage
Issuing an mDL
import { Agent } from '@credo-ts/core'
// Create issuer certificate (simplified)
const issuerCert = await agent.x509.createSelfSigned({
key: issuerKey,
extensions: [/* ... */],
})
// Issue mobile driver's license
const mdl = await agent.mdoc.sign({
docType: 'org.iso.18013.5.1.mDL',
issuerCertificate: issuerCert,
holderKey: holderPublicKey,
namespaces: {
'org.iso.18013.5.1': {
// Mandatory elements
family_name: 'Smith',
given_name: 'Alice',
birth_date: '1990-05-15',
issue_date: '2024-01-01',
expiry_date: '2029-01-01',
issuing_country: 'US',
issuing_authority: 'CA DMV',
document_number: 'D1234567',
portrait: portraitImageBytes,
// Driving privileges
driving_privileges: [
{
vehicle_category_code: 'C',
issue_date: '2024-01-01',
expiry_date: '2029-01-01',
},
],
// Optional elements
age_over_18: true,
age_over_21: true,
issuing_jurisdiction: 'California',
},
},
validityInfo: {
signed: new Date(),
validFrom: new Date(),
validUntil: new Date('2029-01-01'),
},
})
// Store mdoc
const record = await agent.mdoc.store({
mdoc: mdl.base64Url,
docType: 'org.iso.18013.5.1.mDL',
})
// Transfer to holder
const qrCode = generateQRCode(mdl.base64Url)
Verifying an mDL
import { Agent } from '@credo-ts/core'
// Parse received mdoc
const mdoc = agent.mdoc.fromBase64Url(receivedBase64)
// Verify
const result = await agent.mdoc.verify(mdoc, {
trustedCertificates: [dmvRootCert],
})
if (result.verified) {
console.log('Valid mDL')
// Access data elements
const data = mdoc.namespaces['org.iso.18013.5.1']
console.log('Name:', data.given_name, data.family_name)
console.log('Birth date:', data.birth_date)
console.log('Age over 21:', data.age_over_21)
// Check validity period
const validUntil = result.validityInfo.validUntil
console.log('Valid until:', validUntil)
} else {
console.error('Invalid mDL:', result.error)
}
Common Document Types
Mobile Driver’s License (mDL)
docType: 'org.iso.18013.5.1.mDL'
Mobile ID Card
docType: 'org.iso.18013.5.1.mID'
Vaccination Certificate
docType: 'org.iso.18013.5.1.vaccination'
Selective Disclosure
Mdocs support selective disclosure of data elements:
// Issuer issues mdoc with all elements
const mdoc = await agent.mdoc.sign({
docType: 'org.iso.18013.5.1.mDL',
namespaces: {
'org.iso.18013.5.1': {
family_name: 'Smith',
given_name: 'Alice',
birth_date: '1990-05-15',
age_over_18: true,
age_over_21: true,
// ... other elements
},
},
// ...
})
// Holder can present only selected elements
// This is typically done through device engagement
// and presentation protocols (e.g., ISO 18013-5 device retrieval)
See Also