DenialOS
Docs / Audit trail integrity
IMPLEMENTED — RUNTIME-TESTED
⏱️ 2 min read · 369 words

Audit trail integrity

Audit history is only useful if it cannot be quietly edited. DenialOS records customer-bound actions in append-only audit records that are chained per organization, and each chain is anchored outside the chain itself.

Chaining

Every audit record carries the hash of the record before it, forming a per-organization SHA-256 chain. Two chains are maintained: one over the operational audit log and one over the security event stream. A record cannot be removed, reordered, or rewritten without breaking the links that follow it.

Anchoring

A chain that only links forward can still be truncated at its newest end: deleting the last few records leaves a shorter history that still verifies. Each organization's chain therefore has a separate anchor record holding the chain's sequence, newest hash, and recorded entry count. Anchors are written by a dedicated database function, a guard trigger refuses any update that would move an anchor backwards, and the application's runtime role cannot rewrite them.

What verification reports

Verification returns a specific reason rather than a boolean, so an operator can tell what was detected:

ReasonMeaning
TAIL_TRUNCATEDthe log is shorter than its anchor records
ANCHOR_MISSINGentries exist but no anchor does
ANCHOR_MISMATCHthe newest hash disagrees with the anchor
ANCHOR_COUNT_MISMATCHthe number of entries disagrees with the anchor

An append onto a truncated history is refused rather than silently re-linked.

What is verified

The chain suite runs against a real PostgreSQL instance and covers:

Boundary

Anchoring detects edits made through the application or through ordinary SQL; the anchor lives in the same database as the chain, so an actor who controls the database server itself could remove both. Off-database anchoring is a deployment-level option rather than a claim of this documentation.