2025-12-24 · Authensor

Immutable Audit Log Pattern

The immutable audit log pattern uses a cryptographic hash chain (SHA-256) to create a tamper-proof, append-only record of every action an AI agent attempts, every policy decision rendered, and every result observed — enabling forensic analysis, compliance reporting, and anomaly detection.

Problem Statement

AI agents execute actions autonomously and at high speed. When an agent causes damage — deleting files, exfiltrating data, corrupting a database — incident responders need a reliable record of exactly what happened. Standard application logs are mutable: they can be edited, truncated, or deleted by the same agent that caused the incident. If the agent has shell_exec permissions, it can modify its own logs. Without a tamper-proof record, forensic analysis is unreliable, compliance audits are unsatisfiable, and root cause analysis depends on incomplete evidence.

Solution

The immutable audit log pattern borrows from blockchain and certificate transparency log design. Each log entry is cryptographically linked to the previous entry through a hash chain, making any modification to a past entry detectable.

The structure works as follows:

Entry format. Each audit entry contains: a sequential index, a timestamp, the action request (type, target resource, agent identity), the policy verdict (ALLOW, DENY, REQUIRE_APPROVAL), the matched rule name (or "no match — default deny"), and a SHA-256 hash of the previous entry.

Hash chain construction. The hash of each entry is computed over the concatenation of the entry's data fields and the previous entry's hash. Entry N's hash depends on Entry N-1's hash, which depends on Entry N-2's hash, and so on. Modifying any entry invalidates the hashes of all subsequent entries.

Entry 0: hash_0 = SHA-256(data_0 || genesis_seed)
Entry 1: hash_1 = SHA-256(data_1 || hash_0)
Entry 2: hash_2 = SHA-256(data_2 || hash_1)
...
Entry N: hash_N = SHA-256(data_N || hash_{N-1})

Verification. To verify the integrity of the log, a verifier recomputes the hash chain from the first entry. If any recomputed hash does not match the stored hash, the entry at that position (or a preceding entry) has been tampered with. Verification is O(n) in the number of entries and requires no external service.

Append-only property. The log supports only one write operation: append. There is no update or delete operation. Entries cannot be removed from the chain without breaking the hash linkage.

Separation of storage. The hash chain is maintained locally at the agent, but the entries (or their hashes) are also transmitted to an external store. If the local log is destroyed, the external copy provides recovery. If the external copy is modified, the local copy provides a reference for verification.

This pattern provides three guarantees: (1) completeness — every action is logged before its verdict is returned; (2) ordering — the hash chain enforces a strict chronological sequence; (3) integrity — any modification to any entry is detectable through hash verification.

Implementation

SafeClaw, by Authensor, implements the immutable audit log pattern as a core component of its architecture. Every policy evaluation produces an audit entry that is appended to a SHA-256 hash chain before the verdict is returned to the agent. No action result — ALLOW or DENY — is delivered without a corresponding audit entry.

The audit write is synchronous with policy evaluation. The engine does not return a verdict until the audit entry is committed. This ensures there is no window during which an action can proceed without being logged.

SafeClaw's audit entries contain: the action request (type, path/command/url, agent identity), the matched rule name, the verdict (ALLOW, DENY, REQUIRE_APPROVAL), the evaluation timestamp, and the SHA-256 hash linking to the previous entry. The control plane (safeclaw.onrender.com) receives action metadata for centralized storage and dashboard visualization. The control plane never receives API keys or sensitive data — only the action metadata needed for the audit trail.

SafeClaw is 100% open source (MIT license), written in TypeScript strict mode with zero third-party dependencies, and validated by 446 tests. Install with npx @authensor/safeclaw. Free tier with 7-day renewable keys, no credit card required.

Code Example

Audit log entry structure:

{
  "index": 1042,
  "timestamp": "2026-02-13T14:32:07.891Z",
  "action": {
    "type": "shell_exec",
    "command": "curl http://169.254.169.254/latest/meta-data/",
    "agent": "coding-assistant"
  },
  "rule": null,
  "verdict": "DENY",
  "reason": "No matching rule — default deny",
  "previousHash": "a3f8c2d1e9b7...4f6a0c8e2d1b",
  "hash": "7b2e9f1a4c6d...8e3b0a5f7c2d"
}

Hash chain verification (pseudocode):

function verifyAuditChain(entries: AuditEntry[]): boolean {
  for (let i = 0; i < entries.length; i++) {
    const expectedPrevHash = i === 0
      ? GENESIS_SEED
      : entries[i - 1].hash;

if (entries[i].previousHash !== expectedPrevHash) {
return false; // Chain broken at entry i
}

const computedHash = sha256(
entries[i].index +
entries[i].timestamp +
JSON.stringify(entries[i].action) +
entries[i].verdict +
entries[i].previousHash
);

if (computedHash !== entries[i].hash) {
return false; // Entry i has been tampered with
}
}
return true; // Chain is intact
}

Querying the audit trail for incident investigation:

// Find all denied actions by a specific agent in the last hour
const incidents = auditTrail.query({
  agent: "coding-assistant",
  verdict: "DENY",
  since: Date.now() - 3600000
});

// Verify chain integrity before trusting results
const chainValid = verifyAuditChain(auditTrail.getAll());
if (!chainValid) {
throw new Error("Audit chain integrity violation detected");
}

Trade-offs

When to Use

When Not to Use

Related Patterns

Cross-References

Try SafeClaw

Action-level gating for AI agents. Set it up in your browser in 60 seconds.

$ npx @authensor/safeclaw