Trust Check element
A Trust Check element is a per-leg TRQP query declaration on an Agent Surface. Trust Check elements on an Access Point run on the caller leg (Access Point → Managed Agent); Trust Check elements on a Target run on the target leg (Managed Agent → Target). The Trust Check stage executes all configured elements in parallel and writes the results into input.trust_check_results for OPA evaluation.
For conceptual background, see Trust registries. For the OPA fields these results populate, see OPA policy input reference.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
id | string | Yes | — | Surface-unique identifier for this element. Used by Rego to address a specific result via input.trust_check_results.{caller|target}[]. The dashboard generates a UUID automatically. |
| Trust Registry | string | Yes | — | The trust registry to query. Selected from configured trust registries. |
| Record Type | string | Yes | — | TRQP query family. Recognition: “does this authority recognise this entity?” Authorization: “is this entity authorised to perform this action on this resource?” |
| Query | Query parameters | Yes | — | Query parameters. All values are template strings resolved against the request context before dispatch. |
| Name | string | No | None | Operator display label. Max 64 Unicode code points. C0 controls and Unicode bidi-override characters are rejected. Mirrored into the result name field; visible in audit events and OPA results. Do not use for Rego matching; use id. |
Validation constraints
- The element identifier field (
id) must be non-blank and at most 64 Unicode code points. Control characters and bidi-override characters are rejected. - Authority ID must be non-blank.
- Name, when present, must be at most 64 Unicode code points and must not contain control or bidi-override characters.
- Each leg (Access Point or Target) may contain at most 10 Trust Check elements.
- Element identifiers (
id) must be unique within a leg. Duplicate identifiers on the same leg are rejected on save.
Query parameters
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| Authority ID | string | Yes | — | Authority DID or template string (for example "{{ input.agent.provider_did }}"). The caller-leg default is "{{ input.agent.provider_did }}", which resolves to the department DID from the agent’s trust-registry extension. |
| Entity ID | string | No | "" | Entity DID or template. When blank, the runtime derives the entity from the request context: input.agent.did for the caller leg, the target’s agent card DID for the target leg. |
| Action | string | No | "is" (recognition only) | Required for Authorization queries. Optional for Recognition queries; defaults to "is" on the wire when absent or blank. |
| Resource | string | No | "ownedAgent" (recognition only) | Required for Authorization queries. Optional for Recognition queries; defaults to "ownedAgent" on the wire when absent or blank. |
Template syntax
All four query fields accept {{ }} templates resolved against the input.* JSON the gateway builds for the same request. Templates follow the OPA input namespace, so a value from the policy input is available using the same path you would use in a Rego rule.
{{ input.agent.provider_did }} → resolved DID of the agent's department/provider
{{ input.agent.did }} → effective caller DID
{{ input.source_auth.claims.sub }} → JWT subject claim (jwt_bearer auth only)
{{ input.http.path }} → request pathA || fallback operator is supported for fields that may be absent:
{{ input.extension_identity.did || input.agent.did }}The right-hand side is used only when the left-hand side is missing or null. A non-scalar value (array, object) or a malformed template short-circuits with TEMPLATE_RESOLUTION_FAILED; it does not fall through to the right-hand side.
When a template fails to resolve, the element produces ok = false with error.code = TEMPLATE_RESOLUTION_FAILED and no TRQP network call is made.
Result fields
Each element in input.trust_check_results.caller and input.trust_check_results.target has this shape:
{
"id": "tc-caller-1",
"trust_registry_id": "tr-main",
"query_type": "recognition",
"ok": true,
"error": null,
"name": "Verify caller department",
"authority_id": "did:web:authority.example.com",
"entity_id": "did:web:caller.example.com",
"action": "is",
"resource": "ownedAgent",
"query_resolved": true
}| Field | Type | Description |
|---|---|---|
id | string | Mirrors TrustCheckElement.id. Use this to address the result in Rego. |
trust_registry_id | string | The registry the query ran against. |
query_type | string | "recognition" or "authorization". |
ok | boolean | true when the trust registry allowed the request. false for both clean denials (NOT_RECOGNIZED, NOT_AUTHORIZED) and stage failures. |
error | object or null | null only when ok is true. Present for all other outcomes: clean denials (NOT_RECOGNIZED, NOT_AUTHORIZED) and stage failures alike. |
error.code | string | One of the error codes below. |
error.message | string | Human-readable detail. For TRUST_REGISTRY_PROBLEM_REPORT, this is the registry-supplied problem report code; Rego can branch on it without the gateway taking a position on whether it represents a denial or a transport error. |
name | string or null | Mirrors TrustCheckElement.name when set. Absent from the wire when the element has no name. |
authority_id | string or null | The TRQP authority DID as actually sent. Post-template-substitution when query_resolved is true; raw template string on TEMPLATE_RESOLUTION_FAILED. Absent for AGENT_CARD_UNAVAILABLE, TRUST_REGISTRY_METADATA_UNAVAILABLE, IDENTITY_VP_VERIFICATION_FAILED, and TARGET_AGENT_IDENTITY_UNAVAILABLE — the pipeline did not reach the resolution step on those paths. |
entity_id | string or null | The TRQP entity DID as actually sent. Absent on the same four codes as authority_id. |
action | string | The TRQP action as sent. For recognition queries with no operator-set value, the wire default "is" is used. Always present. |
resource | string | The TRQP resource as sent. For recognition queries with no operator-set value, the wire default "ownedAgent" is used. Always present. |
query_resolved | boolean | true when every template placeholder resolved. false when the executor fell back to raw template strings because resolution failed (TEMPLATE_RESOLUTION_FAILED) or because agent card or trust-registry metadata was unavailable. Always present. |
Error codes
| Code | Category | Meaning |
|---|---|---|
NOT_RECOGNIZED | Clean denial | Recognition query returned a negative verdict — the registry answered that it does not recognise the entity. authority_id, entity_id, action, and resource are populated; query_resolved is true. |
NOT_AUTHORIZED | Clean denial | Authorization query returned a negative verdict — the registry answered that the entity is not authorised. Same field population as NOT_RECOGNIZED. |
TRUST_REGISTRY_UNREACHABLE | Stage failure | Outbound TRQP transport could not be established (registry not found, no DIDComm connection, or stale connection). |
QUERY_FAILED | Stage failure | Transport delivered the exchange but it failed in a way that does not fit a more specific category (for example, a low-level send error). |
TRUST_REGISTRY_PROBLEM_REPORT | Stage failure | Registry responded with a DIDComm problem report. The registry-supplied code is in error.message; Rego can branch on it without the gateway taking a position on whether the code represents a denial or an error. |
TRUST_REGISTRY_PARSE_ERROR | Stage failure | Registry response was delivered but could not be parsed into the expected TRQP shape. Distinct from QUERY_FAILED so schema or version drift is observable independently. |
QUERY_TIMEOUT | Stage failure | The per-element timeout_secs budget elapsed before a response was received. Only emitted when the element carries an explicit timeout override. |
TEMPLATE_RESOLUTION_FAILED | Stage failure | A {{ }} template could not be resolved against the request context. No network call was made. authority_id and entity_id carry the raw template strings; query_resolved is false. |
AGENT_CARD_UNAVAILABLE | Stage failure | Target agent card could not be fetched. One result per configured element is synthesised. authority_id and entity_id are absent from the wire. Target leg only. |
TRUST_REGISTRY_METADATA_UNAVAILABLE | Stage failure | Target agent card was fetched but does not carry a usable trust-registry extension block (provider_did or trust_registry_did absent). Template paths referencing input.agent.provider_did or input.agent.trust_registry_did cannot resolve. authority_id and entity_id are absent. Target leg only. |
IDENTITY_VP_VERIFICATION_FAILED | Stage failure | Target agent card was fetched, but the agent-identity-credential/v1 Verifiable Presentation it carries failed cryptographic verification (bad proof, expired, or no VCIssuer configured). input.agent.did is cleared so the unverified DID never reaches OPA. authority_id and entity_id are absent. Target leg only. |
TARGET_AGENT_IDENTITY_UNAVAILABLE | Stage failure | Target agent card was fetched, but it carries no agent-identity-credential/v1 Verifiable Presentation at all. input.agent.did is cleared. authority_id and entity_id are absent. Target leg only. |
Rego patterns
Address a result by id rather than array index:
# Allow only when the named element passed
allow if {
some r in input.trust_check_results.caller
r.id == "tc-caller-1"
r.ok == true
}Deny on any stage failure:
deny if {
some r in input.trust_check_results.caller
r.error != null
}Branch on a registry-level problem report code:
deny if {
some r in input.trust_check_results.caller
r.error.code == "TRUST_REGISTRY_PROBLEM_REPORT"
r.error.message == "AGENT_NOT_RECOGNIZED"
}Related
- Access Point reference: Trust Check on the caller leg.
- Target reference: Trust Check on the target leg.
- OPA policy input reference: How Trust Check results appear as
input.trust_check_resultsin Rego. - Trust registries: Conceptual background on TRQP queries and trust registry connections.
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.