Verifier Integration
Link the Trust Registry to a Verifier2 Service to enable automatic trust verification during credential presentation. This allows the etsi-trust-list policy to resolve issuer certificates without external network calls at verification time.
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Verification Flow │
│ │
│ Credential ──► Verifier2 ──► etsi-trust-list policy │
│ │ │ │
│ │ dependency │ resolves via │
│ ▼ ▼ │
│ Trust Registry Service ◄─────┘ │
│ │ │
│ │ queries │
│ ▼ │
│ Loaded Trust Sources (TSL, LoTE, PILOT) │
└─────────────────────────────────────────────────────────────────┘
Prerequisites
- A Trust Registry Service with at least one trust source loaded (see Setup and Trust Source Management).
- A Verifier2 Service in the same tenant.
Link Trust Registry to Verifier2
Add the Trust Registry as a dependency of your Verifier2 service:
Endpoint: /v1/{target}/verifier2-service-api/dependencies/add
Example Request
curl -X 'POST' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{verifier2Target}/verifier2-service-api/dependencies/add' \
-H 'accept: */*' \
-H 'Authorization: Bearer {yourToken}' \
-H 'Content-Type: text/plain' \
-d 'myorg.tenant1.trust-registry'
Path Parameters
orgID: String — Your organization's Base URL prefix.verifier2Target: String — The Verifier2 service path, e.g.myorg.tenant1.verifier2.
Header Parameters
Authorization: String — Bearer token for authentication. Format:Bearer {yourToken}.
Body
Plain text containing the Trust Registry service path, e.g. myorg.tenant1.trust-registry.
Response Codes
201— Dependency added successfully.
The body must be sent as text/plain, not JSON. The value is the full path to the Trust Registry service.
Verify the Link
List the Verifier2 dependencies to confirm the Trust Registry is linked:
Endpoint: GET /v1/{verifier2Target}/verifier2-service-api/dependencies/list
Example Request
curl -X 'GET' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{verifier2Target}/verifier2-service-api/dependencies/list' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {yourToken}'
Path Parameters
orgID: String — Your organization's Base URL prefix.verifier2Target: String — The Verifier2 service path, e.g.myorg.tenant1.verifier2.
Header Parameters
Authorization: String — Bearer token for authentication. Format:Bearer {yourToken}.
Example Response
Returns an array of all services registered as dependencies of the Verifier2 service.
[
{
"_id": "myorg.tenant1.trust-registry",
"type": "trust-registry"
}
]
Use the etsi-trust-list Policy
The etsi-trust-list policy is a standard Verifier2 VC policy. You add it to the vc_policies array when creating a verification session — the same way you would add signature or any other policy.
The policy snippet looks like this:
{
"policy": "etsi-trust-list",
"expectedEntityType": "PID_PROVIDER",
"allowStaleSource": false,
"requireAuthenticated": true
}
Place this inside the policies.vc_policies array of your session creation request body. For a complete walkthrough of creating a verification session — including the full request structure, flow_type, dcql_query, and response fields — see Credential Verification.
When Verifier2 has the Trust Registry linked as a dependency (as set up above), the policy resolves certificates automatically using the pre-loaded trust sources. No additional URL or inline configuration is required.
Policy Resolution Modes
The etsi-trust-list policy supports three resolution modes. Choose the one that fits your deployment:
1. Linked Service Mode (Recommended)
Uses the Trust Registry you linked in the previous step. The policy discovers and queries it automatically at verification time — no extra configuration needed.
{
"policy": "etsi-trust-list",
"expectedEntityType": "PID_PROVIDER"
}
This is the recommended mode for enterprise deployments. Trust lists are pre-loaded into the Trust Registry Service, so verification requires no outbound network calls.
2. Remote Service Mode
Queries a separate Trust Registry service by URL. Use this when your Verifier2 and Trust Registry run in different tenants, or when you need to delegate trust resolution to an external service.
{
"policy": "etsi-trust-list",
"trustRegistryUrl": "https://trust-registry.example.com",
"expectedEntityType": "PID_PROVIDER"
}
3. Inline Mode
Fetches and processes a trust list directly at verification time, without a Trust Registry service. Suitable for testing or simple deployments where operating a dedicated Trust Registry Service is not warranted.
{
"policy": "etsi-trust-list",
"trustLists": [
"https://ewc-consortium.github.io/ewc-trust-list/EWC-TL"
],
"expectedEntityType": "PID_PROVIDER"
}
Inline Mode fetches the trust list on every verification request. This adds latency and creates a runtime dependency on the availability of the external URL. Avoid this mode in production.
Policy Configuration Options
The following parameters are supported across all resolution modes unless noted otherwise:
| Parameter | Type | Default | Description |
|---|---|---|---|
expectedEntityType | string | null | Filter by entity type. Valid values: PID_PROVIDER, WALLET_PROVIDER, ATTESTATION_PROVIDER, TRUST_SERVICE_PROVIDER. When omitted, no entity type filter is applied. |
expectedServiceType | string | null | Filter by service type URI. When omitted, no service type filter is applied. |
allowStaleSource | boolean | false | When true, accepts two stale cases as trusted: a STALE_SOURCE decision, and a TRUSTED decision where the source's freshness is STALE. Both cases fail when false. Note: a source with sourceFreshness: EXPIRED always fails regardless of this setting. |
requireAuthenticated | boolean | false | When true, requires the trust source to have VALIDATED authenticity (XMLDSig signature verified). When false, sources with SKIPPED_DEMO or UNKNOWN authenticity are still accepted. |
trustRegistryUrl | string | — | (Remote mode only) The URL of the external Trust Registry Service to query. |
trustLists | array of strings | — | (Inline mode only) One or more trust list URLs to fetch and process at verification time. |
validateSignatures | boolean | true | (Inline mode only) When true, validates XMLDSig signatures when loading trust lists inline. Set to false to skip signature validation, e.g. for trust lists without a valid XMLDSig. |
Example Configurations
Strict production mode — entity type enforced, stale sources rejected, XMLDSig required:
{
"policy": "etsi-trust-list",
"expectedEntityType": "PID_PROVIDER",
"allowStaleSource": false,
"requireAuthenticated": true
}
Permissive demo mode — useful during development when trust sources may not yet be fully authenticated:
{
"policy": "etsi-trust-list",
"expectedEntityType": "PID_PROVIDER",
"allowStaleSource": true,
"requireAuthenticated": false
}
Verification Result
Once a wallet has responded to the verification request and the session is complete, retrieve the session result using the session info endpoint. The policyResults field contains one entry per applied policy.
For the etsi-trust-list policy, a successful result looks like this:
{
"policy": "etsi-trust-list",
"success": true,
"result": {
"trusted": true,
"decision": "TRUSTED",
"matchedEntity": {
"entityId": "entity-123",
"entityType": "PID_PROVIDER",
"legalName": "Example PID Provider",
"country": "DE"
},
"matchedService": {
"serviceId": "service-456",
"serviceType": "http://uri.etsi.org/TrstSvc/Svctype/IdV",
"status": "http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/granted"
},
"matchedSource": {
"sourceId": "ewc-pilot",
"sourceFamily": "LOTE",
"displayName": "EWC Pilot Trust List"
},
"sourceFreshness": "FRESH",
"authenticity": "VALIDATED"
}
}
Result fields:
trusted: Alwaystruefor a successful policy result.decision: The trust resolution outcome.TRUSTEDmeans the issuer was found in a valid trusted source.STALE_SOURCEmeans the source was found but is stale — only returned as a success whenallowStaleSource: trueis set.matchedEntity(optional): The entity in the trust source whose certificate matched.entityId: The entity's identifier within the trust source.entityType: The type of the entity, e.g.PID_PROVIDER,WALLET_PROVIDER,ATTESTATION_PROVIDER.legalName: The registered legal name of the entity.country(optional): The country code of the entity, when available.
matchedService(optional): The specific trust service entry that matched the certificate.serviceId: The service's identifier within the trust source.serviceType: The service type URI as defined in the trust list.status: The service status URI as defined in the trust list.
matchedSource: The trust source that produced the match.sourceId: The ID of the trust source as registered in the Trust Registry.sourceFamily: The trust list family, e.g.TSLorLOTE.displayName: The human-readable name of the trust source.
sourceFreshness: Freshness state of the trust source at verification time. Possible values:FRESH,STALE,EXPIRED,UNKNOWN.authenticity: XMLDSig validation state of the trust source. Possible values:VALIDATED,SKIPPED_DEMO,UNKNOWN.warnings(optional): Array of warning strings, present only when the policy succeeded with caveats (e.g. stale source accepted).
