GuidesRemote (Online)mDocs

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

Overview

Setting up online verification includes the following steps:

  1. Configure the MATTR VII Verifier tenant.
  2. Add online verification capabilities into a web application.
  3. Integrate a backend into the verification workflow (optional).
  4. 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:

  1. Configure a verifier application: Define what applications can create verification sessions with the MATTR VII tenant, and how to handle these requests.
  2. Configure trusted wallet providers: Define how to invoke specific wallet applications as part of an online verification workflow.
  3. Configure trusted issuers: The MATTR VII verifier tenant will only accept mDocs issued by these trusted issuers.
  4. 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:

HTTP
POST /v2/presentations/applications

Request body

JSON
{
    "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 only web 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 that localhost 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:

HTTP
POST /v2/presentations/wallet-providers

Request body

JSON
{
    "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 matching authorizationEndpoint 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:

    1. Make a GET request to the Issuer’s /.well-known/openid-credential-issuer endpoint.
    2. Retrieve the mdoc_iacas_uri element from the response.
    3. 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).

Request

Make a request of the following structure to your tenant to create a Truster Issuer:

HTTP
POST /v2/credentials/mobile/trusted-issuers

Request body

JSON
{
    "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:

HTTP
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:

JavaScript
MATTRVerifierSDK.initialise({ apiBaseUrl, applicationId })
  • apiBaseUrl : Replace with the tenant_url of your MATTR VII verifier tenant, provided with your access credentials.
  • applicationId : Unique identifier of the verifier application. This must match the name parameter of an existing Verifier application configuration.
Create a new credential query
JavaScript
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 only mobile (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).
  • 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 requested docType.

    • intentToRetain (Optional): When set to true, the holder will be indicated that the verifier intends to retain this claim beyond the verification workflow. Defaults to false 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:

JavaScript
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 to undefined, 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 either crossDevice or sameDevice 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.

  1. Set resultAvailableInFrontChannel to false when you create the verifier configuration.
  2. Pass a random challenge to the web application and use it when calling the requestCredentials function.
  3. Retrieve the sessionId returned by the MATTR VII verifier tenant to your web application when verification is completed.
  4. Make a request of the following structure to your MATTR VII verifier tenant to retrieve the complete verification results:
HTTP
GET /v2/presentations/sessions/{sessionId}/result
  1. Validate the challenge included in the response to ensure it matches the challenge passed when creating the presentation session.
  2. 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:

JavaScript
// 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()
}