How to consume a RICAL as a wallet provider
Once a RICAL provider has published a RICAL, wallets need to retrieve it, verify its authenticity, and load the trusted Reader Root Certificates into their verification logic. The steps below describe how to do that against a RICAL published by a MATTR-hosted ecosystem.
ISO/IEC 18013-5 uses the term reader for the entity that requests data from an mDoc. Throughout this documentation we use verifier or relying party for the same role. Certificate names defined by the standard (for example, Reader Root Certificate) keep their ISO terminology.
Retrieve the RICAL provider's root CA certificate
The RICAL provider and the VICAL provider share the same root CA distribution endpoint. Call the public DTS root CA certificates endpoint to obtain the root certificate(s) used by the RICAL provider as the anchor of its signing chain. The endpoint is public and does not require authentication.
curl https://your-tenant.vii.au01.mattr.global/v1/ecosystems/public/certificates/caThis endpoint is public and does not require authentication. It should be provided by the RICAL provider to all wallets in the ecosystem.
The response includes one or more PEM-encoded root certificates. Persist these certificates as your trust anchor for the RICAL provider. They only need to be refreshed when the provider rotates its root.
Retrieve the latest RICAL
Call the Retrieve latest RICAL endpoint to download the current RICAL.
curl -o rical-latest.cbor \
https://your-tenant.vii.au01.mattr.global/v1/ecosystems/{ecosystemId}/ricals/public/latestThis endpoint is public and does not require authentication. It should be provided by the RICAL provider to all wallets in the ecosystem.
The response is a binary CBOR file (application/cbor) encoded as a
COSE_Sign1 structure, following the same packaging
conventions as a VICAL.
Wallets should poll the latest endpoint on a schedule that matches the RICAL provider's publishing cadence so they always operate against the latest set of trusted verifiers.
Validate the RICAL signature and certificate chain
The RICAL is signed by a RICAL Signer certificate, which itself chains back to the RICAL provider's root CA retrieved in step 1. Before trusting any data in the RICAL, perform the following checks:
- Extract the RICAL Signer certificate from the COSE_Sign1 unprotected header (
x5chain, COSE label33). - Verify the COSE_Sign1 signature using the public key from that signer certificate and the
signature algorithm declared in the protected header (for example, ES256 / COSE algorithm
-7). - Build the certificate chain from the signer certificate up to the root CA from step 1, and validate each link: signature, validity period, key usage, and revocation status (CRL).
- Confirm the root of the chain matches one of the trust-anchor certificates you persisted in step 1.
If any of these checks fail, reject the RICAL and continue using the previously trusted version.
Decode the RICAL payload
Once the signature has been verified, decode the COSE_Sign1 payload to access the RICAL data. The
decoded structure follows the CDDL definition in the
RICAL overview. The certificateInfos array
contains one entry per trusted Reader Root Certificate, each carrying the DER-encoded certificate, its
serial number, and its Subject Key Identifier.
Load the trusted Reader Root Certificates into your wallet
Iterate over payload.certificateInfos and extract each certificate. These are the trust anchors
you should use when validating signed verifier requests:
import { decode } from "cbor-x";
const ricalBytes = await fetch(
"https://your-tenant.vii.au01.mattr.global/v1/ecosystems/{ecosystemId}/ricals/public/latest"
).then((r) => r.arrayBuffer());
// COSE_Sign1 structure: [protected, unprotected, payload, signature]
const coseSign1 = decode(new Uint8Array(ricalBytes));
const payload = decode(coseSign1[2]);
const trustedReaderRoots = payload.certificateInfos.map((info) => ({
certificateDer: info.certificate,
serialNumber: info.serialNumber,
ski: info.ski,
}));When evaluating a verifier request:
- Extract the verifier's certificate chain from the signed request.
- Build the chain up to a Reader Root Certificate and confirm that root matches one of the trusted Reader Root Certificates loaded from the RICAL (for example, by comparing SKI or by direct certificate match).
- Validate the full PKI chain from the verifier's leaf certificate up to that trusted root, including validity periods, key usage, and revocation status.
This mechanism lets a wallet authenticate verifiers across the ecosystem without maintaining individual trust relationships with each relying party.
How would you rate this page?
Last updated on