light-mode-image
Learn
Pre-authorized Code flow

Learn how to configure an OID4VCI Pre-authorized Code flow to issue an mDoc into a digital wallet

Introduction

The OpenID4VCI specification is an open standard developed by the OpenID Foundation. It leverages the OpenID protocol to support verifiable credentials issuance and management.

In this tutorial we will configure an OID4VCI Pre-authorized Code flow and use it to issue an mDoc into a MATTR GO Hold example app, showing each step both through the MATTR Portal and via the equivalent API calls.

User experience

OID4VCI Tutorial Workflow

This is the user experience you will build in this tutorial:

  1. The user launches their GO Hold example app and scans a QR code received from an issuer.
  2. The GO Hold example app displays what credential is being offered and by what issuer.
  3. Once the user accepts the offer, they are required to provide a transaction code. This code is provided to the user by the issuer through a different channel (e.g. email, SMS, printed on paper).
  4. Once the transaction code is provided, the credential is immediately issued to the user's GO Hold example app. They can now view the credential and present it for verification.

UX considerations

  • No prior authentication required: Users are not required to authenticate before the credential is issued. This simplifies the process but assumes the issuer has already verified the user prior to providing the credential offer (e.g., during login to a wallet application or service portal).
  • Implicit credential acceptance: The user is not technically required to explicitly accept the credential offer. Depending on how the flow is implemented with wallet providers, the credential can be issued immediately upon scanning the QR code.
  • Optional transaction code: The use of a transaction code is optional and can be omitted if not required by the issuer. In this tutorial, we include it to demonstrate how an additional layer of security can be added to the issuance workflow.

Prerequisites

We recommend using the MATTR VII Postman collection in this tutorial. While this isn't an explicit prerequisite it can really speed things up.

Tutorial overview

To build this user experience, the current tutorial comprises the following steps:

  1. Create Issuer certificates: Required to sign mDocs.
  2. Create an mDocs credentials configuration: Controls the content and branding of issued Credentials.
  3. Create and share a Credential offer: Used by digital wallets to trigger the issuance workflow.
  4. Claim the credential as the holder: Use your GO Hold example app to claim the offered Credential.

Tutorial steps

Create issuer certificates

In this tutorial you are going to issue an mDoc, so you need to have valid IACA.

  1. Log into the MATTR Portal.
  2. In the navigation panel on the left-hand side, expand the Platform Management menu.
  3. Select Certificates.
  4. Select the Create new button.
  5. Use the Type radio button to select IACA - Issuing Authority Certificate Authority.
  6. Use the Management method radio button to select MATTR managed.
  7. Use the Country dropdown list to select an issuing country.
  8. Select the Create button to create the IACA certificate.
    The IACA is created as inactive by default.
  9. Use the Status radio button to select Active.
  10. Select the Update button to activate the IACA certificate.

Step 1: Obtain a MATTR VII access token

All of the MATTR VII endpoints you will use in this tutorial are protected, so you will first need to use your tenant details to make a request of the following structure and obtain an access token:

Request
POST https://{auth_server}/oauth/token
  • auth_server : Replace with the auth_url value from your tenant details.
Request body
{
  "client_id": "F5qaeLDdbvnU9zhA0j4eHUGCHwC1bKtt",
  "client_secret": "Wzc8J**********************************************************",
  "audience": "learn.vii.au01.mattr.global",
  "grant_type": "client_credentials"
}
  • Replace client_id, client_secret and audience with your own tenant details.
  • Keep grant_type as client_credentials.

Response

Response body
{
  "access_token": "eyJhb********************************************************************",
  "expires_in": 14400,
  "token_type": "Bearer"
}

Use the returned access_token value as a bearer token for all requests to your MATTR VII tenant in the next steps of this tutorial.

You will need to obtain a new access token whenever it expires. We recommend using our Postman collection to interact with your MATTR VII tenant. This collection includes a pre-request script to obtain an access token when it is missing or expired, as well as pre-configured templates for all available requests.

Step 2: Create the IACA certificate

  1. Make the following request to your MATTR VII tenant to create an IACA:
POST /v2/credentials/mobile/iacas

The response will include an id element which you will use in the next step.

  1. Make the following request to activate the IACA you just created:
PUT /v2/credentials/mobile/iacas/{iacaId}
  • iacaId: Replace with the id element returned in the response when you created the IACA in the previous steps.
{
    "active": true
}

Your IACA is now active and can be used to sign mDocs.

Create a MATTR VII mDocs credential configuration

  1. In the navigation panel on the left-hand side, expand the Credential Issuance menu.

  2. Select Mobile credential.

  3. Select the Create new button.

  4. In the Name text box, enter a clear and descriptive title that will appear on the credential in the wallet, for example "My First Pre-Auth Credential".

  5. In the Description text box, enter a clear and descriptive description that will appear on the credential in the wallet, for example "For High Assurance Interactions".

  6. In the Credential type text box, enter a unique identifier for the credential type, for example com.example.myfirstpreauthcredential.

  7. Copy and paste the following JSON into the Claim mappings text box:

    Claim mappings
    {
      "com.example.personaldetails.1": {
        "name": {
          "mapFrom": "claims.name",
          "type": "string"
        },
        "email": {
          "mapFrom": "claims.email",
          "type": "string"
        }
      }
    }
  8. Enter "1" in the Months text box in the Validity for panel to set the credential expiration period.

  9. Select the Create button to create the credential configuration.

Make the following request to create a simple mDoc credentials configuration that includes the holder's name and e-mail:

Request
POST /v2/credentials/mobile/configurations
Request body
{
    "type": "com.example.myfirstpreauthcredential",
    "expiresIn": {
        "months": 1
    },
    "claimMappings": {
        "com.example.personaldetails.1": {
            "name": {
                "mapFrom": "claims.name",
                "type": "string"
            },
            "email": {
                "mapFrom": "claims.email",
                "type": "string"
            }
        }
    },
    "branding": {
        "name": "My First Pre-Auth Credential",
        "description": "For High Assurance Interactions",
        "backgroundColor": "#a2d82dff"
    },
    "includeStatus": true
}

The response will include an id element. You will use it to create a Credential offer in the next step.

Create a Credential offer

You now have all the pieces in place and can wrap them all together to generate a Credential offer and share it with the intended holder so that they know what credentials are being offered and by whom.

Make the following request to generate a new Pre-authorized Code flow Credential offer:

Request
POST /v1/openid/offers/pre-authorized
Request body
{
    "credentials": ["707e920a-f342-443b-ae24-6946b7b5033e"],
    "transactionCodeConfiguration": {
        "inputMode": "numeric",
        "description": "Please enter the one-time code that was sent to you via email."
    },
    "claims": {
        "name": "John Doe",
        "email": "john.doe@example.com"
    },
    "expiresIn": {
        "minutes": 10
    }
}
  • credentials: Populate the array with the id element returned in the response when you created an mDocs credentials configuration in the previous step.

In this example, the claims are included directly in the credential offer. This is allowed in the Pre-authorized Code flow because the user's identity has already been verified. You can provide these claims programmatically when creating the credential offer, or you can reference a Claims source in your credential configuration to dynamically populate the claims in the issued credential.

Response

Response body
{
    "id": "e6e5e43c-8053-464a-aca4-ca43da765c97",
    "uri": "openid-credential-offer://?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Flearn.vii.au01.mattr.global%22%2C%22credentials%22%3A%5B%22b7b380be-1467-446b-8683-1d131e6532be%22%5D%2C%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%229K3N9UPQD-Hs5f5-gPx0fRJEmb1XTZsWszzXL024pV0%22%2C%22tx_code%22%3A%7B%22length%22%3A6%2C%22input_mode%22%3A%22numeric%22%2C%22description%22%3A%22Please%20enter%20the%20one-time%20code%20that%20was%20sent%20to%20you%20via%20email.%22%7D%7D%7D%7D", 
    "userId": "6e30dd69-c867-4279-afd3-e6619253b4a4",
    "expiresAt": "2025-08-25T01:39:00.523Z",
    "transactionCode": "763677"
}

You will need to obtain two important elements from the response:

  • transactionCode : This is the one-time code that the user will need to provide in order to claim the credential. In production deployments you will need to provide it to the user through a different channel (e.g., email, SMS, printed on paper).
  • uri : This URI can be used by a digital wallet to trigger the OID4VCI workflow. Use one of the following tools to convert the uri value to a QR code (make sure you use the Plain text option where available) and save the generated QR code as an image file.

MATTR is not affiliated with any of these service providers and cannot vouch for their offerings.

Use the MATTR GO Hold example app to claim the credential

  1. Open the GO hold example app.
  2. Select Scan.
  3. Scan the QR code generated in the previous step.
  4. Review the credential offer and select Accept.
  5. Provide the transaction code provided when you created the credential offer.
  6. Follow the on-screen instructions to claim the credential.

Congratulations, you just configured an end-to-end OID4VCI Pre-authorized Code flow to issue an mDoc into a digital wallet!!!

What's next?

In this tutorial we have configured a basic OID4VCI Pre-authorized Code flow. However, you can use MATTR VII to create more complex and rich issuance experience. Check out more resources on MATTR Learn that will enable you to:

How would you rate this page?