AI agent audit trails:
what they are, and how to verify one.

An agent that can act on your business needs a record of what it did. The hard part is not writing the record. It is being able to prove, later, that the record was not changed. This guide covers what to capture, the design choices that decide whether a log is evidence or just a story, and what the EU AI Act's logging rules require, on a high-risk timeline that now reaches into 2027.

An AI agent audit trail is a record of every action an agent took: which tool it called, with what inputs and outputs, on whose behalf, when, and whether the action was allowed or blocked. A chat transcript tells you what was said. An audit trail is built to answer a harder question: who told the agent to do that, and can you prove the record itself was not edited afterward.

That second clause is the whole topic. Most teams discover it the first time someone asks them to demonstrate, not assert, that an agent did only what they claim. We build Pinchy, a self-hosted AI agent platform whose audit trail is one of its core features, so we have a stake here. The design discussion below stands on its own either way, and the parts where the answer is genuinely contested are marked as such.

Why an agent audit trail is not just application logging

Every backend already writes logs. The instinct is to point an agent at the same pipeline and call it done. Three things make that insufficient.

The log is the evidence, and ordinary logs are editable. As one analysis of the EU AI Act's logging mandate put it, application logs "live on infrastructure someone controls. They can be edited or replaced without anyone noticing," and "if your logs can be silently altered and you can't show otherwise, their evidentiary value is zero" (Help Net Security). A log you can quietly rewrite proves nothing about an autonomous system that took actions on your behalf.

Agents are non-deterministic. The same prompt can produce a different sequence of tool calls on two different runs. Observability stacks built for deterministic services assume a request maps to a predictable path. An agent does not, which is exactly why the per-run record of what it actually chose to do matters more, not less.

The interesting events are tool calls, not page views. An agent reads a customer record, drafts an email, updates an invoice, hands off to a sub-agent. The audit-worthy moments are these actions and the decisions around them: which tool, which user asked, what was returned, what was refused. A request-and-response log of the chat endpoint captures almost none of it.

What an agent audit trail has to capture

Working back from "could you reconstruct and defend this later," an agent audit entry needs at least:

This maps onto what regulators are starting to demand. EU AI Act Article 12 frames logging around recording the events needed to identify risk situations, support post-market monitoring, and monitor operation, and it expects traceability across inputs, outputs, and the people involved. A common gap, even in mature setups, is that the log captures the action but not the decision context: the system prompt, accumulated history, and tool results that shaped the agent's choice. Without that context you can show what the agent did but not why, which is often the question being asked.

The hard part: making the log tamper-evident

Capturing the right fields is the easy half. The half that separates an audit trail from a diary is whether anyone, including an administrator, can change an entry after the fact without it showing. Access controls help, but access controls protect the living system; they say nothing about whether last quarter's log was rewritten last night. For that you need the record to carry its own proof.

There is a small design space here, and the choice has real consequences.

Approach Tamper-evident? Survives lawful erasure? Verify outside the system?
Access-controlled log fileNo (editable by anyone with access)YesNo
Hash chainYes (a change breaks the chain)No, if you erase by deleting rows (deletion breaks the chain)Yes, if the chain is exported
Merkle treeYesPartial, with extra machineryYes, with proofs
WORM storageYes (write once)No (cannot delete by design)Depends on the vendor
Per-row signature onlyYes (a change breaks that row's signature)Yes, but only because rows are independent (no ordering guarantee)Yes, if signatures are exported
Per-row signature + chain, PII redacted at write time (Pinchy)Yes (per-row signing pinpoints the row; the chain also catches deletion, truncation, and reordering)Yes, erasure happens on the source record, not by deleting log rowsYes, signatures and chain are exportable and re-checkable

A hash chain is the approach most teams reach for first, and you can watch it happen in the open: agent projects file issues asking for a "SHA-256 hash-chained action log for tamper-proof agent accountability" (a real example lives in the hermes-agent issue tracker). Each entry includes a hash of its own data combined with the previous entry's hash, so altering one entry changes its hash and breaks verification for every entry after it. It is elegant, and for an append-only system that never has to remove anything, it is a fine answer.

Why hash chains and the right to be forgotten collide

The trouble is that real systems do have to remove things. GDPR's right to erasure can require you to delete a specific person's data on request. If your audit trail is a hash chain, deleting one entry breaks the hash of every entry recorded after it, and your tamper-evidence collapses into "this log has been altered" for the entire remainder of the chain. On the surface, that forces a choice between honouring a lawful deletion and keeping a verifiable log. That is not a trade-off most compliance teams will accept, and it is rarely surfaced in the tutorials that recommend chaining.

The usual escape hatch is to weaken the chain: sign each row independently and give up the ordering guarantee, so a single row can be deleted without invalidating the rest. That trade is real, but it is not the only way out. The collision only exists if the chained log holds erasable personal data in the first place. Keep the personal data out of the chain, and you can have both the chain's ordering guarantee and lawful erasure. That is the design below.

Where Pinchy lands: tamper-evidence without the erasure trap

Pinchy signs every audit entry with a per-row HMAC-SHA256 over its canonically-serialised fields, and binds each row's signature to its predecessor's, forming a hash chain. Per-row signing pinpoints a tampered row; the chain makes deletion, truncation, and reordering detectable too.

And you can verify it yourself. An admin API (/api/audit/verify) re-checks every signature and every chain link on demand, reporting exactly which rows were altered and where the chain was broken, and a scheduled job runs that check continuously. Most platforms that market "tamper-evident" logs give you no way to test the claim; Pinchy hands you the check.

This doesn't reintroduce the right-to-be-forgotten collision, because the chained log never holds erasable personal data in the first place:

Honest note: a keyed HMAC or pseudonym is pseudonymised, not anonymised, so under a strict reading it may still count as personal data. Pinchy's stance is that the erasure obligation is met on the source record while the log keeps only a reference that is not reversible in practice. This is a design stance, not legal advice; validate it with your DPO.

How to verify a tamper-evident audit trail

Verification is mechanical once the design is right. For a per-row signed log:

  1. Serialise the entry canonically. Take the entry's fields and serialise them in a fixed, reproducible form, for example with the keys sorted. This step is easy to get wrong and easy to skip: many databases, including PostgreSQL's JSONB, do not preserve key order, so signing the stored representation directly produces signatures that fail for reasons that have nothing to do with tampering.
  2. Recompute the signature. Run the same keyed hash over the canonical bytes that the system ran when it wrote the entry.
  3. Compare. If the recomputed signature matches the stored one, the entry is intact. If it does not, that specific entry was changed.
  4. Verify outside the system. The check is only convincing if it can run somewhere other than the system that produced the log. That means the signatures have to be exportable. A CSV export that carries each row's signature lets an auditor, or you, run the verification independently against the row data alone.

The test of a real audit trail is that last point. If the only thing that can tell you the log is intact is the same application that could have edited it, you have a claim, not evidence.

What the regulations actually require

The driver behind most of this work in 2026 is regulatory. EU AI Act Article 12 requires high-risk AI systems to "technically allow for the automatic recording of events (logs) over the lifetime of the system." Two words carry weight: automatic means the system generates the logs itself, not a person writing notes, and lifetime means from deployment to decommissioning. Related provisions set a minimum retention of six months, and the article expects logs detailed enough to identify risk situations and to support both post-market monitoring and operational oversight. Its high-risk obligations are phasing in on a timeline that has already shifted once: the 2026 Omnibus package moved the use-based high-risk deadline to 2 December 2027.

Worth knowing: there is not yet a finalised technical standard for how to satisfy this. Two are in draft (prEN 18229-1 and ISO/IEC DIS 24970), which means the specifics are still moving. The safe reading is to build for the property the law is reaching for, an automatic and trustworthy record, rather than to a checkbox. The same per-entry integrity and external verifiability also map cleanly onto SOC 2 and onto GDPR's expectation of accountability, so the work is not single-use.

A checklist for evaluating an agent audit trail

Whether you are building one or assessing a vendor's, these are the questions that separate evidence from decoration:

How Pinchy does it

This is the part where we describe our own product, so read it as such. Pinchy records every agent action in an audit trail where each entry is individually signed with an HMAC-SHA256 over its canonically serialised fields, and each row's signature is bound to its predecessor's, forming a hash chain. Per-row signing points at the exact tampered row; the chain also catches deletion, truncation, and reordering. The right-to-be-forgotten collision does not apply, because the log is append-only (a PostgreSQL trigger rejects UPDATE, DELETE, and TRUNCATE) and personal data is redacted at write time rather than deleted later: emails become a keyed HMAC plus a masked preview, and the acting user is stored as a per-user pseudonym. Erasure happens on the user's own record, which leaves the audit entries unlinkable to the person while the trail stays intact. Entries export to CSV with their signatures, and an admin endpoint (/api/audit/verify) recomputes every signature and every chain link, reporting the exact rows that were altered and where the chain broke; a scheduled job runs the same check continuously.

The audit trail sits behind the rest of the model: an allow-list of tools per agent so the log records actions the agent was actually permitted to take, and a self-hosted deployment so the records, and the data they describe, never leave your infrastructure. If you build your own layer instead, the design above is what we would build toward, and if you try Pinchy and something here does not hold up, that is an issue report we want.

Frequently asked questions.

What is an AI agent audit trail?

An AI agent audit trail is a record of every action an AI agent took: which tool it called, with what inputs and outputs, on whose behalf, when, and whether the action was allowed or blocked. Unlike a chat transcript, it is meant to answer 'who told the agent to do that, and can you prove the record was not altered afterward.'

Why isn't application logging enough for AI agents?

Standard application logs live on infrastructure someone controls and can be edited or replaced without anyone noticing, so their evidentiary value is low. Agents also behave non-deterministically (the same prompt can produce different tool calls on different runs) and act through tool calls and sub-agents, so the log has to capture which user asked, which tool ran, and what was allowed, not just request and response lines.

What is the difference between a hash chain and a per-row signature for audit logs?

A hash chain links each entry to the one before it, so altering any entry breaks every entry after it and deletion, truncation, and reordering all show. A per-row signature signs each entry independently, so it pinpoints exactly which row was tampered with but gives no ordering guarantee. The two are not mutually exclusive. Pinchy uses both: a per-row HMAC-SHA256 plus a chain that binds each row to its predecessor. The right-to-erasure collision that usually pushes teams away from chaining does not apply here, because the log is append-only (a database trigger blocks deletion) and personal data is redacted at write time rather than deleted from the log later.

Does the EU AI Act require audit trails for AI agents?

EU AI Act Article 12 requires high-risk AI systems to technically allow the automatic recording of events (logs) over the lifetime of the system, sufficient to identify risk situations, support post-market monitoring, and monitor operation. Related provisions require keeping those logs for at least six months. The high-risk timeline for these obligations has shifted: the 2026 Omnibus changes moved the use-based high-risk deadline to 2 December 2027, so treat the requirement as firmer than any single date.

How do you verify that an audit trail has not been tampered with?

You recompute each entry's signature from the entry's own data and compare it to the signature stored with the entry, and you re-check that each row's chain link still matches its predecessor. If either fails, you know which row was altered and where the chain broke. For this to be meaningful the data has to be serialised in a canonical form (for example with sorted keys) before signing, and the check has to be runnable by you, not only the vendor. Pinchy exposes an admin endpoint (/api/audit/verify) that runs this on demand, runs the same check on a schedule, and exports signatures to CSV so you can re-verify outside the system that produced the log.

An audit trail you can actually verify.

Pinchy signs every agent action with a per-row HMAC and a hash chain, and hands you the verifier: an admin endpoint and a CSV export you can re-check independently. Open source, self-hosted, free to run.

Or email us: info@heypinchy.com