Skip to main content

🛡️ Reader Trust

The reader trust mechanism ensures that the holder app can check whether the verifier (reader) apps that request the credentials can be trusted. Multipaz uses the TrustManager interface to manage and validate trust relationships.

TrustManager Implementations

Multipaz provides several implementations for managing trust:

  • LocalTrustManager: Backs trust with local files.
  • VicalTrustManager: Uses VICAL, following ISO/IEC 18013-5.
  • CompositeTrustManager: Allows stacking multiple trust managers.

Types of Trust

There are two main types of trust in Multipaz:

  • Issuer trust: Used by verifier apps to check the authenticity of credentials received from holder devices. See the verifier/issuer trust section (todo: link) for more details.
  • Reader trust: Used by holder apps to verify the trustworthiness of verifier (reader) apps requesting credentials. This section focuses on reader trust.

Setting Up Reader Trust

To establish reader trust, add trusted verifier app certificates to your trust manager. When a verifier app requests credentials, the associated key is checked against the trusted keys.

Example: Adding Trusted Reader Certificates

class App {
// ...
lateinit var readerTrustManager: TrustManagerLocal

//. . .
suspend fun init() {
//. . .

// Initialize TrustManager
// Three certificates are configured to handle different verification scenarios:
// 1. OWF Multipaz TestApp - for testing with the Multipaz test application
// 2. Multipaz Identity Reader - for APK downloaded from https://apps.multipaz.org/ (production devices with secure boot)
// Certificate available from: https://verifier.multipaz.org/identityreaderbackend/readerRootCert
// 3. Multipaz Identity Reader (Untrusted Devices) - for app compiled from source code at https://github.com/openwallet-foundation/multipaz-identity-reader
// Certificate available from: https://verifier.multipaz.org/identityreaderbackend/readerRootCertUntrustedDevices
// 4. Multipaz Web Verifier - for requesting and verifying mDocs from the web via https://verifier.multipaz.org/
readerTrustManager = TrustManagerLocal(storage = storage, identifier = "reader")

try {
readerTrustManager.addX509Cert(
certificate = X509Cert.fromPem(
Res.readBytes("files/reader_root_cert_multipaz_testapp.pem")
.decodeToString()
),
metadata = TrustMetadata(
displayName = "OWF Multipaz TestApp",
privacyPolicyUrl = "https://apps.multipaz.org"
)
)
} catch (e: TrustPointAlreadyExistsException) {
e.printStackTrace()
}

// Certificate for APK downloaded from https://apps.multipaz.org/
// This should be used for production devices with secure boot (GREEN state)
// Certificate source: https://verifier.multipaz.org/identityreaderbackend/readerRootCert
try {
readerTrustManager.addX509Cert(
certificate = X509Cert.fromPem(
Res.readBytes("files/reader_root_cert_multipaz_identity_reader.pem")
.decodeToString()
),
metadata = TrustMetadata(
displayName = "Multipaz Identity Reader",
privacyPolicyUrl = "https://verifier.multipaz.org/identityreaderbackend/"
)
)
} catch (e: TrustPointAlreadyExistsException) {
e.printStackTrace()
}

// Certificate for app compiled from source code at https://github.com/openwallet-foundation/multipaz-identity-reader
// This should be used for development/testing devices or devices with unlocked bootloaders
// Certificate source: https://verifier.multipaz.org/identityreaderbackend/readerRootCertUntrustedDevices
try {
readerTrustManager.addX509Cert(
certificate = X509Cert.fromPem(
Res.readBytes("files/reader_root_cert_multipaz_identity_reader_untrusted.pem")
.decodeToString()
),
metadata = TrustMetadata(
displayName = "Multipaz Identity Reader (Untrusted Devices)",
privacyPolicyUrl = "https://verifier.multipaz.org/identityreaderbackend/"
)
)
} catch (e: TrustPointAlreadyExistsException) {
e.printStackTrace()
}

// This is for https://verifier.multipaz.org website.
// Certificate source: https://verifier.multipaz.org/verifier/readerRootCert
try {
readerTrustManager.addX509Cert(
certificate = X509Cert.fromPem(
Res.readBytes("files/reader_root_cert_multipaz_web_verifier.pem")
.decodeToString()
),
metadata = TrustMetadata(
displayName = "Multipaz Verifier",
privacyPolicyUrl = "https://verifier.multipaz.org"
)
)
} catch (e: TrustPointAlreadyExistsException) {
e.printStackTrace()
}
}
}

These cerfiticate files can be downloaded from the following links. They should be placed inside commonMain/composeResources/files:

With this setup, your holder app will trust the following Multipaz applications as valid readers:

Add additional trusted readers as needed by importing their certificates. By configuring TrustManager with trusted reader certificates, you ensure that only authorized verifier apps can access user credentials during presentment.

Refer to this reader trust code for the complete example.