Protocols / Intermediate / 12 min

Trust Registries & TRQP

Real-time authorization queries without sharing your internal policies

The Problem Trust Registries Solve

When agents operate across organizational boundaries, how does the receiving system know if they’re authorized—right now?

Traditional approaches:

  • Directory federation — Merge Active Directories (complex, exposes internal structure)
  • API callbacks — “Is Agent-42 authorized?” (latency, availability dependency)
  • Static credentials — Long-lived tokens (can’t revoke instantly)

Problems:

  • Latency — Network round-trip for every auth check
  • Privacy — Exposes who you’re checking and when
  • Revocation lag — Token revocation isn’t instant
  • Tight coupling — Both systems must integrate

Trust Registries + TRQP solve this: a standardized protocol for querying “Is [this agent] authorized to [do this action] right now?” without exposing internal policies.


What Is a Trust Registry?

A Trust Registry is an authorization authority that answers queries about whether an entity (agent, person, system) is currently authorized to perform an action.

Not a database dump — It doesn’t expose all policies; it answers specific questions:

  • ✅ “Is did:webvh:bankA.com:agent-42 authorized to execute trades?”
  • ✅ “Is agent-42 still valid, or was it revoked?”
  • ❌ Not: “Give me a list of all your agents” (privacy-preserving)

Key properties:

  1. Query-only — Verifiers ask questions; registry answers yes/no
  2. Real-time — Authorization status reflects current state (revocations instant)
  3. Privacy-preserving — Registry doesn’t learn what the agent is doing, only that someone verified it
  4. Decoupled — No shared infrastructure; HTTP API over DID-based identities

What Is TRQP?

TRQP (Trust Registry Query Protocol) is the standardized HTTP API for querying trust registries.

Analogy: TRQP is to trust what DNS is to domains—a universal query protocol.

TRQP query:

POST /trust-registry/query
Content-Type: application/json

{
  "query": {
    "agent": "did:webvh:bankA.com:agent-42",
    "action": "execute-trades",
    "resource": "AAPL"
  }
}

TRQP response:

{
  "authorized": true,
  "authorizedBy": "did:webvh:bankA.com:trader-alice",
  "expiry": "2026-12-31T23:59:59Z",
  "conditions": ["trades < $1M per transaction"]
}

TRQP is:

  • Standardized — Same query format across all trust registries
  • Extensible — Can add custom fields for domain-specific needs
  • Stateless — Each query is independent
  • Cacheable — Responses can be cached (with TTLs) for performance

How Trust Registries Work

1. Registration (Setup)

Issuer registers agents in their trust registry:

// Bank A registers Agent-42
await trustRegistry.register({
  agent: 'did:webvh:bankA.com:agent-42',
  authorizedBy: 'did:webvh:bankA.com:trader-alice',
  permissions: ['execute-trades'],
  expiry: '2026-12-31',
  conditions: { maxTradeValue: 1_000_000 }
})

2. Query (Runtime)

Verifier queries the registry:

// Bank B checks if Agent-42 is authorized
const response = await trqpQuery({
  registryUrl: 'https://bankA.com/trust-registry',
  query: {
    agent: 'did:webvh:bankA.com:agent-42',
    action: 'execute-trades',
    resource: 'AAPL',
    timestamp: new Date().toISOString()
  }
})

if (!response.authorized) {
  throw new Error('Agent not authorized')
}

// Proceeds if authorized

3. Revocation (Dynamic)

Issuer revokes authorization:

// Bank A revokes Agent-42 (instant)
await trustRegistry.revoke({
  agent: 'did:webvh:bankA.com:agent-42',
  reason: 'Trader Alice left the company'
})

// Next TRQP query returns authorized: false

TRQP Query Examples

Example 1: Simple Authorization Check

Query:

{
  "query": {
    "agent": "did:webvh:bankA.com:agent-42",
    "action": "execute-trades"
  }
}

Response:

{
  "authorized": true,
  "authorizedBy": "did:webvh:bankA.com:trader-alice",
  "expiry": "2026-12-31T23:59:59Z"
}

Example 2: Resource-Specific Authorization

Query:

{
  "query": {
    "agent": "did:webvh:hospital.com:agent-99",
    "action": "access-PHI",
    "resource": "patient-12345"
  }
}

Response:

{
  "authorized": true,
  "authorizedBy": "did:webvh:hospital.com:caseworker-bob",
  "expiry": "2026-07-22T00:00:00Z",
  "conditions": ["purpose: treatment-review"]
}

Example 3: Revoked Agent

Query:

{
  "query": {
    "agent": "did:webvh:bankA.com:agent-99"
  }
}

Response:

{
  "authorized": false,
  "reason": "Agent revoked by issuer",
  "revokedAt": "2026-07-20T14:30:00Z"
}

Trust Registries vs Alternatives

AspectDirectory FederationAPI CallbacksTrust Registry + TRQP
Setup complexityHigh (merge directories)Medium (custom integration)Low (standard protocol)
PrivacyExposes internal structureIssuer sees every queryQuery-only, no internal exposure
LatencyVariable (LDAP queries)Network round-tripFast (HTTP + caching)
RevocationMinutes to hoursReal-time (but tight coupling)Real-time (decoupled)
Cross-orgRequires federation agreementsCustom per partnerStandard protocol

Real-World Use Cases

1. Cross-Org Agent Trust

Scenario: Bank A’s agent trades with Bank B’s system.

Flow:

1. Bank A issues Agent-42 a DID + mandate (VC)
2. Bank A registers Agent-42 in their Trust Registry
3. Agent-42 sends trade request to Bank B
4. Bank B queries Bank A's Trust Registry via TRQP:
   "Is Agent-42 authorized to execute trades?"
5. Trust Registry responds: "Yes, authorized by trader-alice, expires 2026-12-31"
6. Bank B allows the trade

Key benefit: Bank B never sees Bank A’s internal authorization policies—only yes/no answers.

2. Runtime Governance

Scenario: Agent requests to modify production config.

Flow:

1. Agent Gateway receives request from Agent-42
2. Gateway queries Trust Registry:
   "Is Agent-42 authorized to modify-config on production?"
3. Trust Registry checks:
   - Is Agent-42 still valid?
   - Does the authorizer (engineer-bob) still work here?
   - Are there any time/resource restrictions?
4. Response: authorized=true, conditions: ["requires-approval"]
5. Gateway enforces multi-factor approval before allowing action

Key benefit: Policy enforcement at runtime, not just forensic logs.

3. PHI Access Authorization (HIPAA)

Scenario: AI agent needs to access patient health records.

Flow:

1. Case worker Alice authorizes Agent-99 to access patient-12345
2. Trust Registry records: Agent-99 → authorized by Alice → expires 24 hours
3. Agent-99 requests PHI
4. System queries Trust Registry: "Is Agent-99 authorized for patient-12345?"
5. Response: "Yes, authorized by caseworker-alice, expires 2026-07-22"
6. Access granted, audit log records the authorization VC

Key benefit: HIPAA-compliant proof of authorization—not just a log entry, but cryptographically verifiable.


Trust Registries in the Affinidi Stack

Trust Registry Product provides TRQP endpoints:

// Setup: Register an agent
await affinidi.trustRegistry.register({
  agent: 'did:webvh:yourcompany.com:agent-42',
  authorizedBy: 'did:webvh:yourcompany.com:manager',
  permissions: ['execute-trades'],
  expiry: '2026-12-31'
})

// Runtime: Query authorization
const result = await affinidi.trustRegistry.query({
  agent: 'did:webvh:yourcompany.com:agent-42',
  action: 'execute-trades',
  resource: 'AAPL'
})

console.log(result.authorized) // true/false

Agent Gateway enforces policies via TRQP:

// Agent sends request with DID
const request = {
  agent: 'did:webvh:yourcompany.com:agent-42',
  action: 'execute-trade',
  payload: { symbol: 'AAPL', quantity: 100 }
}

// Gateway queries Trust Registry before allowing
const authorized = await agentGateway.checkAuthorization(request)
if (!authorized) throw new Error('Unauthorized')

// Proceeds if authorized

Performance: Caching TRQP Responses

TRQP responses can be cached to reduce latency:

// Query with cache hint
const response = await trqpQuery({
  registryUrl: 'https://bankA.com/trust-registry',
  query: { agent: 'did:webvh:bankA.com:agent-42' },
  cacheControl: 'max-age=300' // Cache for 5 minutes
})

// Cache the response
cache.set(agent, response, { ttl: 300 })

// Subsequent queries hit cache (sub-millisecond)

Trade-off: Cached responses may be stale if revocation happens mid-cache-TTL. Balance latency vs freshness based on your risk tolerance.


Getting Started

For Developers

Query a Trust Registry:

npm install @affinidi/affinidi-tdk
import { TrustRegistry } from '@affinidi/affinidi-tdk'

const registry = new TrustRegistry('https://yourcompany.com/trust-registry')

const result = await registry.query({
  agent: 'did:webvh:yourcompany.com:agent-42',
  action: 'execute-trades'
})

console.log(result.authorized) // true/false

For Architects

When to use Trust Registries:

  • ✅ Cross-org agent authorization
  • ✅ Real-time revocation requirements
  • ✅ Privacy-preserving authorization (don’t expose internal policies)
  • ✅ Decoupled systems (no shared infrastructure)

When NOT to use:

  • ❌ Internal systems with tight coupling (use traditional authz)
  • ❌ Ultra-low latency requirements (sub-millisecond) where even HTTP is too slow
  • ❌ Static authorization that never changes

Further Reading

Specification:

Affinidi Docs:

Related Deep Dives:

Related Solutions:

Cookie Preferences

We use cookies to enhance your experience. You can manage your preferences below. For more information, read our Cookie Policy.

Strictly Necessary Always Active

These cookies are essential for core website functions such as security, session integrity, and cookie preference storage. They cannot be disabled.

  • _cf_bm: Distinguishes humans from bots (Cloudflare) · 30m
  • _cfuvid: Ensures secure browsing (Cloudflare) · Session
  • __hs_initial_opt_in: Prevents HubSpot's banner · 7 days
  • _gtm_debug: GTM debug mode (testing only) · Session
Analytics

These cookies help us understand how visitors interact with the site so we can improve content and performance. All data is aggregated and anonymous.

  • _ga, _gid, _gat: Google Analytics · Session – 2 years
  • __hstc, hubspotutk, __hssrc: HubSpot visitor tracking · 13 months
  • __hs_opt_out: HubSpot opt-out preference · 6 months
Marketing & Targeting

These cookies allow us and our partners to serve personalised ads and measure campaign performance.

  • _gcl_au, _gcl_dc: Google Ads conversion tracking · 90 days
  • IDE: Google Display Network personalisation · 1 year
  • _fbp: Meta / Facebook remarketing · 90 days
  • li_gc, _li_fat_id, bcookie: LinkedIn tracking · 1–24 months
  • guest_id, personalization_id: Twitter/X analytics · 2 years