Trust Chain Guide
A complete guide to TrustChain — from a one-liner quickstart to production-grade attestation, context integrity, RAG trust, memory protection, and agent hierarchy enforcement.
TrustChainBuilder quickstart
The fastest path to a fully attested agent is TrustChainBuilder. One call wraps your agent with all TrustChain components configured to safe defaults.
from agentcop.trust import TrustChainBuilder
# One-liner: all components, safe defaults
chain = TrustChainBuilder(agent_id="my-agent").build()
# Run your agent through the chain
result = chain.run(my_agent, input="Summarize the quarterly report")
The builder enables attestation signing, context snapshot/verify, RAG source validation, memory integrity, and agent hierarchy checks — all with default settings. Each component can be individually configured or disabled.
from agentcop.trust import TrustChainBuilder
chain = (
TrustChainBuilder(agent_id="production-agent")
.with_attestation(signed=True, key_path="/secrets/agent.pem")
.with_context_guard(snapshot_on=["tool_call", "llm_response"])
.with_rag_trust(sources=["s3://my-kb/", "https://docs.internal/"])
.with_memory_guard(backend="redis://localhost:6379/0")
.with_hierarchy(supervisor="orchestrator-agent", workers=["search", "summarize"])
.build()
)
NodeAttestor: signed vs unsigned attestation
The NodeAttestor signs each execution step with a cryptographic key. Every tool call, LLM response, and context read produces a signed attestation record that can be independently verified.
from agentcop.trust import NodeAttestor
# Unsigned attestation — records steps but does not sign them
# Use for development and audit logging without key management
attestor = NodeAttestor(agent_id="dev-agent", signed=False)
# Signed attestation — each record is HMAC-signed with your key
# Use in production — unsigned records will fail verification
attestor = NodeAttestor(
agent_id="production-agent",
signed=True,
key_path="/run/secrets/attestation_key", # PEM or raw bytes
)
# Attach to your agent
attestor.attach(my_agent)
# Each step now produces a signed attestation record
# Verify a chain after the fact:
chain_records = attestor.export_chain()
attestor.verify_chain(chain_records) # raises AttestationError if invalid
Signed and unsigned attestation differ in their security guarantees:
- Unsigned — records that each step occurred and in what order. Detects missing or reordered steps but cannot prove the record was not modified after the fact.
- Signed — each record is cryptographically bound to the signing key. Any modification to the record or its position in the chain causes verification to fail. Suitable for regulatory audit trails.
ContextGuard: snapshot and verify
The ContextGuard takes a cryptographic snapshot of the agent's context window at specified points and verifies that the context has not been mutated between those points.
from agentcop.trust import ContextGuard
guard = ContextGuard(
agent_id="my-agent",
snapshot_on=["tool_call", "llm_response", "memory_read"],
# Raise immediately if context mutation detected
on_mutation="raise", # or "log", "alert"
)
# Wrap your agent
protected = guard.wrap(my_agent)
# After a run, inspect the context integrity log
for record in guard.integrity_log():
print(f"{record.step}: {record.status} — {record.snapshot_hash[:12]}")
When a mutation is detected, ContextGuard raises a ContextMutationError with a diff showing exactly which keys changed between the last snapshot and the current state. This makes it straightforward to identify which component in the pipeline modified the context unexpectedly.
RAGTrustLayer: register sources, detect poisoning
The RAGTrustLayer maintains a registry of trusted document sources. Every document retrieved during agent execution is checked against this registry before it is added to the agent's context.
from agentcop.trust import RAGTrustLayer
rag = RAGTrustLayer(agent_id="my-agent")
# Register trusted sources — only documents from these sources are allowed
rag.register_source("s3://company-kb/docs/", trust_level="high")
rag.register_source("https://docs.internal/api/", trust_level="high")
rag.register_source("https://external-partner.example.com/", trust_level="medium")
# Optionally register known-good document hashes for strict verification
rag.register_document_hash(
uri="s3://company-kb/docs/policy-v2.pdf",
sha256="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
)
# Wrap your retrieval function
@rag.guard
def retrieve(query: str) -> list[str]:
return vector_store.similarity_search(query)
# Untrusted or hash-mismatched documents raise RAGPoisoningError
# or are quarantined depending on configuration
rag.on_untrusted = "quarantine" # or "raise", "log"
MemoryGuard: snapshot, verify, read_safe
The MemoryGuard protects an agent's persistent memory store against poisoning by taking cryptographic snapshots and verifying reads against those snapshots.
from agentcop.trust import MemoryGuard
guard = MemoryGuard(
agent_id="my-agent",
backend="redis://localhost:6379/1", # or "sqlite:///memory.db"
)
# Take a snapshot of known-good memory state
snapshot_id = guard.snapshot()
# Later — verify memory has not changed since snapshot
guard.verify(snapshot_id) # raises MemoryPoisoningError if modified
# Use read_safe instead of direct reads in production
# read_safe verifies the entry against the last snapshot before returning it
belief = guard.read_safe("user_preferences")
# Write to memory — also logged and included in next snapshot
guard.write("user_preferences", {"language": "en", "timezone": "UTC"})
# Export the full memory audit trail
for entry in guard.audit_log():
print(f"{entry.timestamp}: {entry.operation} — {entry.key}")
AgentHierarchy: supervisor/worker setup, veto, quorum
The AgentHierarchy component enforces which agents can instruct which other agents, and what approval thresholds are required for high-stakes decisions.
from agentcop.trust import AgentHierarchy
hierarchy = AgentHierarchy()
# Define the hierarchy
hierarchy.set_supervisor("orchestrator", workers=["search-agent", "summarize-agent", "write-agent"])
hierarchy.set_supervisor("search-agent", workers=["web-fetcher"])
# Veto rights — orchestrator can override any worker decision
hierarchy.grant_veto("orchestrator", over=["search-agent", "summarize-agent", "write-agent"])
# Quorum — write-agent actions require sign-off from orchestrator AND summarize-agent
hierarchy.require_quorum(
agent="write-agent",
actions=["publish", "delete", "send_email"],
approvers=["orchestrator", "summarize-agent"],
threshold=2 # both must approve
)
# Enforce: a worker cannot accept instructions from a non-supervisor
hierarchy.enforce(strict=True)
# Attach to your agents
orchestrator_agent = hierarchy.wrap("orchestrator", orchestrator_agent)
search_agent = hierarchy.wrap("search-agent", search_agent)
When strict=True, any agent that receives instructions from a non-registered supervisor raises a HierarchyViolationError. This prevents a compromised low-privilege agent from delegating to a high-privilege agent and using its authority.
TrustInterop: cross-runtime portable claims
The TrustInterop module exports attestation records as portable signed claims that can be verified by other runtimes, services, or auditors without access to your internal AgentCop instance.
from agentcop.trust import TrustInterop
interop = TrustInterop(
issuer="agentcop:production-agent",
public_key_url="https://keys.agentcop.live/production-agent.pub",
)
# Export the current chain as a portable JWT-based claim bundle
claims = interop.export_claims(attestor.export_chain())
# Share claims with an external auditor or downstream service
print(claims.to_json()) # signed JSON, verifiable with the public key
# Verify a claim bundle received from another runtime
received_claims = TrustInterop.import_claims(external_json)
received_claims.verify() # raises TrustInteropError if signature invalid
Docker/production: in-memory mode, env vars
In containerized environments, TrustChain components can be configured entirely through environment variables and run in in-memory mode — no external storage required.
# Environment variables for TrustChain in production
AGENTCOP_TRUST_SIGNED=true
AGENTCOP_TRUST_KEY_PATH=/run/secrets/attestation_key
AGENTCOP_TRUST_MEMORY_BACKEND=memory:// # in-memory, no Redis needed
AGENTCOP_TRUST_RAG_STRICT=true
AGENTCOP_TRUST_HIERARCHY_STRICT=true
AGENTCOP_TRUST_ON_VIOLATION=raise
from agentcop.trust import TrustChainBuilder
# Reads configuration from environment variables automatically
chain = TrustChainBuilder.from_env(agent_id="production-agent").build()
# In-memory mode: no persistent storage, suitable for stateless containers
# Memory snapshots are held in process memory and discarded on shutdown
chain = TrustChainBuilder(
agent_id="production-agent",
memory_backend="memory://", # override env if needed
).build()
trust is not assumed. trust is earned, signed, and verified — at every step, by every component, across every runtime.