Learn how to build an application that can verify an mDoc from another app on the same device
Overview
This guide demonstrates how to use the iOS mDocs Verifier Mobile SDK to build a mobile application that can verify an mDoc presented from an Apple Wallet, using the Verify with Wallet API.
Prerequisites
Before you get started, let's make sure you have everything you need.
MATTR Resources
- You will need access to a MATTR VII tenant and know how to make API requests.
- As part of your MATTR Pi SDK onboarding process you should have been provided with access to the
following SDK resources:
- ZIP file which includes the required framework:
(
MobileCredentialVerifierSDK-*version*.xcframework.zip
). - Sample Verifier app: You can use this app for reference as you work through this tutorial.
- ZIP file which includes the required framework:
(
This guide is only meant to be used with the most recent version of the iOS mDocs Verifier SDK.
Apple resources
- Submit an entitlement request to use the Verify with Wallet API. This request would include your app information as well as what information you would like to request for verification and why. You can only proceed with this guide after your request has been approved by Apple.
- For testing the end-to-end flow, you will need to install the Wallet and Apple mDL Developer Integrator profile.
Got everything? Let's get going!
Workflow
The following diagram depicts the workflow you will build in this guide:
- The user performs an action in an iOS mobile app (Verifier Application) that requires a credential to be presented for verification.
- The Verifier Application interacts with the Verify with Wallet API to validate the
request can be met using the Apple Wallet. This includes validating:
- The identity of the verifier.
- That the verifier is entitled to verify the requested credential type.
- That the user has a matching credential in their Apple Wallet.
- The Verify with Wallet API returns the results of the entitlement validation to the Verifier Application.
- If (and only if) all entitlements are valid, the Verifier Application presents a Verify with Apple Wallet button to the user.
- The user taps the Verify with Apple Wallet button.
- The Verifier Application starts a Verify with Apple Wallet presentation session with the configured MATTR VII tenant.
- The MATTR VII tenant calls the Verify with Wallet API with a credentials request.
- The Verify with Wallet API invokes the user's Apple Wallet to request the credential.
- The Apple Wallet displays a popup interface to the user requesting their consent to share the requested information (they never leave the Verifier Application).
- The user provides their consent to sharing a specific credential from the Apple Wallet.
- The user's Apple Wallet sends an Apple encrypted credential to the MATTR VII tenant.
- The MATTR VII tenant decrypts and verifies the credential.
- The MATTR VII tenant sends the verification results to the Verifier Application.
- The Verifier Application displays the verification results and the user continues the interaction accordingly.
You will build this workflow in three parts:
- Part 1: Setup the MATTR VII Verifier tenant.
- Part 2: Configure your Apple Developer account.
- Part 3: Build an iOS mobile application.
Part 1: Setup the MATTR VII Verifier tenant
The MATTR VII tenant will be used to interact with your mobile application (generating a verification request) and the wallet application (presenting an mDoc for verification) as per OID4VP and ISO/IEC 18013-7 Annex B. To enable this, you must:
- Create a verifier application configuration: Define what applications can create verification sessions with the MATTR VII tenant, and how to handle these requests.
- Create a trusted wallet provider configuration: Define how to invoke specific wallet applications as part of a remote verification workflow.
- Configure a trusted issuer: The MATTR VII verifier tenant will only accept mDocs issued by these trusted issuers.
Create a verifier application configuration
Each MATTR VII tenant can interact with multiple verifier applications, and can handle requests differently for each application. This means you must create a verifier application configuration that defines how to handle verification requests from your mobile application.
- In the navigation panel on the left-hand side, expand the Credential Verification menu.
- Select Applications.
- Select Create new.
- Enter a meaningful Name for your application (e.g. "Verify with Wallet Application").
- Use the Type dropdown to select
iOS
as you are building an iOS application. - Enter your Apple Developer Team ID in the Team ID field. You can find it in the Membership details section of your Apple Developer account.
- Enter your iOS application bundle identifier in the Bundle ID field. This is the unique identifier of your iOS application, which you can set in your Xcode project settings. This will be used by the MATTR VII tenant to validate incoming requests are from a known and trusted application.
- Select Create.
Make the following request to your MATTR VII tenant to create a verifier application configuration:
POST /v2/presentations/applications
{
"name": "Verify with Wallet Application",
"type": "ios",
"teamId": "A2B3C4D5E6",
"bundleId": "io.mattrlabs.dev.sampleApp.MdocSampleApp",
"resultAvailableInFrontChannel": true
}
name
: You can use whatever name you'd like, as long as it is unique on your tenant.type
: Useios
as you are building an iOS verifier application.teamId
: Replace with your Apple Developer Team ID associated with your iOS application. You can find it in the Membership details section of your Apple Developer account.bundleId
: Replace with your iOS application bundle identifier. This is the unique identifier of your iOS application, which you can set in your Xcode project settings. This must match the bundle ID you included in your Verify with Apple Wallet entitlement request.resultAvailableInFrontChannel
: Setting this totrue
makes the verification results available directly to the verifier application.
Response
{
"id": "0eaa8074-8cc4-41ec-9e42-072d36e2acb0"
//... rest of application configuration
}
id
: You will use this value later to initialize the SDK so that requests coming from your verifier application can be recognized and trusted by the MATTR VII tenant.
Configure a trusted issuer
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.
- In the navigation panel on the left-hand side, expand the Credential Verification menu.
- Click on Trusted issuers.
- Click on Create new.
- In the Certificate PEM file field, paste the PEM certificate of the IACA used by the issuers you want to trust. For testing purposes, you can use the IACA of the Apple Developer Integrator profile referenced in the prerequisites section.
- Click on Add.
Make the following request to your MATTR VII tenant to configure a trusted issuer:
POST /v2/credentials/mobile/trusted-issuers
{
"certificatePem": "-----BEGIN CERTIFICATE-----\nMIICYzCCAgmgAwIBAgIKXhjLoCkLWBxREDAKBggqhkjOPQQDAjA4MQswCQYDVQQG\nEwJBVTEpMCcGA1UEAwwgbW9udGNsaWZmLWRtdi5tYXR0cmxhYnMuY29tIElBQ0Ew\nHhcNMjQwMTE4MjMxNDE4WhcNMzQwMTE1MjMxNDE4WjA4MQswCQYDVQQGEwJBVTEp\nMCcGA1UEAwwgbW9udGNsaWZmLWRtdi5tYXR0cmxhYnMuY29tIElBQ0EwWTATBgcq\nhkjOPQIBBggqhkjOPQMBBwNCAASBnqobOh8baMW7mpSZaQMawj6wgM5e5nPd6HXp\ndB8eUVPlCMKribQ7XiiLU96rib/yQLH2k1CUeZmEjxoEi42xo4H6MIH3MBIGA1Ud\nEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRFZwEOI9yq\n232NG+OzNQzFKa/LxDAuBgNVHRIEJzAlhiNodHRwczovL21vbnRjbGlmZi1kbXYu\nbWF0dHJsYWJzLmNvbTCBgQYDVR0fBHoweDB2oHSgcoZwaHR0cHM6Ly9tb250Y2xp\nZmYtZG12LnZpaS5hdTAxLm1hdHRyLmdsb2JhbC92Mi9jcmVkZW50aWFscy9tb2Jp\nbGUvaWFjYXMvMjk0YmExYmMtOTFhMS00MjJmLThhMTctY2IwODU0NWY0ODYwL2Ny\nbDAKBggqhkjOPQQDAgNIADBFAiAlZYQP95lGzVJfCykhcpCzpQ2LWE/AbjTGkcGI\nSNsu7gIhAJfP54a2hXz4YiQN4qJERlORjyL1Ru9M0/dtQppohFm6\n-----END CERTIFICATE-----"
}
certificatePem
: Replace with the PEM certificate of the IACA used by the issuers you want to trust. For testing purposes, you can use the IACA of the Apple Developer Integrator profile you installed as part of the prerequisites.
Response
A successful 201
response indicates that this issuer's certificate was added to your MATTR VII
tenant's trusted issuer's list. This means that mDocs that use this IACA as their root certificate
can be trusted and verified.
Create an Apple Identity Access certificate
To enable your MATTR VII tenant to interact with Apple Wallet as part of a remote verification workflow, you must create an Apple Identity Access certificate. This certificate is used to sign requests sent to the Verify with Wallet API.
Currently this action is not available in the MATTR Portal and can only be performed via an API request.
Make the following request to your MATTR VII tenant to create an Apple Identity Access certificate:
POST /v2/presentations/certificates/apple-identity-access-certificates
{
"teamId": "A2B3C4D5E6",
"merchantId": "com.domain.subdomain"
}
teamId
: Replace with your Apple Developer Team ID associated with your iOS application. You can find it in the Membership details section of your Apple Developer account.merchantId
: Replace with the merchant ID you created as part of your Verify with Apple Wallet entitlement request.
Response
A successful 201
response indicates that the Apple Identity Access certificate was created
successfully:
{
"id": "fd44e792-45ac-11f0-bef8-bb24f133065e",
"teamId": "A2B3C4D5E6",
"merchantId": "com.domain.subdomain",
"csrPem": "string"
}
Make note of the csrPem
value, as you will need it in the next part to create a matching Apple
Identity Access certificate in your Apple Developer account.
Part 2: Configure your Apple Developer account
Now that you have created the Apple Identity Access certificate in your MATTR VII tenant, you must create a matching certificate in your Apple Developer account and configure it accordingly.
Create an Identity Access Certificate
Log into your Apple Developer account and create a new Apple Pay Identity Access certificate using the CSR you obtained in the previous step. For detailed instructions, see Create an Apple Pay Identity Access certificate.
Once this certificate is created, the Verify With Wallet API will be able to validate requests coming from your MATTR VII tenant, as they are signed using the private key associated with this certificate.
Part 3: Build an iOS mobile application
Now that the MATTR VII verifier tenant and your Apple developer account are both properly configured, you can proceed with the steps required to embed verification capabilities into your mobile verifier application:
Environment setup
Create a new project
Follow the detailed instructions to Create a new Xcode Project and add your organization's identifier.
Unzip the dependencies file
- Unzip the
MobileCredentialVerifierSDK-*version*.xcframework.zip
file. - Drag the
MobileCredentialVerifierSDK-*version*.xcframework
folder into your project. - Configure
MobileCredentialVerifierSDK.xcframework
to Embed & sign.
See Add existing files and folders for detailed instructions.
This should result in the following framework being added to your project:
Run the application
Select Run and make sure the application launches with a “Hello, world!” text in the middle of the display, as shown in the following image:
Configure application entitlement files
To enable your application to interact with the Apple Wallet, you must add the required capabilities in your Xcode project (see example below):
- Add the In App Identity Presentment capability and define the document types and elements you want to request for verification. You can find a list of supported document types and elements in the Apple Developer documentation.
- Add the In App Identity Presentment Merchant IDs and define the merchant IDs you created as part of your Verify with Apple Wallet entitlement request.
You can add these via the Signing & Capabilities tab of your Xcode project. For detailed instructions, see Add capabilities to your app.
Identity Presentment capabilities
Identity Presentment capabilities configuration
Initialize the SDK
The first capability you will build into your app is to initialize the SDK so that the app can use its functions and classes.
mobileCredentialVerifier.initialize(
platformConfiguration: {
tenantHost: "https://learn.vii.au01.mattr.global"
}
)
tenantHost
: Replace with the URL of your MATTR VII tenant.
Validate verification feasibility
Before displaying a Verify with Apple Wallet button, the SDK must confirm that the request can be met using the Apple Wallet. This includes validating:
- The identity of the verifier (using the provided
merchantId
). - That the verifier is entitled to verify the requested credential type (using the provided
docType
in the credential request and comparing it against the entitlements associated with thismerchantId
). - That the user has a credential that matches the requested
docType
in their Apple Wallet.
This is achieved by calling the fetchAppleWalletConfiguration
method and providing the following
parameters:
func fetchAppleWalletConfiguration(
request: MobileCredentialRequest,
applicationId: String,
merchantId: String
) async -> Result<AppleWallet, MobileCredentialVerifierError>
request
: Pass aMobileCredentialRequest
instance that defines what information is requested for verification (see example below). This will be used by the Verify with Wallet API to determine whether the requested credential type is supported by the entitlements associated with your application.applicationId
: Replace with the identifier of the MATTR VII verifier application created above. This will be used later on by MATTR VII to identify your application and ensure that requests coming from it can be trusted.merchantId
: Replace with the merchant ID you created as part of your Verify with Apple Wallet entitlement request. This is used by the Verify with Wallet API to determine whether this specific merchant is authorized to request the specified credential type.
If all checks pass, this method returns an instance of the AppleWallet class, which includes the UI elements and methods required to request a credential from an Apple Wallet.
Your application can then present one of the returned UI elements (for example a Verify with Apple Wallet button) to the user, which when tapped would invoke the Apple Wallet to request the credential for verification.
MobileCredentialRequest example
let mobileCredentialRequest = MobileCredentialRequest(
docType: "org.iso.18013.5.1.mDL",
namespaces: [
"org.iso.18013.5.1": [
"family_name": false,
"given_name": false,
"birth_date": false
]
]
)
This object defines what information is required for verification:
- The requested credential type (e.g.
org.iso.18013.5.1.mDL
). - The claims required for verification (e.g.
family_name
). - The requested namespace (e.g.
org.iso.18013.5.1
). - Whether or not the verifier intends to persist the claim value (
true
/false
).
Request a credential from an Apple Wallet
Once the user taps the Verify with Apple Wallet button, you can call the
requestMobileCredentials
method to invoke the Apple Wallet and request the mDoc for verification:
func requestMobileCredentials(challenge: String) async throws -> OnlinePresentationSessionResult
challenge
: Unique UUID that must be generated by the verifier app. Should be a unique, unpredictable value generated for each verification session to mitigate replay attacks by ensuring the response from the Apple Wallet is tied to the current request and cannot be reused maliciously. Always generate a new challenge for every credential request.
Once called, this method would orchestrate the interaction to request the mDoc for verification from the Apple Wallet. The user would see the Apple Wallet popup interface, where they can select the credential to present for verification and provide their consent to share the requested information.
Display verification results and continue the interaction
After the user consents, Apple Wallet sends the encrypted credential to the MATTR VII tenant. The
tenant decrypts and verifies it, then returns the verification results to your app as an
OnlinePresentationSessionResult
.
Your app should then:
- Validate the challenge in the
OnlinePresentationSessionResult
matches the one you sent in the request. - Parse the
OnlinePresentationSessionResult
object to extract the verification results. - Display the results to the user and continue the interaction accordingly.
How would you rate this page?