HMAC-chained audit log
Every privileged action, signed and chained.
Every privileged action that completes writes an audit row. Per-row HMAC-SHA256 signed with Z4J_AUDIT_CHAIN_SECRET, a dedicated key separate from the application secret and required outside development, plus prev_row_hmac so consecutive rows form a chain, and a separately authenticated head and row count. An edit or a deletion that does not come from the audit service leaves the two out of agreement, which verification reports. This covers application bugs, a downgraded adapter and an operator mistake; it does not cover a role holding write access to the database itself, and the threat model says so plainly.
Mockup of the dashboard view for this feature. Live-reloading and themed to match your dashboard.
Ships with
- Per-row HMAC (detects modification)
- Chain anchor plus an authenticated head and row count (detects deletion)
- Signed with a dedicated key, so an auditor can verify without holding the session key
- z4j audit verify walks the chain on demand, or on a schedule via an opt-in worker
- Row id folded into HMAC input (prevents row cloning)
- Verifiable against a head exported off-box, which is what covers the database-role case