AuditRailsAuditRails
Back to Blog
EngineeringMarch 2026

How Cryptographic Hash Chaining Ensures Tamper-Proof Logs

When an auditor reviews your logs, they need to trust that what they’re seeing is exactly what happened, no events removed, no timestamps altered, no records inserted after the fact. Cryptographic hash chaining provides that guarantee through mathematics, not policy.

What Is Hash Chaining?

Hash chaining is a technique where each record in a sequence includes a cryptographic hash that depends on the previous record. If any record in the chain is modified, deleted, or reordered, the hash values no longer match and the tampering is immediately detectable.

The concept is simple but powerful. Each log event’s hash is computed from three inputs: the hash of the previous event, the canonical payload of the current event, and a millisecond-precision timestamp. We use SHA-256, the same algorithm used in TLS certificates, digital signatures, and Bitcoin.

The Hash Formula

At AuditRails, every log event’s hash is computed as follows:

hash = SHA-256(prev_hash + canonical_payload + timestamp_ms)

Where:

  • prev_hash is the SHA-256 hash of the immediately preceding event in the same tenant’s chain
  • canonical_payload is a deterministic JSON serialization of the event’s core fields: log_id, tenant_id, action, actor_id, resource, and metadata
  • timestamp_ms is the server-assigned timestamp in milliseconds since the Unix epoch

The canonical payload deliberately excludes fields that are added during processing (such as geo-IP data, enrichment fields, and the hash itself) to ensure the hash is computed over the immutable, application-provided data.

Per-Tenant Chains and the Genesis Hash

Each tenant (organization) maintains its own independent hash chain. This is a deliberate design choice: tenant isolation is a foundational security principle, and mixing tenants into a single chain would create cross-tenant dependencies that complicate both security and scalability.

Every chain starts with a genesis hash, a well-known starting value of 64 zeros:

genesis_hash = "0000000000000000000000000000000000000000000000000000000000000000"

The first event in a tenant’s chain uses this genesis hash as its prev_hash. From that point forward, each event references the hash of the event that came before it, creating an unbroken sequence.

How Tampering Breaks the Chain

Consider a chain of three events for a tenant. Each event’s hash depends on the previous event’s hash:

Event #1:
  prev_hash:  0000000000000000...  (genesis)
  payload:    {"action": "user.login", "actor_id": "usr_abc", ...}
  timestamp:  1711929600000
  hash:       a1b2c3d4e5f6...

Event #2:
  prev_hash:  a1b2c3d4e5f6...     (hash of Event #1)
  payload:    {"action": "document.create", "actor_id": "usr_abc", ...}
  timestamp:  1711929601500
  hash:       f7e8d9c0b1a2...

Event #3:
  prev_hash:  f7e8d9c0b1a2...     (hash of Event #2)
  payload:    {"action": "document.share", "actor_id": "usr_abc", ...}
  timestamp:  1711929603000
  hash:       3344556677889900...

Now suppose someone modifies Event #2, perhaps changing document.create to document.view to hide the fact that a document was created. The moment Event #2’s payload changes, its recomputed hash no longer matches f7e8d9c0b1a2.... And since Event #3’s hash was computed using Event #2’s original hash as the prev_hash, Event #3’s hash also becomes invalid. The corruption cascades through every subsequent event in the chain.

Even if an attacker recomputes all hashes from the tampered event forward, the new chain head hash will differ from the stored chain head, which AuditRails maintains in a separate, cryptographically protected store. There is no way to tamper with a single event without detection.

WORM Storage: The Second Layer of Protection

Hash chaining detects tampering. WORM (Write Once, Read Many) storage prevents it at the infrastructure level.

Every batch of log events is written to Amazon S3 with Object Lock enabled in compliance mode. Once written, the data cannot be deleted or overwritten by anyone, including AWS root accounts, until the retention period expires. Retention periods start at 6 months on every plan and extend automatically based on your subscribed compliance frameworks, 7 years for SOX, up to 10 years for the EU AI Act, the longest requirement across all 18, or can be extended further with a self-service retention add-on.

This two-layer approach means that even if an attacker gained full access to the database, they could not modify the cold storage copies, and any modifications to the hot storage would be detected by the hash chain verification.

How Does This Compare to Blockchain?

If hash chaining sounds familiar, it should, it’s the same fundamental concept that underpins blockchain technology. Each block in a blockchain contains the hash of the previous block, creating an immutable ledger.

The key difference is that AuditRails uses a centralized, per-tenant chain rather than a distributed consensus mechanism. We don’t need proof-of-work, mining, or a peer-to-peer network. The trust model is different: instead of trusting a decentralized network, you trust AuditRails as the append-only custodian of your audit trail, backed by cryptographic verification that you can run independently.

This gives you the tamper-evidence guarantees of blockchain technology at a fraction of the cost and complexity, with millisecond-level write latency instead of the seconds-to-minutes confirmation times typical of distributed ledgers.

The Verification Process

AuditRails provides a verification endpoint and a dashboard feature that walks the hash chain and recomputes every hash from the genesis event forward. The process is straightforward:

  1. Start with the genesis hash ( 0000...0000) as the expected prev_hash
  2. For each event in sequence, verify that the stored prev_hash matches the expected value
  3. Recompute SHA-256(prev_hash + canonical_payload + timestamp_ms)
  4. Verify the recomputed hash matches the stored hash
  5. Use the stored hash as the expected prev_hash for the next event

If any step fails, the verification report identifies the exact event where the chain breaks and the nature of the discrepancy. This gives auditors a concrete, mathematically verifiable proof of log integrity.

Why Auditors Care

Compliance frameworks like SOC 2 (CC7.2), HIPAA (§164.312(b)), and ISO 27001 (A.12.4) all require organizations to maintain audit trails that are protected from unauthorized modification. Hash chaining provides a cryptographic proof that logs haven’t been tampered with, not just a policy statement, but a mathematical guarantee.

When an auditor asks “How do you ensure the integrity of your audit logs?”, the answer is no longer “We have access controls on the database.” It’s “Every log event is cryptographically chained using SHA-256, stored on WORM storage, and independently verifiable. Here’s the verification report.”

That’s the difference between a control that might work and a control that is provably effective.

See hash chaining in action

Create a free account and send your first audit event. Verify the chain from your dashboard, no credit card required.

Start for Free