OWASP AST09: execution receipts for AI agents
AST09 is the "missing execution receipts" entry in the OWASP Agentic Skills Top 10 — the risk that an AI agent takes an action and leaves behind nothing a third party can trust. This page explains what the entry asks for, the bilateral receipt pattern that is its normative guidance, and how to satisfy it in a few lines of code.
What AST09 is
The OWASP Agentic Skills Top 10 catalogs the ways autonomous agent "skills" go wrong. AST09 is the accountability gap: when an agent invokes a tool, moves money, or reads a record, the operator usually keeps an ordinary log — on their own infrastructure, editable and deletable by them. Anyone auditing that log has to trust the exact party whose behavior they are auditing. AST09 names that as a distinct risk class and asks for records that survive scrutiny by an outside party.
The bilateral receipt pattern (the normative guidance)
The pattern that answers AST09 is a pair of signed receipts per action. It is normative guidance in the AST09 entry (PR #35, merged by project lead Ken Huang):
- Admission receipt (before the action): who is acting, what they intend, the authorized scope, and the policy version in effect.
- Outcome receipt (after the action): what actually happened, linked to the admission by a content-derived hash.
Both records are canonicalized with JCS (RFC 8785) so any conformant implementation serializes them to identical bytes, then signed with Ed25519 and hash-chained. The concrete hash construction that links the two receipts — the action_ref — is published in the OWASP solutions catalog (PR #38) rather than the normative page itself. Because action_ref is derived from the content of the action (agent id, action type, scope, timestamp), anyone can recompute it, and the operator cannot forge or quietly re-point it.
Why this clears the bar that a log does not
- Tamper-evident: altering a record invalidates its signature; deleting one leaves a gap in the hash chain.
- Independently verifiable: a third party checks a receipt offline with just the receipt and a public key — no access to the operator, and no trust in them.
- Bound to authority: the admission receipt pins the authorized scope, so an out-of-scope action is visible as a mismatch rather than buried in a log.
Implementing AST09 receipts
Nobulex is the open-source (MIT) reference implementation of the bilateral receipt pattern. Adding conformant execution receipts to an existing agent function is one decorator:
from nobulex import track
@track(agent_id="billing-bot")
def charge(invoice_id: str, amount_cents: int):
... # your existing code, unchanged
Each call now emits an admission receipt and an outcome receipt, linked by action_ref, signed and chained. A denied action still produces a signed admission record, so "the agent was stopped" is auditable too — not a silent hole.
Verifying a receipt
Verification recomputes action_ref from the record and checks the Ed25519 signature against the agent's published public key. It runs fully offline — no callback to the operator, the platform, or Nobulex:
from nobulex.agent import Agent
agent = Agent("billing-bot")
receipt = agent.act("charge", scope="invoice:042")
assert receipt.verify() # recomputes action_ref, checks the signature, offline
Change one byte of a receipt and verify() returns false. That is the whole guarantee AST09 is after.
How AST09 relates to regulation
The same records that satisfy AST09 map cleanly onto the EU AI Act (Regulation (EU) 2024/1689), Article 12, which requires high-risk systems to keep automatically generated logs that enable post-hoc verification of how the system operated (enforcement from December 2, 2027). A log the operator can silently rewrite does not clear that bar; a signed, independently verifiable receipt does. See the EU AI Act compliance guide for the article-by-article mapping.
Getting started
pip install nobulex
# or
npm install @nobulex/core
There is a live tamper demo and a ten-line verify in the repository. For a step-by-step build, see the verifiable audit trail guide; for common questions, the FAQ.
