# Cryptographic AI Audit Trail: What the Cryptography Actually Proves

> Markdown mirror for AI agents, generated 2026-08-12 from the live page.
> Canonical: https://agenticrail.nz/blog/cryptographic-ai-audit-trail/
> Site context: https://agenticrail.nz/llms.txt

[AgenticRail](https://agenticrail.nz/)›[Writing](https://agenticrail.nz/blog/)›Cryptographic AI Audit Trail

 Security 2026-05-12 · reviewed 2026-07-22 Kade Cowper

# Cryptographic AI Audit Trail: What the Cryptography Actually Proves

A regular audit log records what a system **says it did**. A cryptographic AI audit trail proves what it **actually did** — and that the record hasn't been touched since. Not a matter of degree: a specific set of mechanisms — a signature over a canonical serialisation, a key ID, a hash chaining each receipt to the one before it, and an independently held archive. This walks through what each one does, and what happens when you remove it.

Every AgenticRail gate receipt is Ed25519-signed (legacy receipts before 2026-06-07 remain HMAC, verify-only) and independently verifiable offline. [Try the demo](https://agenticrail.nz/demo/) [Public keys](https://agenticrail.nz/spec/receipt-public-keys.json)

## What a regular audit log cannot prove

Most AI agent deployments produce audit logs — step names, timestamps, decisions, inputs, living in a database or a log aggregator. When an auditor asks what the agent did, you export the records and present them.

The problem isn't the content. It's that **nothing in the records proves they haven't changed** since they were written. A database row can be updated. A log file can be overwritten. An administrator with the right permissions can delete an inconvenient entry, and nobody outside the system can detect it.

The trusted-log problem

A regulator asks an AI operator to prove human oversight ran before each automated decision last quarter. The operator produces the logs. Every record shows the oversight step completed first.

The regulator's question: how do we know these records haven't been updated since? The operator's answer: access controls and a change-management process. The regulator's problem: that requires trusting the operator. The point of the requirement was evidence that doesn't.

## The mechanisms that make an audit trail cryptographic

Encryption protects data in transit and at rest — it says nothing about whether the data was modified. Cryptographic integrity is a different property, built from a specific set of mechanisms. Remove any one and the trail loses its tamper-evidence.

-

Mechanism 1

Signature over all fields (Ed25519)

Every current receipt is Ed25519-signed over all its fields, verifiable offline by anyone with the published public key. If any field changes after signing — decision, timestamp, step, nonce, any input — the recomputed signature won't match the stored one. Receipts written before 2026-06-07 use HMAC-SHA256 instead, kept for legacy verification only; new receipts are never HMAC-signed.
-

Mechanism 2

Canonical JSON serialisation

Signing operates on bytes, not objects. Before signing, the receipt is serialised to a canonical byte sequence — keys sorted alphabetically, no whitespace. Different serialisations of the same object produce different bytes and therefore different signatures; canonical form ensures the signer and any verifier, in any language, produce identical bytes for the same receipt.
-

Mechanism 3

Key ID in every record

Each receipt stores the ID of the signing key used — e.g. `k2_2026-06-07_ed25519`. Signing keys rotate periodically. Without a key ID, a verifier checking receipts after a rotation can't tell which key to use. With one, verification selects the correct key regardless of when the receipt was written, across any number of rotations, with no re-signing.
-

Mechanism 4

A hash chaining each receipt to the one before it

Every receipt carries `prev_receipt_hash` — a SHA-256 of the entire previous receipt's canonical content, signature included. Altering an earlier receipt breaks every hash after it, not just that record — a single tampered receipt is caught immediately, and where it broke is visible.
-

Mechanism 5

An independently held archive

The hash chain alone has one honest gap: someone holding the signing key could rewrite an entire chain and re-sign it consistently — internally coherent, still wrong. Sealed sequences are additionally copied, at the moment of sealing, to a separate write-once store the operator doesn't control the same way. A rewrite by the operator is then detectable by comparison against that independent copy, not just against itself.

## What each mechanism catches

| Attack or failure mode | Regular log | Cryptographic trail |
| Modify a DENY to ALLOW after the fact | Undetectable | Signature breaks on verification |
| Delete a record showing a violation | Undetectable | Breaks the hash chain from that point on |
| Change a timestamp to alter apparent order | Undetectable | Timestamp is a signed field — signature breaks |
| Rewrite an entire chain, re-signed with the real key | N/A | Not caught by the chain alone — caught by comparison against the independent archive |
| Verify old receipts after key rotation | N/A | Key ID selects the correct historical key |
| Third-party verification without system access | Impossible | Needs only the receipt and the public key |

That third-to-last row is the honest one, worth sitting with rather than glossing over: the signature and the hash chain protect against tampering by anyone *without* the signing key. They don't, alone, protect against the operator itself rewriting history — that's what the independent archive is for, and it's the reason it exists rather than being a redundant extra layer.

## What a cryptographic receipt actually contains

A real receipt shape — Ed25519, current

```
pack_id: "24449424...e020" // SHA-256
decision: "ALLOW"
reasons: []
executed: true // permitted — not proof the downstream action ran
meta: {
 model_id: "client:acme-underwriting",
 sequence_id: "underwriting-9f3a1",
 step: "bias_audit",
 function: "bias_audit",
 action_type: "VALIDATE_INPUT",
 policy_map_ids: ["msmd_policy_v1"]
}
payload_hash: "9080bd2a...86cb"
prev_receipt_hash: "b6a18d23...338d" // hash of the FULL prior receipt
ts_ms: 1747043892114
key_id: "k2_2026-06-07_ed25519"
signature_alg: "Ed25519"
signature: "TpQr8f3aXz9c2b1d..." // base64, over canonical JSON of everything above
```

None of these fields are metadata that can change after signing — every one is inside the signed content. `model_id`, `sequence_id`, `step`, `function`, and `action_type` live inside `meta`, not at the top level.

## Canonical JSON is not optional

System A serialises with a plain `JSON.stringify()`. System B sorts keys first. If the receipt's keys aren't already alphabetical, the two produce different byte sequences from the same object — different signatures — and System B incorrectly reports a genuine receipt as tampered. The problem compounds across languages: Python's `json.dumps()`, JavaScript's `JSON.stringify()`, Go's `encoding/json` all serialise the same object differently by default. A receipt signed in one and verified in another fails unless both use the same canonical form.

Canonical form

Keys sorted alphabetically at every nesting level, no whitespace, consistent number formatting, arrays in order. The same shape as [RFC 8785 (JSON Canonicalization Scheme)](https://datatracker.ietf.org/doc/html/rfc8785) — any conforming implementation produces identical bytes.

## How the chain was actually tested, not just described

On 2026-07-11, a sealed receipt was deliberately overwritten in storage with a fabricated version, without the real signing key. The live compliance report caught it immediately — signature invalid, chain broken. The receipt was restored and the report returned clean. Two things that test showed, worth stating plainly rather than just asserting: the hash chain alone can't protect its own last link (nothing commits to a chain's final receipt but its own signature), and a corruption made *with* the real signing key would re-sign cleanly and only be caught by the separate archive comparison — not by the chain or the signature alone. That's the honest division of labour between the two mechanisms, confirmed by actually trying to break it, not just claimed.

## What compliance frameworks actually require

None of EU AI Act Article 12, ISO 42001 A.6.1.6, or NIST Measure 2.4 use the word "cryptographic." All three require properties only cryptographic signing provides — and a cryptographic audit trail produces evidence toward each, without itself constituting full compliance with any of them.

EU AI Act · Article 12

Reconstruction of events

Requires records a regulator can verify without trusting the operator. Cryptographic signing makes that verification independent of the operator being trustworthy or even reachable.

ISO 42001 · A.6.1.6

Operational logging

Certification auditors need records that prove behaviour, not records that describe it. A signed receipt is evidence a decision was made and hasn't changed since — a database row requires trusting whoever administers the database.

NIST AI RMF · Measure 2.4

Tamper-evident monitoring

Requires monitoring that detects unexpected behaviour and preserves the evidence. A DENY receipt that caught a violation can't be quietly removed once written.

Run a sequence, generate a receipt, and verify it yourself against the published keys — no account, no callback to AgenticRail. [Try the demo](https://agenticrail.nz/demo/) [Verify a receipt](https://report.agenticrail.nz/report)

Related [AI Agent Audit Log Best Practices](https://agenticrail.nz/blog/ai-agent-audit-log-best-practices/)

What makes an audit trail evidence-grade rather than just a log — the requirements this post's mechanisms satisfy. [Are AI Agents Deterministic or Probabilistic?](https://agenticrail.nz/blog/deterministic-vs-probabilistic-ai-agents/)

Why the enforcement layer has to be deterministic even when the agent it governs is not. [Pre-Action Authorization for AI Agents](https://agenticrail.nz/blog/pre-action-authorization-ai-agent/)

Independent evidence that intercepting actions before execution beats catching them after. [The Completeness Specification](https://agenticrail.nz/spec/completeness/)

The eight requirements separating an evidence-grade record from an ordinary log, vendor-independent.
