Postgres audit tables, cloud ledgers and open source vs AuditKit
An append-only table with REVOKE UPDATE, DELETE and a trigger stops the application from editing history; it does not stop a superuser, a restore from backup, or a dropped partition. Immutability inside one database is a permission, not a proof. Below: each technique, the role that defeats it, and what adding a hash chain plus an external anchor changes.
Last updated 2026-10-05
What each Postgres technique buys
| Technique | Stops | Defeated by |
|---|---|---|
REVOKE UPDATE, DELETE on the audit table | The application role | Any superuser, the owner role, SET ROLE |
| Trigger that raises on UPDATE/DELETE | Casual edits | ALTER TABLE … DISABLE TRIGGER, session_replication_role = replica |
| pgaudit (statement logging) | Nothing; it records | Editing or rotating the log files it writes; it audits the database, it is not an immutable store |
Hash chain column (prev_hash) | Silent single-row edits | Recomputing the chain from the edited row forward; nobody outside can tell |
| Backups | Loss | Restoring an older backup erases the tail and nobody can prove it existed |
The practitioner consensus on Hacker News: "If you want immutable logs, you log to an external log server. Anything else seems security theater to me." The missing piece in every row above is a copy of the state that the DBA cannot reach. That is what anchoring a Merkle root to Rekor and OpenTimestamps adds: the root is outside the database, outside the backup, outside the vendor.
Cloud ledgers and open source
| Integrity claim | Proof verifiable outside the vendor? | Status | |
|---|---|---|---|
| Amazon QLDB | Cryptographically verifiable journal | Was AWS-bound | Retired 31 July 2025 (AWS shutdown list) |
| Azure Confidential Ledger | "no one — not even Microsoft — is 'above' the ledger"; Merkle receipts | Receipts verify against Microsoft's enclave attestation; Azure-only | Live |
| Google Cloud Audit Logs | "Log entries written by Cloud Audit Logs are immutable." | No proof format; Google's word; _Required bucket 400 days, not configurable | Live; logs Google's platform, not your app |
| immudb (open source, Apache 2.0) | "Data can only be added, never changed or deleted, and every read can be answered with a cryptographic proof." | Client-verified, but the root of trust is the immudb server you run | Live |
| Retraced (open source) | Hosted/self-hosted audit log API with viewer | No external anchoring described | Live: repository active, pushed August 2026, about 450 stars |
| Pangea Secure Audit Log | Merkle trees; roots published to Arweave hourly or every 10k events | Yes (Arweave) | Product URLs now redirect to CrowdStrike Falcon AIDR; future unclear |
| AuditKit | Hash chain, signed receipts, Merkle roots in Rekor and OpenTimestamps | Yes: offline verifier, pinned public key, AGPL self-host | Live |
Build vs buy
Build if you need an audit table for your own debugging. Buy, or self-host this, if a customer's security questionnaire asks how you prevent tampering, because that answer needs signing, anchoring, a verifier and a retention story, and Velt's estimate for even a basic build is "6-12 weeks": "Rolling your own means building append-only storage, hash chains, query interfaces, and compliance-ready exports before you've logged a single event that matters." The hybrid: keep your Postgres table for queries, and send each row to AuditKit for the receipt and the anchor.
Sources: AWS service shutdown list, learn.microsoft.com Confidential Ledger overview, docs.cloud.google.com/logging/docs/audit, immudb.io, GitHub API for retracedhq/retraced, pangea.cloud/docs/audit/about-tamperproofing, velt.dev, Hacker News item 44602532 (all fetched 2026-10-05/06).