Building Tamper-Proof Logs for AI Agents: Hash Chains, Verification, and Export
Your logs are lying to you. Or more precisely, you have no way to prove they are not.
A traditional log file is a sequence of text lines appended to a file. Anyone with write access can modify those lines. An attacker who gains shell access can edit the log to cover their tracks. An insider can delete entries that record their actions. A compromised process can overwrite the log with fabricated events. And in every one of these cases, you have no mechanism to detect the modification.
For most applications, this is an acceptable risk. For AI agent security, it is not.
When an AI agent has access to file_write, shell_exec, and network capabilities, the actions it takes can cause real, measurable damage. The audit trail that records those actions is the only way to understand what happened after an incident. If that trail can be tampered with, your incident response is built on sand.
SafeClaw implements tamper-proof logs using SHA-256 hash chains. This article explains the engineering behind them: how they work, how they differ from traditional logs and from blockchain, how verification works, and how the export mechanism enables independent auditing.
Why Traditional Logs Fail
A traditional log entry looks like this:
2026-02-13T10:00:01Z INFO agent=claude-01 action=file_write path=/workspace/config.json result=allow
2026-02-13T10:00:02Z INFO agent=claude-01 action=shell_exec cmd="git commit -m 'update'" result=allow
2026-02-13T10:00:03Z WARN agent=claude-01 action=network url=https://exfil.evil.com result=deny
Now suppose an attacker gains access and modifies line 3:
2026-02-13T10:00:03Z INFO agent=claude-01 action=network url=https://api.github.com result=allow
The log now shows an allowed request to GitHub instead of a denied request to a malicious domain. There is no mechanism to detect this change. The file's modification timestamp can be reset. The file's checksum was never recorded. The altered log is indistinguishable from the original.
This is the fundamental weakness: traditional logs have no internal integrity mechanism. Each line is independent. There is no relationship between entries that would break if one is modified.
The Hash Chain Solution
A hash chain adds a cryptographic link between consecutive entries. Each entry includes the SHA-256 hash of the previous entry. This creates a chain where the integrity of each entry depends on the integrity of every entry before it.
Here is the structure in detail:
Entry 0:
data: {
timestamp: "2026-02-13T10:00:01Z",
agent: "claude-01",
action: "file_write",
path: "/workspace/config.json",
result: "allow"
}
prevHash: "0000000000000000000000000000000000000000000000000000000000000000"
hash: SHA256(serialize(data) + prevHash) = "a1b2c3..."
Entry 1:
data: {
timestamp: "2026-02-13T10:00:02Z",
agent: "claude-01",
action: "shell_exec",
cmd: "git commit -m 'update'",
result: "allow"
}
prevHash: "a1b2c3..."
hash: SHA256(serialize(data) + prevHash) = "d4e5f6..."
Entry 2:
data: {
timestamp: "2026-02-13T10:00:03Z",
agent: "claude-01",
action: "network",
url: "https://exfil.evil.com",
result: "deny"
}
prevHash: "d4e5f6..."
hash: SHA256(serialize(data) + prevHash) = "g7h8i9..."
Now if an attacker modifies Entry 2's data, the hash of Entry 2 changes. But Entry 2's hash is embedded in Entry 3 as prevHash. Entry 3's hash was computed using the original value. The chain is broken.
To make the modification undetectable, the attacker would need to recompute every hash from the modified entry to the end of the chain, and also replace the chain head hash if it has been independently recorded. This is the same property that makes blockchain immutable, applied in a simpler, local context.
SafeClaw's Implementation
SafeClaw implements its hash chain with these specific design choices:
Serialization
Each entry's data is serialized to a canonical JSON representation before hashing. Canonical serialization ensures that the same data always produces the same byte sequence, regardless of property ordering or whitespace. This is critical -- without canonical serialization, semantically identical entries could produce different hashes.
Hash Computation
The hash is computed as:
hash = SHA256(canonical_json(data) + prevHash)
SHA-256 is used because it is:
- Collision-resistant: no known practical method to find two different inputs that produce the same hash.
- Preimage-resistant: given a hash, no practical method to find the input that produced it.
- Widely available: implemented in every major programming language and operating system.
- Battle-tested: used in TLS, Bitcoin, and countless security-critical systems.
SafeClaw uses Node.js built-in
crypto module for SHA-256, which binds to OpenSSL. No external cryptographic libraries are used -- consistent with the zero-dependency architecture.
Genesis Entry
The first entry in the chain uses a known, fixed value for prevHash -- 64 zeros (the hexadecimal representation of a 256-bit zero value). This establishes the chain's starting point and allows verification to begin from the first entry.
Storage
The hash chain is stored locally on the machine where SafeClaw is running. Entries are appended atomically -- each entry is fully written (including its hash) before the next entry begins. This prevents partial writes from corrupting the chain.
The Verification Process
Verification walks the chain from the genesis entry to the most recent entry, checking two properties at each step:
- Hash integrity: Recompute the entry's hash from its data and prevHash. Compare to the stored hash. If they differ, the entry has been modified.
- Chain continuity: Compare the entry's prevHash to the previous entry's hash. If they differ, the chain has been broken -- an entry has been inserted, deleted, or modified.
function verify(chain):
for i = 0 to chain.length - 1:
// Check hash integrity
computed = SHA256(serialize(chain[i].data) + chain[i].prevHash)
if computed != chain[i].hash:
return { valid: false, error: "Hash mismatch at entry " + i }
// Check chain continuity
if i > 0 and chain[i].prevHash != chain[i-1].hash:
return { valid: false, error: "Chain break at entry " + i }
// Check genesis
if i == 0 and chain[i].prevHash != ZERO_HASH:
return { valid: false, error: "Invalid genesis entry" }
return { valid: true, entries: chain.length }
This verification can be performed by any program that implements SHA-256 and knows the serialization format. It does not require SafeClaw itself. The algorithm is deterministic and publicly documented.
What Verification Catches
- Modified entries: Any change to an entry's data changes its hash, causing a hash integrity failure.
- Deleted entries: Removing an entry breaks the chain continuity -- the next entry's prevHash no longer matches any existing entry's hash.
- Inserted entries: Adding an entry between two existing entries breaks the chain continuity at the insertion point.
- Reordered entries: Changing the order of entries breaks chain continuity at every point where the order changed.
What Verification Does Not Catch
- Appended false entries: If an attacker can append new entries to the end of the chain with correct hashes, those entries will pass verification. This is mitigated by independently recording the chain head hash at known points in time.
- Complete chain replacement: If an attacker replaces the entire chain with a fabricated one that is internally consistent, verification will pass. This is mitigated by independently recording the genesis hash or periodic chain state.
The Export Mechanism
SafeClaw supports exporting the audit trail in JSON format. The export includes every entry with its data, prevHash, and hash fields. This export can be:
- Stored externally. Copy the export to a separate system that the agent (and any attacker who compromises the agent's environment) cannot access. Even if the local chain is tampered with, the exported copy preserves the original state.
- Verified independently. Any tool that implements SHA-256 can verify the exported chain. You do not need SafeClaw to verify SafeClaw's logs.
- Compared to the live chain. If you suspect tampering, compare the exported chain to the live chain. Any discrepancy identifies the point of modification.
- Archived for compliance. Regulatory frameworks often require log retention for specific periods. The export mechanism enables archival in any storage system.
Comparison to Blockchain
The hash chain concept is often associated with blockchain. SafeClaw's implementation shares the core idea but differs in important ways:
Similarities:
- Both use hash chains to create tamper-evident records.
- Both make modification of historical entries detectable.
- Both use SHA-256 (or similar) for hash computation.
Differences:
| Aspect | Blockchain | SafeClaw |
|---|---|---|
| Authority model | Distributed (many nodes, consensus required) | Single authority (local SafeClaw instance) |
| Write latency | Seconds to minutes (consensus) | Sub-millisecond (local append) |
| Storage model | Replicated across all nodes | Local with optional export |
| Verification | Any node can verify | Any tool with SHA-256 can verify |
| Network requirement | Requires network for consensus | Fully local, no network needed |
| Complexity | High (consensus, networking, incentives) | Low (hash computation, serial append) |
SafeClaw does not need distributed consensus because the threat model is different. Blockchain protects against a scenario where no single party is trusted. SafeClaw protects against a scenario where the log itself might be modified after the fact. For this threat model, a local hash chain with export capability is sufficient and dramatically simpler.
Performance Impact
Adding hash chain computation to every log entry introduces overhead. In SafeClaw's case, this overhead is negligible:
- SHA-256 computation of a typical log entry (a few hundred bytes of serialized JSON) takes microseconds.
- Canonical JSON serialization is fast for small objects.
- Appending to the chain is a sequential write operation.
Practical Implications
Tamper-proof logs change how you approach incident response:
- You can trust the timeline. The hash chain guarantees that entries are in the order they were recorded.
- You can detect tampering. If someone modified the logs, verification will catch it.
- You can prove completeness. A valid chain with no gaps proves that no entries were deleted.
- You can share logs with confidence. Exported logs are independently verifiable by any party.
npx @authensor/safeclaw, configure your policies through the browser dashboard at safeclaw.onrender.com, and every action evaluation is automatically recorded in the hash chain.
The client is 100% open source. The hash chain implementation, serialization format, and verification algorithm are all inspectable. For more on the Authensor framework, visit authensor.com.
Try SafeClaw
Action-level gating for AI agents. Set it up in your browser in 60 seconds.
$ npx @authensor/safeclaw