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.
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:
- The private key corresponding to
Pwas used to produce this signature. Shas not been altered since — any modification invalidates the signature.- 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.
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:
- The agent runtime signs. You trust the runtime, its configuration, and its key custody.
- A sidecar monitor signs. You trust the monitor — and you additionally need coverage: what happens to calls that route around it?
- The remote server signs. You trust the counterparty, which is fine if that is the point, and useless if it is not.
- A hardware enclave signs. You trust the silicon vendor and the attestation chain — the root moved, it did not disappear.
- A timestamping authority signs. You trust its clock and its refusal to backdate.
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 binding problem
Most real failures are not cryptographic. They are failures to bind signed statements to the events they are supposed to describe.
- Identifier binding. The authorization record and the execution record must reference the same identifier. Otherwise a valid receipt for action A can be presented as evidence about action B.
- Replay. A valid signature from last week is still a valid signature. Without a nonce and a validity window, receipts are transferable across time.
- Expiry and rotation. Receipts need a notion of "valid at the time of use," and a documented story for what happens when keys rotate. A receipt whose verification semantics change at rotation is not a durable artifact.
- Key custody inside agents. Agents typically run in shared, frequently rebuilt environments. A key that lives alongside the code has the same blast radius as the code.
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.
What was authorized, by whom, with what scope and expiry. Signed by an authority distinct from the executor.
What the runtime attempted: tool identity, arguments, the decision that admitted the call. Knowable locally. This is where most "agent audit" designs stop.
What the downstream system observed. Requires the counterparty to co-sign or to keep its own independent log. Cannot be manufactured locally.
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:
- Who holds the signing key, and what else can that process do?
- What identifier binds this receipt to the authorization it claims to implement?
- Is there a validity window? What is the semantics at key rotation?
- Is there a notion of time that does not depend on the signer's own clock?
- If the log operator is malicious, what exactly do you detect — and what requires a pinned tree head?
- Does this artifact claim an attempt, or an effect? Which word does the documentation use?
- Who could produce a receipt for an action that never happened, and what prevents it?
- 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.