Trust elements

Field reference for the Trust Check and Trust Recorder canvas elements: TRQP verification queries against trust registries, and writing agent-registration records into trust registries.

Two canvas elements operate on trust registries. Trust Check runs TRQP queries against a registry at request time and exposes the results to OPA policies. Trust Recorder writes agent-registration records into registries as requests pass through the surface.

For conceptual background, see Trust registries.

Trust Check

Drop a Trust Check element on a surface edge to run a TRQP query against a trust registry at request time. The Trust Check stage runs all configured elements in parallel and writes results into input.trust_check_results for OPA evaluation.

Two placements are available, each checking a different agent:

  • Access Point → Managed Agent edge (caller leg): verifies the inbound caller. Available on all protocols.
  • Managed Agent → Transit Point edge (target leg): verifies the downstream agent at the Transit Point destination. The drop slot is available on A2A and AP2 Transit Points only. MCP Transit Points do not offer this slot.

Results are written to OPA under input.trust_check_results.caller and input.trust_check_results.target respectively.

For the OPA fields these results populate, see OPA policies reference.

Panel

The sidebar panel shows the configured queries as a read-only list (query type and trust registry name). Open the fullscreen editor to add or edit queries. Each leg allows a maximum of 10 queries.

Query fields

Each query in the fullscreen editor has these fields.

FieldRequiredDescription
Trust RegistryYesTrust registry to query. Selected from your configured trust registries.
Record TypeYesAuthorization: is this entity authorised to perform this action on this resource? Recognition: does this authority recognise this entity?
Authority IDYes (target leg). Auto on caller leg.Issuer or Authority DID selected from the gateway’s configured Issuers and Authorities. On the caller leg, leaving this blank defaults to the verified agent-identity-credential issuer ({{ input.agent.identity_issuer_did }}). On the target leg, an explicit selection is required.
Entity IDNoNamed-subject dropdown. On the caller leg: the caller’s agent DID (default, {{ input.agent.did }}) or the gateway’s managed-identity DID ({{ input.extension_identity.did }}). On the target leg: the target’s agent DID (default, {{ input.agent.did }}).
ActionYes (Authorization only)TRQP action string. Required for Authorization queries. Optional for Recognition queries; defaults to is when blank.
ResourceYes (Authorization only)TRQP resource string. Required for Authorization queries. Optional for Recognition queries; defaults to ownedAgent when blank.

The id field is auto-generated for each query and used by OPA to address results in input.trust_check_results.{caller|target}[]. It is not editable in the UI.

Validation constraints

  • Each leg allows a maximum of 10 queries.
  • Authority ID must be non-blank on the target leg.
  • On the caller leg, a stored {{ … }} template other than the verified-issuer default is invalid. Replace it with an explicit Issuer or Authority selection.
  • Action and Resource are required for Authorization queries and must not be blank.
  • Query id values are auto-generated and must be unique within a leg.

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 path

A || 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 and 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
}
FieldTypeDescription
idstringMirrors TrustCheckElement.id. Use this to address the result in Rego.
trust_registry_idstringThe registry the query ran against.
query_typestring"recognition" or "authorization".
okbooleantrue when the trust registry allowed the request. false for both clean denials (NOT_RECOGNIZED, NOT_AUTHORIZED) and stage failures.
errorobject or nullnull only when ok is true. Present for all other outcomes: clean denials (NOT_RECOGNIZED, NOT_AUTHORIZED) and stage failures alike.
error.codestringOne of the error codes below.
error.messagestringHuman-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.
namestring or nullMirrors TrustCheckElement.name when set. Absent from the wire when the element has no name.
authority_idstring or nullThe 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_idstring or nullThe TRQP entity DID as actually sent. Absent on the same four codes as authority_id.
actionstringThe TRQP action as sent. For recognition queries with no operator-set value, the wire default "is" is used. Always present.
resourcestringThe TRQP resource as sent. For recognition queries with no operator-set value, the wire default "ownedAgent" is used. Always present.
query_resolvedbooleantrue 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

CodeCategoryMeaning
NOT_RECOGNIZEDClean denialRecognition 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_AUTHORIZEDClean denialAuthorization query returned a negative verdict — the registry answered that the entity is not authorised. Same field population as NOT_RECOGNIZED.
TRUST_REGISTRY_UNREACHABLEStage failureOutbound TRQP transport could not be established (registry not found, no DIDComm connection, or stale connection).
QUERY_FAILEDStage failureTransport 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_REPORTStage failureRegistry 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_ERRORStage failureRegistry 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_TIMEOUTStage failureThe per-element timeout_secs budget elapsed before a response was received. Only emitted when the element carries an explicit timeout override.
TEMPLATE_RESOLUTION_FAILEDStage failureA {{ }} 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_UNAVAILABLEStage failureTarget 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_UNAVAILABLEStage failureTarget 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_FAILEDStage failureTarget 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_UNAVAILABLEStage failureTarget 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"
}

Trust Recorder

The Trust Recorder element writes agent-registration records into one or more trust registries on the response leg (Managed Agent → Access Point). It runs after the managed agent responds, so the agent’s DID from the reply is available to record. Each entry targets one registry and specifies the Issuer that signs the records and the Authority that acts as the trust anchor.

Entry fields

Each row in the entry list configures one registry target.

FieldRequiredDefaultDescription
Trust RegistryYesTrust registry to write records into. Selected from your configured trust registries.
IssuerYesIssuer that signs the records written to this registry. Selected from your configured Issuers.
AuthorityYesTrust anchor asserting these records. Selected from your configured Authorities or Issuer-derived authority DIDs.
Built-in tripleNoOnCheckbox. When on, the gateway writes an ownedAgent record: [Authority] Agent DID is ownedAgent. The agent DID is auto-filled from the response.

Custom resources

Each entry can include additional custom records. Custom resources extend the standard owned-agent record with operator-defined registrations.

FieldRequiredDefaultDescription
ActionYesThe action the record authorises or recognises (for example is, invoke).
ResourceYesThe resource URI or identifier the action applies to (for example ownedAgent, paymentAgent).
Entity targetNoAgent DIDWhich DID is written as the entity_id on the record. Options: Agent DID, Issuer DID.
Record typeNorecognitionType of TrAdmin record. Options: recognition, authorization.