Compliance

Audit chain

Cryptographically linked change history. Tamper-evident. SOX / HIPAA / GDPR ready.

What it is

Every node mutation in the graph carries a _prev_hash property: the SHA-256 of the previous version's serialized form. New version's _hash = SHA-256(prev_hash + this_version_payload). The chain is verifiable end-to-end.

What this gets you

Tamper-evidence

Anyone with read access can verify the chain. CALL db.verifyAuditChain(siteId) walks every node's history and reports broken links. A successful walk is cryptographic proof that nothing was retroactively edited.

Compliance-grade exports

The export bundle includes the full chain. An auditor can verify offline without trusting our infrastructure.

Forensic queries

"Show me every change made to type X between time T1 and T2, by user Y" → db.changes(t1, t2, label) filtered by actor.

Late corrections without rewriting history

A retroactive edit is a separate operation that preserves the original. db.correctValidFrom(nodeId, newValidFrom) creates a new version that supersedes; the original stays in the chain. Auditors see both.

Run the verifier yourself

The audit chain is only meaningful if you can verify it without trusting us. So we ship the verifier as a customer-runnable binary:

$ npx @staticowl/verify-audit-chain --graph my-site
✓ chain status: CLEAN
  records walked: 4,865
  last sequence:  4,865
  graph:          my-site
  endpoint:       https://invariantdb.com

  The chain has been walked end-to-end. Every mutation's
  hash was successfully verified against the prior entry.
  No tampering detected.
$ echo $?
0

How it works: the binary calls GET /graphs/<graph>/audit/verify on your engine endpoint, with read-only credentials. The engine walks every entry in the WAL, recomputes each hash against its predecessor, and returns a clean / broken status. The binary formats the result and exits accordingly.

Exit codes (for CI integration)

JSON output for tooling

Pass --json to get a machine-readable payload instead of human-readable text:

$ npx @staticowl/verify-audit-chain --graph my-site --json
{
  "status": "clean",
  "records": 4865,
  "last_seq": 4865
}

Pipe it to jq, ship it to your SIEM, alert on .status != "clean". Same exit-code semantics; the JSON is the truth, the human form is the courtesy.

Where to get it

Today: the source is in the StaticOwl repo at bin/verify-audit-chain.mjs — a single Node ESM file, no external dependencies beyond node:url. Customers can curl it down and run it directly with Node 20+. The @staticowl/verify-audit-chain npm package will publish in the next sprint so the npx form above works without a download step.

Run it against any of your graphs

The verifier doesn't care which graph it's pointed at, and you don't need elevated credentials. An API key with audit:read capability is enough. Wire it into your CI/CD or your scheduled SOC checks; treat a non-zero exit the way you'd treat any other tamper alarm.

Combined with WORM mode

WORM (write-once-read-many) mode marks specific content types as immutable once published. Combined with the audit chain: published content cannot be edited (WORM) AND cannot be tampered with (chain). Two independent mechanisms; defense in depth.

What it doesn't do

Read the compliance use-case →

Related features

Resolved at build time via {% similar %} — cosine similarity over embeddings, not tag overlap. Zero arguments.

Audit-grade history — StaticOwl
67% match
Reviews that stay honest — StaticOwl
55% match
Functions — StaticOwl
50% match