How to setup mDocs online verification
mDocs are digital credentials based on the ISO/IEC 18013-5:2021 standard and DTS 18013-7:2024 technical specification. They are designed to be stored on a holderβs mobile device and support both in-person (proximity) and remote (online) verification workflows.
The purpose of this guide is to explain how to configure an end-to-end mDocs online verification workflow, which can include different sets of capabilities:
- Adding online verification capabilities to a web application.
- Adding online presentation capabilities to a native application used to hold and present mDocs.
Prerequisites
- We recommend you make yourself familiar with the following concepts to support your
understanding of the concepts included this guide:
- What is Credential verification?
- What are mDocs?
- What are online verification workflows and what steps do they include?
- To implement verification capabilities:
- You will need access to a MATTR VII tenant and obtain an access token that enables you to make API requests.
- You will need access to the Verifier Web SDK.
- For testing purposes, you will need an mDoc stored on a mobile device with an application that supports ISO/IEC 18013-7 (online presentation of mDocs). We recommend downloading the MATTR GO Hold example app and using it to claim an mDoc.
- To implement holding capabilities:
- You will need access to one of our mDocs Holder SDKs.
Overview
Setting up online verification includes the following steps:
- Configure the MATTR VII Verifier tenant.
- Add online verification capabilities into a web application.
- Integrate a backend into the verification workflow (optional).
- Add online presentation capabilities into a native application.
Configure the MATTR VII Verifier tenant
This step is only required if you wish to implement verification capabilities. If you are only implementing holding capabilities, you can skip to step 4.
The MATTR VII tenant is used to interact with a web application (generating a verification request) and a native application (presenting an mDoc for verification) as per OID4VP and ISO/IEC 18013-7. To enable this, you must:
- Configure a verifier application: Define what applications can create verification sessions with the MATTR VII tenant, and how to handle these requests.
- Configure trusted wallet providers: Define how to invoke specific wallet applications as part of an online verification workflow.
- Configure trusted issuers: The MATTR VII verifier tenant will only accept mDocs issued by these trusted issuers.
- Distribute the MATTR VII verifier tenant root CA certificate: Provide a way for wallet applications to establish trust when interacting with your verifier tenant.
Create a verifier application configuration
Each MATTR VII tenant can interact with multiple verifier applications, and can handle requests differently for each application. This is achieved by configuring a verifier application and defining:
- How to uniquely identify and validate requests coming from this application.
- What workflows are supported (e.g. cross-device/same-device).
- Redirect URI for same-device workflows.
- Display settings for cross-device workflows (e.g. logo, display text and colors).
- How to handle the verification results.
You will need to create a verifier application configuration for each verifier application you expect to interact with your MATTR VII verifier tenant.
Request
Make a request of the following structure to your MATTR VII tenant to create a verifier application configuration:
POST /v2/presentations/applications
Request body
{
"name": "Example Verifier Web Application",
"type": "web",
"domain": "example-verifier-web-application.com",
"openid4vpConfiguration": {
"supportedMode": "all",
"redirectUris": ["https://example-verifier-web-application.com/presentation/callback"],
"display": {
"logoImage": {
"url": "https://example-logo-image-url.com",
"altText": "Logo image"
},
"headerText": "Share your information.",
"bodyText": "Please scan the QR code to provide information required for completing this interaction.",
"privacyPolicyUrl": "https://example-privacy-policy.com",
"primaryColorHex": "#FFFFFF"
}
},
"resultAvailableInFrontChannel": true
}
name
: Unique name to identify the verifier application.type
: Defines the verifier application type. Currently onlyweb
is supported.domain
: Fully qualified domain name of verifier application that can create an online presentation session. This ensures the verifier tenant only accepts requests from known and trusted applications. Note thatlocalhost
is not supported - use local tunnelling services for testing.openid4vpConfiguration
: Details how to handle requests from this verifier application:supportedMode
: Indicates whether a verifier supports only a same device flow, a cross device flow, or both.redirectUris
: Only required for same-device flows, and used to redirect the user back to the web application after completing interactions with the digital wallet. This can be any URI, including custom URI schemes.display
: Only required for cross-device flows, and used to adjust the iframe modal appearance.logoImage
: Logo to be displayed on the top left corner of the iframe modal.url
: URL where the logo image is available.altText
: Logo image alternative text.
headerText
: Header text displayed in the iframe modal.bodyText
: Optional body text displayed in the iframe modal, explaining the context in which the credentials will be shared.privacyPolicyUrl
: Optional privacy policy url to be displayed in the iframe modal.primaryColorHex
: Optional hex rgb triplet to indicate the primary color of the iframe modal.
resultAvailableInFrontChannel
: Indicating whether or not the verification result should be returned directly to the web application (true
) or only via a configured back-end (false
). For more information see the detailed workflow.
Response
A successful 200 response indicates that a verifier application configuration has been created.
Create wallet provider configuration
Verifier applications can define specific wallet applications to accept mDocs from as part of online verification workflows. The MATTR VII verifier tenant needs to be configured with a specific URI scheme that will be used to invoke these wallets.
Request
Make a request of the following structure to your MATTR VII tenant to create wallet provider configuration:
POST /v2/presentations/wallet-providers
Request body
{
"name": "wallet-id",
"openid4vpConfiguration": {
"authorizationEndpoint": "com-example.wallet://"
}
}
name
: Unique identifier for the wallet. This field is compared against the wallet identifier defined in the request by the Verifier Web SDK. Value must be unique amongst configured wallet providers on your tenant.authorizationEndpoint
: URI scheme that will be used to invoke the wallet application.
Verification requests from a verifier web application can include a unique identifier of the wallet they want to invoke as part of the verification workflow:
- If an identifier is provided in the request and matches the
name
of a configured wallet provider, the verifier tenant will use the matchingauthorizationEndpoint
to invoke a wallet application as part of the verification workflow. - If an identifier is provided and does not match the
name
of any configured wallet provider, the request will fail. - If an identifier is not provided, the verifier tenant will use
mdoc-openid4vp://
(default scheme defined in OID4VP) to invoke any wallet.
Configure trusted issuers
You must configure trusted issuers on your MATTR VII verifier tenant, as presented mDocs will only be verified if they had been issued by a trusted issuer.
This is achieved by providing the PEM certificate of the IACA used by these issuers to sign mDocs. This certificate can be retrieved in one of two ways:
-
The Issuer can provide it directly to the Verifier out of band.
-
The Verifier can retrieve it from the Issuerβs metadata:
- Make a GET request to the Issuerβs
/.well-known/openid-credential-issuer
endpoint. - Retrieve the
mdoc_iacas_uri
element from the response. - Make a GET request to that URI to retrieve the IACAs list (for example for a MATTR VII Issuer
tenant this URI would be
{tenant_url}/v1/openid/iacas
).
- Make a GET request to the Issuerβs
Request
Make a request of the following structure to your tenant to create a Truster Issuer:
POST /v2/credentials/mobile/trusted-issuers
Request body
{
"certificatePem": "-----BEGIN CERTIFICATE-----\r\nMIICUDCCAfWgAwIBAgIKVVqBlVonWFs3lTAKBggqhkjOPQQDAjAkMQswCQYDVQQG\r\nEwJOWjEVMBMGA1UEAwwMRXhhbXBsZSBJQUNBMB4XDTI0MDExMTAzMjYwMFoXDTM0\r\nMDEwODAzMjYwMFowJDELMAkGA1UEBhMCTloxFTATBgNVBAMMDEV4YW1wbGUgSUFD\r\nQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOHxm9MYkCvIvZc/MyoWGul8+tla\r\nFSSRVkDllFERbO/Tg7DOj4CJfYrhDJEuV04eRgcowBDhr9W/bvnTMZMa/RijggEN\r\nMIIBCTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E\r\nFgQUpS3hOCbmCUwu8n91X9CLS682cOkwOwYDVR0SBDQwMoYwaHR0cHM6Ly9odWRz\r\nb24tdGVuYW50LTAwMS52aWkuYXUzMDEubWF0dHJsYWJzLmlvMIGGBgNVHR8EfzB9\r\nMHugeaB3hnVodHRwczovL2h1ZHNvbi10ZW5hbnQtMDAxLnZpaS5hdTMwMS5tYXR0\r\ncmxhYnMuaW8vdjIvY3JlZGVudGlhbHMvbW9iaWxlL2lhY2FzL2VkNzQzMTllLTcy\r\nYTYtNDQwMS1iM2E1LTk0ZTk4MGZiZWJlYS9jcmwwCgYIKoZIzj0EAwIDSQAwRgIh\r\nAJxWGZvntq+hymL7zWwrlZo1Jz1+lWglu/MESdmUhTNFAiEAg+x5e3TzBxgHneIM\r\nVpTmZNOyZI3Hn17WRKkyKSg+5/8=\r\n-----END CERTIFICATE-----\r\n"
}
certificatePem
: Use the PEM certificate of the IACA that is being used by the issuer to sign mDocs.
Distribute the verifier root CA certificate
The MATTR VII verifier tenant must provide a way for the wallet application to establish trust when requesting mDocs for verification. This is achieved by creating a root CA certificate that is used to uniquely identify the tenant.
When creating the first verifier application configuration on your tenant, a verifier root CA certificate is automatically created (unless you had manually created one prior). This certificate can be distributed to wallet providers to enable establishing trust between wallet applications and this verifier.
Request
Make a request of the following structure to your tenant to retrieve all Verifier root CA certificates:
GET /v2/presentations/certificates/ca
Response
The response will include all Verifier CA certificates available on your tenant. The certificate
used for online verification interactions is the earliest issued certificate (indicated by the
active
and notBefore
properties).
Once youβve identified the certificate being used, retrieve its certificatePem
property, which is
a PEM representation of the verifier root CA certificate. Share it with wallet providers so that
their wallet applications can trust requests coming from your MATTR VII verifier tenant.
Add online verification capabilities into a web application
This step is only required if you wish to implement verification capabilities. If you are only implementing holding capabilities, you can skip to step 3.
Add online verification capabilities into your web application by using the following Verifier Web SDK functions:
Initialize the SDK
Before using any SDK functions you must initialize the SDK by calling the initialise function:
MATTRVerifierSDK.initialise({ apiBaseUrl, applicationId })
apiBaseUrl
: Replace with thetenant_url
of your MATTR VII verifier tenant, provided with your access credentials.applicationId
: Unique identifier of the verifier application. This must match thename
parameter of an existing Verifier application configuration.
Create a new credential query
const credentialQuery = [
{
profile: 'mobile',
docType: 'org.iso.18013.5.1.mDL',
nameSpaces: {
'org.iso.18013.5.1': {
given_name: {
intentToRetain: false
},
family_name: {
intentToRetain: false
},
birth_date: {
intentToRetain: false
},
portrait: {
intentToRetain: false
},
resident_postal_code: {
intentToRetain: true
}
}
}
}
]
-
profile
: Credential format of the credential that will be verified. Currently onlymobile
(mDocs) is supported. -
docType
: the mDLβs type. Confirm with the certificate issuer for what docType they are issuing. Some common examples include:- Mobile Driver License (
org.iso.18013.5.1.mDL
). - PhotoID (
org.iso.23220.photoid.1
). - Mobile Vehicle Registration Card (
org.iso.7367.1.mVRC
). - Health certificate (
org.micov.vtr.1
).
- Mobile Driver License (
-
nameSpaces
: Each namespace corresponds to a group of claims included in the credential. These can be claims that are part of a specific standard, jurisdiction or any other reference. The namespace would usually correspond to the requesteddocType
.intentToRetain
(Optional): When set totrue
, the holder will be indicated that the verifier intends to retain this claim beyond the verification workflow. Defaults tofalse
when not specified.
In this example the credentialQuery
query will request for the given_name
, family_name
,
birth_date
, portrait
and resident_postal_code
claims from any credentials whose profile
is
mobile
and docType
is org.iso.18013.5.1.mDL
.
It also sets intentToRetain
as true
for the resident postal code, indicating to the holder that
the verifier will retain this claim beyond the verification workflow. The other claims have
intentToRetain
as false
indicating that the verifier will not retain any of these claims.
While intentToRetain
defaults to false
, it is explicitly set for some of the claims in the
example above for clarity. If there is no intention to retain a claim, it is sufficient to
simply exclude intentToRetain
from the query.
Trigger a presentation request and share it with the wallet
As part of a digital interaction with the user, call the
requestCredentials
function with the created credential query. This will trigger the configured MATTR VII verifier
tenant to create a presentation request and share it with the wallet:
const result = await MATTRVerifierSDK.requestCredentials({
credentialQuery: [credentialQuery],
challenge: MATTRVerifierSDK.utils.generateChallenge(), // replace with a challenge generated by the backend when applicable
walletProviderId,
mode: undefined, // auto detection base on browser user agent
redirectUri, // required fields for save device mode
crossDeviceCallback: {
// required fields for cross device mode
onComplete: (result) => {
console.info(
'<<< MATTRVerifierSDK.requestCredentials crossDeviceCallback.onComplete',
result
)
},
onFailure: (error) => {
console.info(
'<<< MATTRVerifierSDK.requestCredentials crossDeviceCallback.onFailure',
error
)
}
}
})
credentialQuery
: Use the query created above.challenge
: Create a random and unique challenge to ensure the security of the verification process by preventing replay attacks. You can use this challenge to verify the verification response from the MATTR VII tenant.walletProviderId
: This value must match one of the values configured on your MATTR VII verifier tenant in Step 1 above.mode
: When set toundefined
, the SDK will automatically choose the presentation flow based on the user agentβs browser (mobile agents will use same-device workflows while desktop agents will use cross-device workflows). You can set to eithercrossDevice
orsameDevice
to explicitly choose a presentation flow.redirectUri
: Only required for cross-device flows. Use the same value you configured on your MATTR VII verifier tenant in step 1 above.crossDeviceCallback
: Define how to handle success/failure cross device callbacks.
Integrate a backend into the verification workflow
This step is only required if you wish to adjust the workflow so that verification results are shared with a configured backend rather than directly with the frontend.
- Set
resultAvailableInFrontChannel
tofalse
when you create the verifier configuration. - Pass a random
challenge
to the web application and use it when calling therequestCredentials
function. - Retrieve the
sessionId
returned by the MATTR VII verifier tenant to your web application when verification is completed. - Make a request of the following structure to your MATTR VII verifier tenant to retrieve the complete verification results:
GET /v2/presentations/sessions/{sessionId}/result
- Validate the
challenge
included in the response to ensure it matches thechallenge
passed when creating the presentation session. - Process the verification results and pass the required information back to the web application to continue the interaction based on your business logic.
Add online presentation capabilities into a wallet application
This step is only required if you wish to implement holding capabilities. If you are only implementing verification capabilities, you can skip this step.
Add online presentation capabilities into your digital wallet application by using the following React Native Holder SDK components:
// start a new presentation session
const createPresentationSessionResult =
await wallet.credential.mobile.createOnlinePresentationSession({
authorisationRequestUri: '...'
})
if (createPresentationSessionResult.isErr()) {
// Define how to handle any errors creating a new presentation session
}
const session = createPresentationSessionResult.value
// Render the verifier information stored in `session.verifiedBy`.
// Render the list of matched mDocs for each received request stored in `session.matchedCredentials` for user to select.
// Construct and send a presentation response with the selected credentials
const sendResponseResult = await session.sendResponse({ credentialIds })
// In case of an error, you could either terminate the session or try and create a new createOnlinePresentationSession again
if (sendResponseResult.isErr()) {
await session.terminateSession()
}
authorisationRequestUri
: This should match theauthorizationEndpoint
defined as part of the Verifier application configuration.