Back to audit
← index

What a Signed Receipt Can and Cannot Prove About an Agent's Tool Call

Signatures are cheap. Binding a signed statement to the real world is not — and most "agent audit trail" designs quietly assume that problem away.

Engineering note · Correctover · 2026-09-15

The category error

When teams start instrumenting autonomous agents, a common shortcut appears: wrap every tool call in a signed envelope, hash-chain the envelopes, and call the result an audit trail. The cryptography works. The signatures verify. And the resulting artifact still may not support the claim people want to make with it — that this action happened.

That gap is not a bug in any particular library. It is structural, and it is worth being precise about, because an evidence system that overclaims is worse than no evidence system: it moves a security decision onto a foundation that cannot carry it.

What a signature actually establishes

Given a signature over a byte string S that verifies under public key P, you learn three things:

  1. The private key corresponding to P was used to produce this signature.
  2. S has not been altered since — any modification invalidates the signature.
  3. Therefore, whoever held that private key asserted S.

That is the whole list. Notice what is absent: any statement about whether S is true. A signature is an assertion by a key holder. It is not an observation of the world, and the two are routinely conflated.

The one-line version: a signature proves someone said this. Everything else you want from an audit trail is a separate problem, and each one has its own trust assumption.

Five things people believe they have proven

In practice, a signed tool-call receipt is often described as if it established the following. It does not, at least not on its own.

1. That the agent actually performed the action

A receipt is produced by software. If the same process that could fabricate the action can also reach the signing key, the receipt attests to an assertion, not to execution. Signing from inside the process you do not trust is circular.

2. That the action had the claimed effect

"Called refund_order with these parameters" and "a refund occurred" are different propositions. The first is knowable locally; the second lives in a system you do not control. Only the counterparty — or an independent log on their side — can speak to the effect.

3. That the inputs were authentic

A signature over a tool call says nothing about where the arguments came from. If untrusted content reached the model's context and steered the call, every signature in the chain still verifies. Provenance of inputs is a separate control, and it has to be captured before the model acts, not after.

4. That a human authorized it

Unless there is a distinct authorization artifact, produced by a different key holder, and bound to the same request identifier as the execution record, "the agent signed it" is not evidence of human intent. Two independently signed facts are only useful if something ties them together.

5. That the business fact is true

This is the one that tends to surface late, usually during an incident review or an audit. Integrity of a record and truth of its contents are orthogonal. A perfectly signed, perfectly chained log of fabricated events is still a log of fabricated events.

Where the trust actually lands

The useful question is never "is it signed." It is "who is the signer, and what would it take for that signer to lie?" Every design puts the root somewhere:

There is no configuration in which the trust root is empty. The design work is choosing where it sits, and being explicit about it in the documentation rather than in a footnote.

What hash chaining does and does not buy you

Append-only structures and Merkle inclusion proofs are genuinely useful, but for narrower properties than they are often credited with.

They give you consistency: given a signed tree head you have previously retained, an operator cannot silently rewrite history without detection. They give you inclusion: a specific record is provably in the log.

They do not give you completeness. "There is no record of X" is not provable from an inclusion proof. Absence claims require either an exhaustive log or an operator you already trust.

They do not give you truth. A log faithfully preserves whatever was written to it.

The pinning detail matters more than it looks. If you never retain a signed tree head, the operator can present different, internally consistent histories to different verifiers. The log becomes a coordination device rather than an evidence device.

The binding problem

Most real failures are not cryptographic. They are failures to bind signed statements to the events they are supposed to describe.

A layered model

It helps to be explicit about which layer a given artifact covers, and to refuse to describe one layer using another's language.

LAYER 0 — INTENT
What was authorized, by whom, with what scope and expiry. Signed by an authority distinct from the executor.
LAYER 1 — EXECUTION
What the runtime attempted: tool identity, arguments, the decision that admitted the call. Knowable locally. This is where most "agent audit" designs stop.
LAYER 2 — EFFECT
What the downstream system observed. Requires the counterparty to co-sign or to keep its own independent log. Cannot be manufactured locally.
LAYER 3 — ENVIRONMENT
Attestation about the platform the runtime ran on. Moves the trust root rather than removing it.

The common overclaim is to produce a Layer 1 artifact and describe it in Layer 2 terms. That is the specific failure worth designing against.

A checklist for any receipt format

Questions worth asking before an evidence format goes into a security narrative:

  1. Who holds the signing key, and what else can that process do?
  2. What identifier binds this receipt to the authorization it claims to implement?
  3. Is there a validity window? What is the semantics at key rotation?
  4. Is there a notion of time that does not depend on the signer's own clock?
  5. If the log operator is malicious, what exactly do you detect — and what requires a pinned tree head?
  6. Does this artifact claim an attempt, or an effect? Which word does the documentation use?
  7. Who could produce a receipt for an action that never happened, and what prevents it?
  8. When verification fails, does the system fail open or fail closed?

Why the precision is worth it

The failure mode is not a broken signature. It is a true statement used to support a false one. "This receipt is valid" and "this action occurred" are both reasonable sentences, and only the first follows from the cryptography.

The honest framing: a receipt bounds the set of stories that can be told about a run. It narrows the space. It does not, by itself, select the true story — that requires the layers above, each with its own signer and its own explicit trust assumption. Being clear about which layer you have is what keeps an evidence system from becoming a liability during the incident where it is needed.