Open SCITT profile · early-stage draft (IETF Internet-Draft) · open source

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.)

Built on IETF SCITT (RFC 9943) Verifier + producer, open source Cross-implementation tested (RFC9162 · CCF)
In plain terms

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? →

The problem

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.

Signed

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.

Transparent

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.

Third-party verifiable

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.

Add it to your stack

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:

Goose — pip install capsule-emit · FastMCP extension
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 extension
Goose adapter docs ↗ · verified end-to-end against Goose v1.39.0 ↗
MCP / any callable — pip install capsule-emit
from 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)
MCP adapter docs ↗
LangChain / LangGraph — pip install capsule-emit langchain-core
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]})
LangChain adapter docs ↗
CrewAI — pip install capsule-emit crewai
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])
CrewAI adapter docs ↗
Hermes / any custom loop — pip install capsule-emit
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
Hermes adapter docs ↗
agentgateway — seal at the gateway chokepoint (one policy point, not N integrations)
# 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 gracefully
agentgateway adapter docs ↗ · verified at ExtMcp gRPC protocol boundary ↗

Don't see your framework? The base is ~30 lines — add an adapter or open a request ↗. Full guides live in capsule-emit/docs/adapters.

What's sealed

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:

Decision

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.

Attestation

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.

Chain

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.

capsule_id (the seal) · sealed ✓
operator 4515…10de · developer po-agent@v1 · decide → executed · input 18e7…ba81 · output 406f…9c54
Explore a capsule

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 →

The stack

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.

layer 1The profile
the standardagent-action-capsule — the Signed Statement format (COSE_Sign1 over application/agent-action-capsule+json) + the reference verifier.
↓ produced by
layer 2The producer
capsule-emit — seal an action in one call, or wrap an existing tool with one decorator. The agent-developer on-ramp.
↓ registered to · receipt verified by
layer 3The verifier
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).
↓ anchored to
layer 4The log
capsule-anchor — a neutral, product-free SCITT Transparency Service. Live at anchor.agentactioncapsule.org.
How it fits your stack

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.

LegAnswersDoesn't answer
WHO — Identity e.g. SPIFFE/WIMSE, agent IDswhich accountable principal — who the agent iswhat it did
CAN — Authorization e.g. OAuth/AAuth, GNAP, policywhat it may dowhat it actually did, and the outcome
Payments / settlement e.g. AP2whether a human authorized the spendwhat was actually done, end-to-end
AUDIT — Runtime gate / observability e.g. a policy gateway, your logswhat you say happenednothing to a party who doesn't trust you — it's self-attested
WHAT — Agent Action Capsulewhat it provably didcomposes 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 →

Canonical Payload Binding & Composition

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.

jcs-n

One canonicalization

RFC 8785 JCS over the normalized value — the same algorithm any independent implementation can run to recompute the digest.

Typed reference

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.

Open registry

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 ↗

Verify

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
1

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.

2

Signature + inclusion, independently

The signature proves who sealed it; the receipt proves the log included it. Both check from the bytes.

3

VDS-agnostic

The same statement verifies whether the log uses RFC 9162 Merkle proofs or Microsoft CCF. The action layer never changes.

Disclosure

Hand someone the record — not your word for it.

Because a capsule verifies from the bytes, you can give an auditor, a reviewer, or a regulator the capsules for what your agent did and say: here's what happened — don't trust me, check it yourself. They confirm each seal and the chain links with no access to your systems, and the contents stay private — digests, not raw data.

Adoption path

One config change per rung — start in ten minutes, scale as you need.

Rung 1 · Stub

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

Rung 2 · Self-hosted anchor

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

Rung 3 · Public anchor

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 ↗

What leaves your walls

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.

Public log

Zero-setup proofs

Anchor to the shared, open log at anchor.agentactioncapsule.org. A digest + timestamp leaves; your data never does.

Your region

Residency control

Run the open anchor in the region or jurisdiction you need (e.g. EU, Singapore). The hash stays in your jurisdiction.

Your VPC

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 →

Interop

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.

TEST VECTORS · CONTRIBUTED UPSTREAM · NOT A WG ENDORSEMENT

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 ↗
TESTED AGAINST · MICROSOFT CCF

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 ↗
PREPARING · IETF 126

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 ↗
Open source

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 →

Who's behind this

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.

Playground

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.

Get involved

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:

Adopt

Seal your agent's actions

Wrap a tool with one decorator, anchor each call, and verify from the bytes.

Quickstart → Adopters — start here ↗
Contribute

Add an adapter

Bring your framework's seam onto the shared base, or open a request — so producers stay one format.

capsule-emit ↗
Shape it

Help the standard

The profile is an individual IETF Internet-Draft. Review it, bring test vectors, and engage in SCITT.

Read the draft ↗
Adopters & interop

Who's already using it.

Adopter quotes and interop results arriving here. Building? Start with ADOPT.md ↗ — 30-minute self-serve path from zero to anchored, verified capsule.

New here? Read how the project is governed → · Join the conversation on GitHub.