---
title: "Make the audit log impossible to change · Agent Wranglers"
url: https://agentwranglers.se/playbook/compliance/audit-logs-and-access/audit-log-immutable
updated: 2026-10-20
licence: "All rights reserved"
---

# Make the audit log impossible to change

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Audit logs and access](https://agentwranglers.se/playbook/compliance/audit-logs-and-access)
- Rule: Store audit events where the app can only add and nobody can edit or delete. Chain each event to the one before with a hash.
- How: Give the app a database role with insert rights only on the audit table, or ship events to write-once storage. Object storage with a compliance-mode lock, such as S3 Object Lock or an Azure immutable blob policy, refuses deletes even from admins. Store a SHA-256 hash of each event together with the hash of the previous one. A verifier then finds any gap or edit.
- Check: An `UPDATE` or `DELETE` on the audit table as the app role fails. A test changes one stored event in a copy, and the chain verifier reports the exact event.

Example:

```js
import { createHash } from 'node:crypto';

const hashEvent = (event, previousHash) => createHash('sha256').update(previousHash + JSON.stringify(event)).digest('hex');

export function firstBrokenLink(entries) {
  let previousHash = '';
  for (const [index, { event, hash }] of entries.entries()) {
    if (hashEvent(event, previousHash) !== hash) return index;
    previousHash = hash;
  }
  return -1;
}
```

```python
import hashlib, json

def hash_event(event: dict, previous_hash: str) -> str:
    return hashlib.sha256((previous_hash + json.dumps(event, separators=(",", ":"))).encode()).hexdigest()

def first_broken_link(entries: list[dict]) -> int:
    previous_hash = ""
    for index, entry in enumerate(entries):
        if hash_event(entry["event"], previous_hash) != entry["hash"]:
            return index
        previous_hash = entry["hash"]
    return -1
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers compliance playbook: https://agentwranglers.se/playbook/compliance/audit-logs-and-access/audit-log-immutable`.

- Previous: [Write an audit event for every sensitive action](https://agentwranglers.se/playbook/compliance/audit-logs-and-access/audit-log-events)
- Next: [Keep audit logs for a set time](https://agentwranglers.se/playbook/compliance/audit-logs-and-access/audit-log-retention)
- [Audit logs and access](https://agentwranglers.se/playbook/compliance/audit-logs-and-access)
