Repository navigation
audit export drops the event chain, so an exported audit log cannot be verified anywhere #620
Description
sysknife audit export writes the transaction chain and drops the event chain, so the file it produces cannot be verified anywhere, including on the host that wrote it. sysknife audit verify checks both chains, and it only reads a live store.
At 82a087f, export reads one table (apps/sysknife-cli/src/runner.rs:1217):
store
.fetch_chain_rows()Verify needs both (runner.rs:1614):
let event_rows = match store.fetch_event_rows() {Transaction rows sign the event tip (crates/sysknife-daemon/src/audit_chain.rs:614-625), so a verifier holding only the exported rows cannot check them. AuditVerifyArgs (apps/sysknife-cli/src/cli.rs:195-206) takes --json and --pubkey <FILE> and has no way to name an exported file.
Why it matters
docs/vm-daemon-setup.md("More than one host") tells you to verify a remote host's chain by pulling "its database and public key to an auditor's machine". Copying a live SQLite file is the hard way, and open_read_only writes: audit verify and audit export migrate the database and fail on a read-only copy #267 means verify then fails on a read-only copy.- An auditor should be able to take one file and one public key and get a yes or no. The pieces for that exist:
verify_all_with_pubkeyandChainRow/EventRowboth serialise. - The fleet audit work (Fleet plan and execute: design and order of work #617) builds on this: a fleet verifier pulls one export per host and checks it against that host's pinned key.
Scope
- Make
audit exportwrite both chains as one versioned JSON document:{"version": 1, "chain": [...], "events": [...]}. The top-level shape changes, so name it in the CHANGELOG. - Add
sysknife audit verify --from <export.json> --pubkey <key.pub>. It verifies offline and never opens a database. --since/--limiton export cut the chain, so a partial export cannot verify from genesis. Either refuse--fromon a partial export with a clear message, or record the startingprev_chain_hashand verify from it. Pick one and document it.- audit export publishes request_hash, an unsalted hash over unredacted params, with no statement of its sensitivity #268 is closed: fix(security): key request_hash with an HMAC under the audit key (chain_version 4) #627 (
223e86e) maderequest_hashan HMAC under the host's audit key, atchain_version = 4. This issue changes the container; it should not change what each row contains.
Tests first
- Export a store with a few transactions and events, verify the file with
--from: intact. - Flip one byte in an event row in the file: verify reports the event chain broken and exits with the documented failure code.
- Drop the last event row: verify must fail. Remove the event check from the new path and this test must go green, which proves the event half is load-bearing.
Difficulty
medium: no new cryptography, but it changes a published output format and adds a verification mode.
Getting started
CONTRIBUTING.md has the build and test commands. No CLA and no copyright waiver. The project is MIT; sign off each commit with git commit -s (the required dco check enforces it since #732).
Activity
vladimirrott commentedon Oct 19, 2026
@ITSMERNB this fits what you did in #594 and #611: you made the CLI stop on a step that did not succeed and pinned it with tests that fail when the stop is removed. Here the audit export leaves out the event chain, so an export cannot verify anywhere, and the fix needs the same care about what counts as intact. It is yours if you want it; reply here and I will assign it.
vladimirrott commentedon Oct 24, 2026
@ITSMERNB I offered you this on 19 October and I'm putting it back in the pool so someone else can pick it up. If you want it later, say so here and it's yours again. Nothing is owed either way.
vladimirrott commentedon Oct 24, 2026
@k4its1t your #289 made
audit verifyreport checks that never ran, and #340 put the anchor into the verdict. An export drops the event chain today, so a verdict computed offline from an export cannot check what yours check on the live store. This issue closes that gap.I'm holding it for you. Say so here and I'll assign it. If it isn't for you, no reply needed.