Back to Blog
Governance

Tamper-Evident Audit Logs: What Makes an AI Agent Action Trail Actually Immutable

· 10 min read

By Yuki Tanaka

When a security reviewer asks whether your AI agent has an audit trail, they are not asking whether your system writes log lines to a database. They are asking whether those records can be trusted after the fact, specifically: whether someone with database access could modify or delete records in a way that would not be detectable.

The distinction matters enormously for regulated environments. An audit trail that can be silently edited is not an audit trail in any meaningful governance sense. It is a mutable activity log, which answers a different set of questions. Security reviews for financial services, healthcare, and government deployments will probe this distinction directly. "We write every agent action to a Postgres table" is an answer to a different question than the one being asked.

What Tamper Evidence Actually Means

Tamper evidence is the property that any modification to a historical record is detectable. It does not require that modification be prevented, though that is also desirable. It requires that if a record is changed, deleted, or if a new record is inserted retroactively, this can be proven by an independent party examining the audit trail.

The standard mechanism for achieving this in append-only log systems is hash chaining. Each log entry includes a cryptographic hash of its own content plus the hash of the preceding entry. Modifying any entry in the chain invalidates the hash of that entry and every entry that follows it. An independent verifier running the chain from start to current can detect any tampering because the chain integrity check will fail at the first modified entry.

{
  "entry_id": "e_4921",
  "run_id": "run_af9b2c",
  "event": "tool_call",
  "tool": "read_database",
  "params": {"table": "accounts", "filter": "user_id=8801"},
  "result_hash": "sha256:a3f9...",
  "timestamp": "2026-04-23T14:22:07.441Z",
  "prev_hash": "sha256:d71c...",
  "entry_hash": "sha256:8b4a..."
}

The prev_hash field contains the hash of the immediately preceding entry in the chain. The entry_hash is computed over all other fields in this entry including prev_hash. To verify the chain, re-compute each entry_hash from the entry fields and check that each entry's prev_hash matches the preceding entry's entry_hash. Any modification anywhere in the chain breaks this relationship at the tampered entry and propagates forward.

Write-Once Storage Semantics

Hash chaining proves that records have not been modified. It does not prevent modification on its own. An attacker with full database access can rewrite an entry and then recompute all subsequent hashes in the chain to restore consistency. The chain will verify cleanly after this operation because the hashes are recomputed correctly for the new content.

Preventing undetectable rewriting requires write-once storage semantics: the storage layer must not allow update or delete operations on existing records by any principal, including database administrators. This is a stronger property than hash chaining alone and requires architectural choices at the storage layer.

The canonical implementation uses an append-only storage engine with no UPDATE or DELETE operations exposed. PostgreSQL's logical replication with publication-level restrictions can be configured to allow only INSERT. Object storage systems like S3 with Object Lock in COMPLIANCE mode prevent deletion by any user including the bucket owner until the configured retention period expires. Time-series databases like InfluxDB have retention policy configurations that control deletion at the policy level rather than the row level.

For on-premises deployments, the standard approach is to combine an append-only write path with a separate read-only replica that serves verification queries. Write access to the primary store is restricted to the log writer service. No application principal has direct database credentials that permit UPDATE or DELETE on the log table. Verification is done against the replica to ensure the verification path does not require access to the write credentials.

What Fields Must Be Captured

An audit trail for an AI agent is not a generic application log. It has specific semantic requirements: it must record what the agent did, not just that it did something. The difference matters for postmortem analysis and for answering regulator questions.

The minimum field set for a useful agent audit entry is: run identifier, event type, timestamp with millisecond precision, tool name and parameters (before execution), tool output or error (after execution), any policy decision that applied (allowed or denied and which policy rule), and the resource consumption of this step. The run identifier links all entries from a single agent run into a retrievable sequence. The policy decision field makes the audit trail answer not just "what happened" but "what was enforced."

Tool parameters before execution are particularly important. For database read operations, the parameter set includes which table and which filter. For file operations, which path. For API calls, the endpoint and key request parameters. Recording the parameter set at execution time, before the tool runs, captures what the agent intended to do, not a post-hoc reconstruction. This matters when investigating suspicious activity: you can see exactly what the agent requested, not what the tool returned.

The Completeness Problem

A tamper-evident audit trail that is missing events is more dangerous than a mutable one. A mutable log reveals its own weakness: you know the records might have been changed. An incomplete immutable log looks complete, and a verifier checking chain integrity will find nothing wrong. The missing records are simply absent from the chain, and absence is not detectable through chain verification.

Completeness requires that every action the agent takes goes through the logging path before it can proceed. This means the logging path must be synchronous with the action, not asynchronous. An agent that calls a tool, receives a result, and logs the event asynchronously afterward can produce an incomplete log if the logging write fails: the action happened, the log entry did not.

The correct architecture is that the tool invocation is mediated by the runtime layer, which writes the log entry before forwarding the call to the underlying tool. The tool never receives the call unless the log write succeeds. If the log write fails, the tool call fails and returns an error to the agent. This guarantees the invariant that every tool execution has a corresponding audit entry, by construction.

Retention Policy and Log Sealing

Audit log retention periods for regulated environments are not homogeneous. Financial services typically requires five to seven years for transaction-adjacent records under various regulations. Healthcare records involving patient data have minimum retention periods that vary by record type and jurisdiction. An audit trail system that applies a single retention period to all records, or that silently deletes records at expiry without documentation of the deletion, creates compliance gaps.

The right model is to declare a retention policy per record category at configuration time, to seal the log at regular intervals (daily is typical), and to record the sealed log's root hash in a separate, independently verified location. Sealing binds a time range to a verifiable digest: the sealed hash proves that the log as of that point contained exactly those records, and any future alteration to records within the sealed range will break verification against the published seal hash.

Published seal hashes can be stored in a separate system, printed in a daily report, or submitted to a transparency log service. The key property is that they are not stored in the same mutable system as the records they protect. An organization that stores seal hashes in the same database as the records they seal gains no integrity benefit from sealing.

Verification as a First-Class Operation

An audit trail that is tamper-evident but never verified provides weaker guarantees than one with regular, documented verification runs. Verification should be a scheduled operation, not something that only happens when an incident triggers an investigation.

Running chain verification on a schedule and recording the verification outcome (pass or fail, the range verified, the verifier identity, and the timestamp) creates a verification log that is itself part of the audit posture. When a regulator asks "how do you know your audit trail is intact," the answer is not "it is technically possible to verify it" but "we ran verification on this date range and it passed, here is the verification record." That is the answer that satisfies the question.

We are not saying this level of rigor is necessary for every deployment. A development tool used internally with no regulatory exposure can operate with a simpler log. But for any agent that handles regulated data, processes transactions, or operates in an environment where a security review will be conducted, the properties described here are what "immutable audit trail" actually means. Treating them as implementation details rather than design requirements tends to be discovered at review time, not build time.

Put these controls into production

Runta gives your agents sandbox isolation, resource quotas, configurable egress allowlists, and an immutable audit trail out of the box. No custom runtime engineering required.

Request Early Access Read the Docs