# Tamper-evident tamper-proof: what an agent audit log can actually prove

> Source: <https://dev.to/rojaneerdev/tamper-evident-tamper-proof-what-an-agent-audit-log-can-actually-prove-129b>
> Published: 2026-10-23 02:29:31+00:00

Open any "AI agent governance" page and you'll find the phrase **tamper-proof audit log**. Treat it as a tell. No append-only file on a machine someone administers is tamper-proof, and a vendor who says otherwise is either not thinking hard about it or hoping you won't.

So let's do the un-sexy thing and be precise. In [an earlier post](https://dev.to/rojaneerdev/from-god-mode-to-governed-an-ai-agent-that-cant-exceed-its-grant-4ilk) I showed an agent acting as a human and leaving a receipt. This post is about **how much you can actually trust that receipt** — what it genuinely proves, the three places it honestly can't, and — the part most "trust" posts skip — *which of those are shipped and which I'm still building.* All runnable from the Apache core; verify it yourself.

The ledger is an **append-only, hash-chained** file: each event carries the SHA-256 of the exact bytes of the event before it, so the records form a chain. `agenthof audit verify <run>` walks it:

``` bash
$ agenthof audit verify r-85f417c6…
head: 4d655340… (13 events)
```

That gives you one real, strong guarantee: **any edit, deletion, or reordering of a committed event breaks the chain and fails `verify`.** Change one byte of one event, drop a line from the middle, swap two — the hashes stop matching from that point on. For honest mistakes (a corrupted write, a botched migration) and lazy tampering, that's genuine and it's free.

That is **tamper-*evident*.** It is not tamper-*proof*, and the difference is the whole post.

The chain protects *committed* events. But if an attacker controls the whole file, they can delete the **tail** — the last N events — and recompute a perfectly valid chain from a clean point. Nothing inside the file betrays it; a shorter valid chain looks exactly like a run that simply did less.

You can't win this *locally*. The only defense is a **head recorded somewhere off the machine** — then you compare. Two shipped ways, and they are *not* equally strong, so I'll be exact:

`agenthof audit verify --expect-head sha256:<hex>`. Real, but only as independent as wherever `agenthof audit anchor` pins the current head into a `audit verify control` then checks every recorded anchor against the chain. Now a whole-root rewrite is detectable by a `audit seal` to rotate the ledger into sealed segments. So the honest scorecard on truncation: **solved for the governance ledger** (independent anchor, today), and for the **per-run receipt** it's the manual `--expect-head` path — bringing automatic anchoring to the per-run receipt too is **reserved, not yet built.** I'd rather tell you that than let you assume your run receipts are anchored to a transparency log. They aren't yet.

Here's the subtle one, and a reader pushed on exactly it, correctly. `verify` proving the chain is unbroken does **not** prove the chain is *complete*. If a door acted but its event was never written — a transient write failure, or a code path that forgot to record — the chain still verifies *perfectly*. The events that are there are untampered; you just can't tell that one is *missing*.

And — important — **cryptography cannot fix this.** You can't cryptographically prove the existence of a record that was never created; a dropped event leaves no missing signature, because the signature would have been *on* the dropped event. Signing gives you integrity, not completeness. Completeness is an **accounting** problem, not a crypto one.

Where it stands, honestly: today sequence numbers catch a dropped *tail*, and containment means a governed action has to pass through a recording door — but detecting a *silently dropped* door event is **in design, not shipped.** The approach is accounting, not crypto: have the gateway count the calls it handled at its ingress and check that the ledger holds that many, so a missing one *fails* `verify`. I'm building it because the gap is real. When this post says a limit is closed, it'll be because I ran it — and this one isn't closed yet.

The ledger is written by the operator's own gateway. So "nobody tampered" ultimately rests on trusting *your* gateway — and in a regulated setting the first question is *who checks, and what does it cost when it's wrong?* The honest answer isn't "trust my gateway." It's to put the **evidence** somewhere that isn't yours — which is exactly what the transparency-log anchor does for the governance ledger: the corroborator is a party neither the agent nor the operator controls. Independence comes from **where the record is anchored, not from the gateway being neutral** — because it isn't neutral, and claiming it is would be the same move as "tamper-proof."

Put it in one picture:

None of those rows say "tamper-proof," and that's the point. A guarantee you can **run yourself** and whose **limits are stated** is worth more than a marketing adjective. You don't have to trust me: `agenthof audit verify`, `audit verify control`, and `--expect-head` are in the repo, and the honest-limits are written into the docs, not a footnote.

This is **[Agenthof](https://github.com/agenthof/agenthof)**, Apache-2.0. It's early, and as you can see I'll tell you exactly where the edges are — including the one I'm still building. If "tamper-proof" makes you flinch too, the repo's [here](https://github.com/agenthof/agenthof), and `verify` is yours to try.

Next post: **containment by construction** — an agent with no network and no secrets, so the bad outcome isn't *forbidden*, it's *impossible*.
