Prove what your agent did —
to someone who doesn’t trust you.
AI agents are just starting to take consequential actions — placing orders, moving money, changing records. When one does, the only proof it happened as intended is the operator's own word. An Agent Action Capsule fixes that: a tamper-evident, content-private record of the action that anyone can verify from the record itself — without trusting the operator.
It's early — for the technology and for this profile. The aim is to get the record of what agents do right while it's still being figured out: in the open, verifiable by anyone, and built to be donated so it ends up owned by no one. (Roughly the role TLS plays for a connection, applied to an agent's actions.)
A tamper-evident receipt for what your AI agent did.
Say your agent pays an invoice. Six months later an auditor asks: did it really only pay approved vendors, for the right amounts? Today your only answer is your own logs — your word for it. An Agent Action Capsule is a signed, privacy-preserving receipt of each consequential action, so you can hand the auditor proof they can check for themselves — without giving them access to your systems, and without asking them to trust you.
Who it's for today: agent developers who want verifiable records, and standards / security folks. It's early and built in the open — not yet a turnkey compliance product. What exactly is a capsule? →
Agents take actions. Right now, you have to trust the operator that they happened as claimed.
The Agent Action Capsule closes that gap with three properties — the same shape SCITT (the IETF effort standardizing transparency for signed statements, now standardized in RFC 9943 (the SCITT Architecture), with the COSE Receipts specification now published as RFC 9942) defines for software supply chains, profiled for agent actions.
Sealed at the moment of action
A capsule is a statement committing to the action, its inputs and outputs (by digest), and the model/runtime that produced it — content-addressed by default, and COSE-signed at the Signed-Statement tier (COSE is the standard format for signing records like this). Tamper any byte and verification fails.
Anchored to an append-only log
The statement is registered to a SCITT Transparency Service, which returns a receipt proving inclusion. The log can't quietly drop or rewrite history.
Anyone can check, offline
An auditor, reviewer, or regulator verifies the signature and the inclusion proof from the bytes alone — no access to the operator's systems. You trust the log's key, not the operator.
Seal from the framework you already use.
One capsule, one anchor, one verify — an adapter only changes where you hook in, over a ~30-line base. No protocol change; input and output are sealed automatically. Adapters seal consequential actions (writes + sensitive reads), not every call — what counts? → Pick your runtime and copy the code:
from mcp.server.fastmcp import FastMCP
from capsule_emit.adapters.mcp import MCPCapsuleEmitter
server = FastMCP("po-agent")
emitter = MCPCapsuleEmitter(operator="acme-co", developer="goose-agent@v1")
@server.tool() # Goose connects over MCP
@emitter.tool(effect_type="write_order") # capsule-emit seals every call
def submit_order(vendor, amount, po_number):
return place(vendor, amount, po_number)
server.run() # stdio — add to Goose as an extensionfrom capsule_emit.adapters.mcp import MCPCapsuleEmitter
emitter = MCPCapsuleEmitter(operator="acme-co", developer="po-agent@v1")
@emitter.tool("submit_order") # one line — every call sealed + anchored
def submit_order(vendor, amount, po_number):
return place(vendor, amount, po_number)from capsule_emit.adapters.langchain import LangChainCapsuleEmitter
emitter = LangChainCapsuleEmitter(operator="acme-co", developer="research-agent@v1")
# attach as a callback — every tool call on the run is sealed
agent.invoke(payload, config={"callbacks": [emitter]})from capsule_emit.adapters.crewai import CrewAICapsuleEmitter
emitter = CrewAICapsuleEmitter(operator="acme-co", developer="ops-agent@v1")
safe_tool = emitter.wrap(my_tool) # one capsule per tool call
agent = Agent(role="AP clerk", tools=[safe_tool])from capsule_emit.adapters.hermes import HermesCapsuleEmitter
emitter = HermesCapsuleEmitter(operator="acme-co", developer="hermes-agent@v1")
result = execute_tool(name, inputs)
emitter.after_tool(name, inputs, result) # one line at the tool boundary# 1. run the capsule-emit policy service (gRPC ExtMcp hook)
pip install "capsule-emit[agentgateway]"
capsule-emit-agentgateway # listens on :50051
# 2. point agentgateway at it — seal tools/call only (in config.yaml)
mcpGuardrails:
processors:
- kind: remote
host: "localhost:50051"
methods: { "tools/call": full } # reads pass through
failureMode: failOpen # capsule outage degrades gracefullyDon't see your framework? The base is ~30 lines — add an adapter or open a request ↗. Full guides live in capsule-emit/docs/adapters.
Purpose-built for agent actions — not generic attestation.
Its tamper-evident seal is the capsule_id — a SHA-256 of the statement's canonical form (RFC 8785 JCS); recompute it and it must match. And it's content-private by construction: a capsule carries digests of your inputs and outputs, never the raw prompts, vendors, or amounts. Around that seal it commits exactly what an agent action needs to be accountable:
The may/did, bound to its effect
What the agent decided and whether it executed, was confirmed, denied, or blocked — with a confirmed-effect binding, so the claim and the real outcome can't drift apart.
Which model decided, by digest
The model that decided, with the full input it saw — system prompt, context, tools, and the action's arguments — and the output, each committed as a SHA-256 digest. The proof travels; the raw values stay with you.
Trails for human-in-the-loop
Confirm, supersede, and escalate links turn approved → executed → confirmed into one verifiable chain — the basis for review and selective disclosure.
That's the shape a build-artifact attestation doesn't give you — and the reason to standardize one agent-action profile together rather than reinvent it. What's in a capsule → · tamper one, watch the seal break →
One statement layer. Any transparency service. Neutral, donatable substrate.
The capsule is a statement-layer profile — it makes no claim about which verifiable-data-structure the log uses. Each layer is a separate open-source library.
agent-action-capsule — the Signed Statement format (COSE_Sign1 over application/agent-action-capsule+json) + the reference verifier.capsule-emit — seal an action in one call, or wrap an existing tool with one decorator. The agent-developer on-ramp.scitt-cose — verifies SCITT receipts across verifiable-data-structures (vds = the log's proof format): RFC9162_SHA256 (vds=1) and CCF ccf.v1 (vds=2).capsule-anchor — a neutral, product-free SCITT Transparency Service. Live at anchor.agentactioncapsule.org.Composes with what you already run — it doesn't replace it.
Identity, authorization, payments, runtime gates — each proves its own slice, and each is self-attested about it. The capsule composes with all of them by digest-reference, and adds the one thing none can self-provide: a record checkable by someone who trusts neither the operator nor any single layer.
| Leg | Answers | Doesn't answer |
|---|---|---|
| WHO — Identity e.g. SPIFFE/WIMSE, agent IDs | which accountable principal — who the agent is | what it did |
| CAN — Authorization e.g. OAuth/AAuth, GNAP, policy | what it may do | what it actually did, and the outcome |
| Payments / settlement e.g. AP2 | whether a human authorized the spend | what was actually done, end-to-end |
| AUDIT — Runtime gate / observability e.g. a policy gateway, your logs | what you say happened | nothing to a party who doesn't trust you — it's self-attested |
| WHAT — Agent Action Capsule | what it provably did | composes with all of the above |
Each layer is self-attested about its own slice; the capsule is the independent record of what was actually done that they all commit into. Adopting it doesn't fork your stack — it references the others' evidence by digest. How it composes → · what's worth sealing →
The composition crux: every profile speaks the same binding language.
The Agent Action Capsule seals SHA-256 digests of your inputs and outputs — not the raw bytes. The precise construction (how those digests are canonicalized, derived, and referenced across profiles) is defined in a companion IETF draft: the Canonical Payload Binding (CPB). A second companion draft, Agent Accountability: Composition and Conformance, defines how independently-verifiable profiles — CAN, WHO, WHAT, AUDIT — compose into one record by a shared action digest, and the conformance-vector suite that tests it. CPB is the shared seam that makes that composition possible without drift.
One canonicalization
RFC 8785 JCS over the normalized value — the same algorithm any independent implementation can run to recompute the digest.
Reference by digest, not copy
External evidence (authorization grants, policy decisions, upstream receipts) binds by its SHA-256 digest. The referenced data stays where it lives; only the commitment travels.
Owner-authored, conformance-checked
The Agent Action Capsule is the first registered payload profile; MachineMandate is registering as the second. Each entry is owner-authored and checked against a real conformance-vector suite — mutation-tested, not a rubber stamp.
Conformance status: the Python reference implementation passes the full CPB vector suite (CI-verified); a second independent implementation, in TypeScript, is in progress.
The full picture — composition, the open registry, and the conformance bar →
CPB spec: draft-mih-sokolov-scitt-payload-binding-01 ↗ · Composition spec: draft-mih-sato-agent-accountability-composition-00 ↗ · Registry: registries of record ↗ · Vectors: conformance vectors ↗
From the bytes. Offline. Trust the log's key — not the operator.
This is what an auditor runs against a ledger of capsules. Tamper any field and ok turns false.
# install the reference verifier pip install agent-action-capsule # verify a ledger of sealed actions, offline agent-action-capsule verify --store ledger.jsonl capsule_id 9f2a…c14 ok capsule_id 4b07…8de ok # inclusion on the public log: substrate.receipt_verified: True
Inputs & outputs committed by digest
The capsule seals SHA-256 digests of what went in and came out. Raw values stay local; the proof travels.
Signature + inclusion, independently
The signature proves who sealed it; the receipt proves the log included it. Both check from the bytes.
VDS-agnostic
The same statement verifies whether the log uses RFC 9162 Merkle proofs or Microsoft CCF. The action layer never changes.
One config change per rung — start in ten minutes, scale as you need.
Structured records, offline verify
Set CAPSULE_ANCHOR=false. Structured records, local ledger file, offline verification. Zero services. The ten-minute first touch — no network, no account.
Page renders: self-attested / not anchored
Real receipts, your trust domain
Deploy your own capsule-anchor instance. Real inclusion receipts within your org — tamper-evident across teams, honest internal separation of duties.
Policy descriptor tier: self-operated
Third-party verifiable
One config change: point at the public anchor. Records become third-party-verifiable; permalinks are shareable. No signup, no key, no cost.
Policy descriptor tier: public
Full adoption guide: ADOPT.md ↗
Only a hash leaves. Anchor anywhere — including your own VPC.
A capsule is content-private by construction. When you anchor it, the only thing that travels to the log is a digest and a timestamp — never prompts, payloads, reasoning, or PII. The raw content stays under your control.
Zero-setup proofs
Anchor to the shared, open log at anchor.agentactioncapsule.org. A digest + timestamp leaves; your data never does.
Residency control
Run the open anchor in the region or jurisdiction you need (e.g. EU, Singapore). The hash stays in your jurisdiction.
Nothing leaves
Self-host the anchor container inside your own environment — then even the hash never leaves your walls.
The capsule is anchor-agnostic, so you can move or mix anchors without changing the record. One caveat: a digest only hides values that aren't guessable — for low-entropy fields (a short amount, a known ID), salt before hashing. What a digest hides →
Tested against other implementations — not just our own.
The statement layer is fixed; the verifiable-data-structure is the log's choice. We've proven that holds across vendors.
Shared test vectors
Our RFC9162_SHA256 cross-implementation vectors were contributed to, and merged into, the SCITT working group's examples repository — a reference anyone can verify against. It's a merged contribution, not a WG endorsement of this profile.
ietf-wg-scitt/examples ↗Two-party, two logs
One capsule, registered to our RFC9162 log and a real Microsoft CCF node — both receipts verify under our verifier stack. (CCF uses vds=2; RFC 9162 uses vds=1.) Tested against CCF; not a Microsoft endorsement.
scitt-cose ↗Implementation report
We intend to bring an implementation report and the shared test vectors to the SCITT working group at IETF 126 (Vienna) — connecting the verifier, the vectors, and the plug-fest.
AAC: draft-mih-scitt-agent-action-capsule-02 ↗ · CPB: draft-mih-sokolov-scitt-payload-binding-01 ↗Every layer is open source.
Read it, run it, fork it. The tooling is Apache-2.0; the specification follows the IETF Trust's terms (BCP 78/79, with code components under the Revised BSD License). Built to be donated to a neutral home, not owned.
Scope. The open project is the record layer — the profile, the producer (with example constraint manifests), the verifier, and the anchor. Acting on those constraints at runtime (enforcement) is a separate concern you compose with a policy gateway: the capsule records what happened, it doesn't gate. How the project is governed →
Built by an agent developer who wanted proof, not promises.
The Agent Action Capsule was created by Steven Mih — a startup founder and agent developer with a long background in open source, including helping steward openly and neutrally governed software (the Presto Foundation, under the Linux Foundation). He built it after hitting the wall everyone building agents hits: once an agent takes a real action, the only "proof" it happened as intended is the operator's own word. The capsule is the answer — a verifiable record anyone can check, built to be owned by no one.
Why build it this way? Verifiable records of what agents do are infrastructure the whole ecosystem depends on — and we think AI safety and open standards matter far too much for that layer to be controlled by any single company. So the design goal from day one is to give it away.
Where it stands today. The project is stewarded by Action State Group, which also operates the reference services (the public log and the verifier) for now — with the explicit intent to donate the profile, the trademark, and the services to a neutral foundation as the ecosystem matures. The governance model is public and modeled on Linux Foundation practice, and co-maintainers are welcome to join. Read the governance model → · comments on the draft are welcome at spec@actionstate.ai and in the IETF SCITT working group.
Mint your own capsule — in under 60 seconds.
One button. No signup. No install. Your agent action sealed client-side, anchored to the public log, and handed back as a shareable permalink anyone can verify.
Playground launching soon — see the quickstart to seal your first capsule now.
An open profile to shape together — not another silo to fork.
The capsule is open and built to be donated. The useful move is to improve one shared profile together — feedback, competing ideas, and adapters all welcome. Ways in:
Seal your agent's actions
Wrap a tool with one decorator, anchor each call, and verify from the bytes.
Quickstart → Adopters — start here ↗Add an adapter
Bring your framework's seam onto the shared base, or open a request — so producers stay one format.
capsule-emit ↗Help the standard
The profile is an individual IETF Internet-Draft. Review it, bring test vectors, and engage in SCITT.
Read the draft ↗Who's already using it.
New here? Read how the project is governed → · Join the conversation on GitHub.