Agent validation via Trust Registry
This guide explains how to validate caller trust with the Trust Check node and enforce the final access decision with a Policy node.
Trust Check verifies trust evidence. Policy decides allow or deny.
What Trust Check verifies
The Trust Check node verifies whether a caller can be trusted before traffic reaches downstream components (for example, a Managed Agent). Verification can include:
- Caller identity validation
- Trust Registry recognition checks
- Authorisation checks
- Policy-input enrichment for enforcement
Important behaviour
Trust Check itself does not block requests.
Trust Check only produces structured results. The final decision is made by Policy, typically by evaluating input.trust_check_results.* fields.
Typical execution flow
Access Point
↓
Identity Node
↓
Trust Check
↓
Policy
↓
Managed AgentThe first step is establishing caller identity. Identity is typically derived from request payload fields and transformed into an identity object for trust verification.
Supported Trust Check query types
A Trust Check node can contain multiple verification queries. Two query types are supported:
- Recognition queries
- Authorisation queries
You can configure up to 10 trust registry queries in a single Trust Check node.
If multiple trust registries are relevant, configure all required registries and evaluate them in one Trust Check stage.
Recognition
Recognition verifies whether an identity is recognised by the selected Trust Registry.
Authorization
Authorization verifies whether an identity is allowed to perform a specific action on a specific resource.
For example, Authorization can answer the question:
Is this caller allowed to send a message?
Authorization supports custom actions and resources.
How queries are executed
Trust Check executes all configured queries against the selected Trust Registry configuration from the node sidebar.
The output is written into Trust Check result fields and then consumed by Policy.
Enforce with Policy (allow or deny)
Use a surface policy to enforce Trust Check outcomes. A common pattern is to require every caller-leg Trust Check result to be successful:
package surface.policy
default allow = false
allow if {
every r in input.trust_check_results.caller { r.ok }
}In this model:
- Trust Check produces evidence
- Policy enforces access
- Failed conditions typically result in
403 Forbidden
Authority sources for verification
Authority can come from:
- Surface configuration
- Provider information carried in Trust Registry extensions in the payload
When payload trust metadata is present, the provider ID from that metadata can be used as verification authority.
Observe and troubleshoot with logs
Trust verification results should be visible in logs.
Example (shortened) runtime sequence for a successful caller-leg validation:
2026-07-07T04:31:05.891647Z INFO Found matching response for thread bd3e031a-22d3-4b29-ba34-bdb0e6819a28: https://affinidi.com/didcomm/protocols/trqp/1.0/query-authorization/response
2026-07-07T04:31:05.907647Z INFO Received response: https://affinidi.com/didcomm/protocols/trqp/1.0/query-authorization/response
2026-07-07T04:31:05.968448Z INFO Found matching response for thread 891a1d37-a954-4447-8a58-36138c6be7b2: https://affinidi.com/didcomm/protocols/trqp/1.0/query-recognition/response
2026-07-07T04:31:05.984913Z INFO Received response: https://affinidi.com/didcomm/protocols/trqp/1.0/query-recognition/response
2026-07-07T04:31:06.324767Z INFO [OPA-INPUT] Channel policy input before eval: {"http":{"method":"POST","path":"/","headers":{"x-forwarded-for":"[REDACTED-IP]","user-agent":"PostmanRuntime/7.54.0","host":"[REDACTED-IP]:8839","content-type":"application/json"}},"gateway":{"direction":"inbound"},"channel":{"config_id":"b96cff84-1bab-42dd-a923-cfc7cd46390e","name":"OSCAR"},"trust_check_results":{"caller":[{"query_type":"authorization","ok":true,"name":"isProviderAuthorized_registry_agents"},{"query_type":"recognition","ok":true,"name":"isProviderRecognized_is_registeredDepartment"},{"query_type":"recognition","ok":true,"name":"isEntityRecognized_is_ownedAgent"}],"target":[]}} channel="b96cff84-1bab-42dd-a923-cfc7cd46390e"
2026-07-07T04:31:06.360911Z INFO [CHANNEL:b96cff84-1bab-42dd-a923-cfc7cd46390e] ✅ MULTI_CHANNEL_HANDLER: Received success response with status 200 OKHow to read this sequence:
- TRQP response lines confirm the registry answered both Authorization and Recognition queries.
- The
[OPA-INPUT]line showstrust_check_results.caller[*].okvalues available to surface policy. - A final
200 OKmeans policy conditions passed for this request path. - If policy denies, expect the same sequence up to OPA input, followed by a deny outcome (typically
403).
Use logs to determine:
- Which trust queries were executed.
- Whether Recognition passed or failed.
- Whether Authorisation passed or failed.
- Why Policy returned a 403.
For request tracing and policy decision details, see Observability.
Trust Recorder
The Trust Recorder is a configurable component that publishes trust recognition records for Managed Agents into one or more configured Trust Registries.
The Trust Recorder provides a verifiable trust footprint for Managed Agents without impacting runtime request handling. It publishes recognition records that establish:
- Which agents are owned by a particular issuer.
- Additional trust assertions about the agent.
- Trust relationships that can later be evaluated through Trust Check operations.
The recorder acts as a publisher of trust metadata and is not involved in runtime authorisation decisions.
Configuration model
A surface can have one or more Trust Recorder configurations. Each configuration consists of:
- Target Trust Registry
- Issuer DID
- Optional custom actions
trustRecorder:
- trustRegistry: alpha-registry
issuer: did:web:example.com:issuer
- trustRegistry: beta-registry
issuer: did:web:regional.com:issuerTrust Registry selection
A single surface may publish to one or multiple Trust Registries. Each Trust Registry configuration is processed independently.
trustRecorder:
- trustRegistry: alpha-registry
issuer: did:web:alpha.com:issuer
- trustRegistry: beta-registry
issuer: did:web:beta.com:issuer
- trustRegistry: gamma-registry
issuer: did:web:gamma.com:issuerTrust chain model
The Trust Recorder follows the same trust-anchor hierarchy used in Trust Registry integrations:
Trust Authority
│
▼
Issuer
│
▼
Managed AgentThree trust relationships must be established:
1. Issuer registration
Authority : Trust Authority
Entity : Issuer
Action : is
Resource : registeredDepartment2. Issuer agent registration rights
Authority : Trust Authority
Entity : Issuer
Action : register
Resource : agents3. Managed Agent ownership (automatically generated by the Trust Recorder)
Authority : Issuer
Entity : Agent
Action : is
Resource : ownedAgentDefault recording behavior
Whenever a Managed Agent successfully returns an HTTP 200 response, the Trust Recorder creates a default ownership record:
{
"authority": "did:web:example.com:issuer",
"entity": "did:web:example.com:bravo",
"action": "is",
"resource": "ownedAgent"
}This record establishes that the Managed Agent belongs to the configured Issuer.
Glad to hear it! Please tell us how we can improve more.
Sorry to hear that. Please tell us how we can improve.
Thank you for sharing your feedback so we can improve your experience.