light-mode-image
Learn
Wallet Attestation

How to set up Wallet Attestation

Configure the SDK Backend, create a Holder root CA certificate, and coordinate with each issuer to enable Wallet Attestation in your holder application.

Wallet Attestation lets your holder application prove it is a trusted wallet to issuers that require it. For how the mechanism works and why issuers use it, see the Wallet Attestation overview. This guide covers the one-time setup: configuring the SDK Backend, creating a Holder root CA certificate, and coordinating with each issuer.

Setting up Wallet Attestation

Complete the following steps to enable Wallet Attestation in your holder application.

Configure the SDK Backend

Set up an SDK Backend to connect the Holder SDK to your MATTR VII tenant:

Creating a Holder Application is currently not available in the MATTR Portal and must be performed using the MATTR VII API. Portal support will be added in the near future.

  1. Create Holder Applications on your MATTR VII tenant for each platform target (iOS and Android).
  2. Initialize the SDK with the correct platformConfiguration including the tenant URL and the identifiers of the Holder Application you created.

Create and activate a Holder root CA certificate

Your backend MATTR VII tenant must have an active Holder root CA certificate. This root CA is used to sign Wallet Attestation signers, which in turn sign the client attestation JWTs presented to issuers, forming a chain of trust.

MATTR VII supports two types of Holder root CA certificates:

  • Managed: MATTR VII generates and manages the root certificate and its private key on your behalf. Wallet attestation signers are auto-provisioned when needed.
  • Unmanaged (external): You supply your own root CA in PEM format. You are responsible for signing and uploading wallet attestation signer certificates.

For step-by-step instructions on creating and activating a Holder root CA, see the Holder certificates guide.

Coordinate with the issuer

Wallet Attestation requires an out-of-band coordination process between you and each credential issuer. You must complete the following before your wallet can claim credentials from issuers that require Wallet Attestation:

  1. Confirm the issuer's requirements: Verify with the issuer whether Wallet Attestation is required. See Understanding issuer requirements for details on how issuer-side configuration works.

  2. Share your Holder root CA certificate: Provide the public certificate of your root CA to the issuer (for example, via a secure channel or as part of a business onboarding process). The issuer uses this certificate so they can validate the attestation proof chain your SDK presents.

  3. Align on the client identifier: The clientId you configure on your Holder Application is included as the sub claim in the wallet attestation JWT and is the value the issuer sees when your wallet claims a credential. The issuer must have this exact value registered against your wallet (with Wallet Attestation required) in their trusted wallet list. If the value your wallet presents and the value the issuer has registered do not match, the issuer rejects the attestation proof and credential claiming fails. See Agreeing on a client identifier for how to coordinate this value and why agreeing on it early matters.

Agreeing on a client identifier

The Wallet Attestation proof already tells the issuer which trusted wallet application is requesting the credential. That proof is what cryptographically establishes your wallet's authenticity. The clientId carries no additional product capability on top of this. It exists because the underlying OAuth 2.0 Attestation-Based Client Authentication specification requires every client to identify itself with a client_id. MATTR VII supports it so your wallet interoperates with any spec-compliant issuer, but the choice of value is something you and each issuer must agree on out of band.

There are two ways this coordination plays out:

  • You define the client identifier (recommended): You choose a single clientId for your wallet application (for example, mattr-wallet), configure it on your Holder Application, and share it, together with your Holder root CA certificate, with each issuer during onboarding. Every issuer registers that same value, so your wallet presents one consistent identity everywhere. This keeps your integration simple: one Holder Application, one clientId, and no per-issuer bookkeeping.

  • The issuer assigns the client identifier: Some issuers insist on assigning their own value (for example, one issuer registers your wallet as mattr-wallet while another requires partner-wallet-42). Because the value your wallet presents must match what each issuer has registered, supporting issuer-assigned identifiers means maintaining a separate Holder Application for each distinct clientId and tracking which issuer expects which value. This adds operational overhead and is best avoided where possible.

Recommendation: Wherever you can, agree on a single clientId that you define and ask each issuer to register it as-is. Raising this early in onboarding, before the issuer has provisioned your wallet in their trusted wallet list, saves you from managing multiple Holder Applications and per-issuer client identifier mappings later.

Important for existing integrations: If you already have a client_id registered with an issuer from a pre-Wallet Attestation integration, we recommend registering a new client_id for your Wallet Attestation-enabled app rather than reusing the existing one. See Migrating to Wallet Attestation for details.

Once these steps are complete, the SDK handles all Wallet Attestation interactions automatically whenever an issuer requires it during credential claiming.

Migrating to Wallet Attestation

When you enable Wallet Attestation, your SDK uses a different client authentication method (attest_jwt_client_auth_dpop instead of none). If older app versions that do not support Wallet Attestation share the same client identifier, and the issuer configures that client identifier to require attestation, those older versions will fail to claim credentials.

If your holder application is already integrated with an issuer that does not require Wallet Attestation, it is recommended to use a new client identifier to migrate safely without breaking existing app versions, as described in the following steps.

Register a new client identifier with the issuer

Coordinate with the issuer to register a new client identifier (for example, my-wallet-client-v2) that will be associated with Wallet Attestation. The issuer adds this new client identifier to their trusted wallet list with Wallet Attestation required, alongside your existing client identifier which continues to work without attestation.

Configure your Holder Application with the new client identifier

When creating or updating your Holder Application on your MATTR VII tenant, set the clientId field to the new value you registered with the issuer:

Request body
{
    "name": "My iOS Holder Application",
    "clientId": "my-wallet-client-v2", 
    "type": "ios",
    "bundleId": "com.yourcompany.holderapp",
    "teamId": "YOUR_APPLE_TEAM_ID",
    "maxTimeOfflineInSecs": 864000,
    "appAttest": {
        "required": true,
        "environment": "production"
    }
}

Release the updated app

Publish the new version of your app that supports Wallet Attestation. This version uses the new client identifier and presents Wallet Attestation proofs to issuers that support it. Existing app versions continue to use the original client identifier and operate without attestation.

Retire the old client identifier

Once you are confident that enough users have migrated to the new app version, coordinate with the issuer to remove the old client identifier from their trusted wallet list. This completes the migration and ensures all active wallet instances use Wallet Attestation.

How would you rate this page?

Last updated on

On this page