All posts
Architecture8 min read

Hash-chained receipts: audit logs your auditor can verify

Traditional audit logs ask your auditor to trust your database. Signed, hash-chained receipts let anyone verify — independently, offline — that the record is complete and untampered.

PN
Priya Natarajan
Co-founder & CTO

Ask a security engineer what protects their audit log and the honest answer is usually 'permissions.' The log is a table; the table has restricted write access; therefore the log is trustworthy. But that argument protects the log from outsiders, not from the operator — and the operator is exactly who an auditor is being asked to check. A log that its owner can silently edit is testimony, not evidence.

govern.sh takes a different position: the audit trail should be verifiable by someone who distrusts us and distrusts you. Every action an agent takes produces a receipt, every receipt is signed, and every receipt binds itself to the one before it. The result is a structure where tampering isn't prevented by access control — it's made self-evident by arithmetic.

Anatomy of a receipt

A receipt is a small canonical document: who acted (the agent's passport ID and public key), what they did (tool, verb, a digest of the parameters), what the policy said (the verdict, the policy version that produced it, and the approver identity if a human signed off), and when. Two fields turn this record into a chain: prev_hash, the SHA-256 of the previous receipt in the workspace's chain, and a sequence number. The whole document is then signed with Ed25519.

JSON
{
  "seq": 481223,
  "agent": "ap_7f3k...",
  "agent_key": "ed25519:mAX2...",
  "action": { "tool": "stripe", "verb": "refund.create", "params_sha256": "9c1e..." },
  "verdict": { "result": "allow", "policy_version": "42" },
  "issued_at": "2026-04-14T09:12:44.031Z",
  "prev_hash": "sha256:f2ab41...",
  "signature": "ed25519:sig:Kj9w..."
}

Signing uses canonical serialization — sorted keys, fixed number formatting, UTF-8 — because a signature over ambiguous bytes is a signature over nothing. The parameters themselves are digested rather than embedded, so the chain never becomes a second copy of your sensitive payloads: you can prove what an agent sent without the audit trail storing it.

What the chain actually guarantees

  • Tamper evidence: editing any historical receipt changes its hash, which breaks the prev_hash of every subsequent receipt. There is no quiet edit — only a rewrite of the entire suffix, which the next property makes detectable.
  • Completeness: sequence numbers plus chaining mean deletion is as visible as modification. A gap in seq or a prev_hash that doesn't match is a finding in itself.
  • Attribution: each receipt is signed by keys the operator doesn't hold — action receipts by the platform signer, with the acting agent's public key embedded. A forged receipt requires a forged signature, not just database access.
  • External anchoring: every 10,000 receipts (or hourly, whichever comes first), the chain head is published to an external transparency log. Rewriting history now requires rewriting a record outside anyone's unilateral control.

Verification without trust

The point of all this is the verifier, and the verifier is deliberately boring. It's a few hundred lines, open source, with no network dependency on govern.sh: feed it an exported receipt bundle and the public keys, and it recomputes every hash, checks every signature, validates sequence continuity, and compares chain heads against the published anchors. Your auditor can run it on a laptop with the WiFi off. If we disappeared tomorrow, every receipt you've exported remains exactly as verifiable as it is today.

Bash
$ govern verify --bundle q1-receipts.jsonl --keys workspace-keys.json
Verifying 1,204,118 receipts...
  hash chain      OK (0 breaks)
  signatures      OK (1,204,118 valid)
  sequence        OK (contiguous 0..1204117)
  anchors         OK (121 of 121 match transparency log)
Chain head: sha256:44e1a9...  VERIFIED

Why not a blockchain?

Because the problem doesn't need one. Consensus solves the question of who may append when writers distrust each other; here there is a single writer per workspace, and the property we need is that the writer can't rewrite what it already wrote. A hash chain with external anchoring delivers that with microsecond appends and no gas, no validators, and no new trust assumptions. We use the boring 40-year-old construction — the same lineage as Certificate Transparency — because boring is what you want under your evidence.

In practice, this changes the texture of an audit. Instead of sampling screenshots and interviewing engineers about log retention, an auditor takes an export and a public key and checks the math. One of our customers closed a SOC 2 evidence request that historically took two weeks of engineer time in a single afternoon. Evidence that verifies itself is cheaper for everyone — including the people checking you.

Your agents are already out there.

Give them identity worth trusting. Mint your first passport in under five minutes — free for three agents, no credit card.