Repository navigation
fix(audit): resolve checkpoint and MCP stores consistently - #636
Conversation
vladimirrott
left a comment
There was a problem hiding this comment.
Thanks, Danny. The fix is right: checkpoint, sysknife_audit_verify and the doctor chain check now resolve the store through resolve_audit_store(), the same resolver audit verify uses, and I found no default_database_path() caller left in apps/ outside the resolver. The choose_audit_store_with_paths seam is a good shape.
Two things before I merge.
1. The new tests pass with the call sites reverted. Every new test sets SYSKNIFE_DATABASE_PATH, and default_database_path() returns that variable first (crates/sysknife-core/src/lib.rs:44). Old and new code therefore read the same file in those tests. Put default_database_path() back at runner.rs:1383 or mcp_server.rs:1395 and nothing goes red. the_report_carries_the_which_machine_caveat pins audit_store_details, but it injects the store, so it never passes through the wrapper either. The bug in #557 lives in those call sites, so they need a test that fails when one goes back to the per-user path. The cheapest version that holds: a test that reads runner.rs and mcp_server.rs and fails if default_database_path( appears in an audit path outside the resolver. A seam on the system path (a resolve_audit_store_from(...) the wrappers call, driven by a test) is stronger if you'd rather.
2. checkpoint loses the sudo hint on a packaged install. As a non-root operator against the 0700 /var/lib/sysknife, path_is_present counts the EACCES as present, so checkpoint now picks the system store, then require_exists (runner.rs:2611, a plain Path::exists()) reports audit key not found at /var/lib/sysknife/.... audit verify gives the same person "the system daemon's store is root-owned, so run this under sudo" (runner.rs:1187). Reusing that hint in checkpoint would close it.
Small one: "Fixes #557 and #479" only links #557, since GitHub needs the keyword in front of each number. Fixes #557, fixes #479 closes both.
I'll write the CHANGELOG line at merge.
|
The parity test and docs are pushed, and the workspace baseline now matches the suite. All required checks passed on |
…olver # Conflicts: # README.md # docs/distro-support.md # docs/introduction.md # tests/evidence/workspace-tests.json
vladimirrott
left a comment
There was a problem hiding this comment.
Both items are done, and done the way I'd have asked for them. Approving at 00841e5b.
The wiring is pinned now. cli_and_mcp_audit_readers_do_not_bypass_the_shared_store_resolver reads runner.rs and mcp_server.rs and fails if either calls the per-user resolver. I proved it in a no-network container: the test passes as written, and with let resolved_store = sysknife_core::resolve_audit_store(); swapped back to AuditStoreChoice::PerUser(sysknife_core::default_database_path()), the same test FAILED. Checkpoint also gives the same sudo guidance as audit verify now, so a non-root operator on a packaged install gets told what to do instead of "audit key not found".
One small note for later, not for this PR: the scan matches the qualified sysknife_core::default_database_path(, so a future use sysknife_core::default_database_path; followed by a bare call would slip past it. Matching the bare name, or listing the import too, would close that.
The board is green, the baseline of 2,014 matches the suite, and the PR body now closes both #557 and #479. Merging through the gate.
Main reached 2,014 with lacs-project#636; this branch adds six, so the baseline is 2,020.
Minor release. #627 keys request_hash with an HMAC under the audit key (chain_version 4; previews stored by an older release fail closed after upgrading) and #639 changes the history request a newer CLI sends, so a caller relying on the old behaviour notices: the middle digit moves. Also: the planner sees only its host's distribution (#626, #656, #658, #684), checkpoint and the MCP audit tools share the audit-store resolver (#636), every workflow job has a time limit (#662), a weekly cargo audit (#640), release hardening (#635, #637, #660), and every published figure is rendered from its source (#685). Claude-Session: https://claude.ai/code/session_01UpyrhbDTW1gBwzGAC44GYU Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Routes audit verification, export, checkpointing, MCP doctor, and MCP verification through the shared audit-store resolver. On packaged installs, readers select the system daemon store when no explicit or per-user store exists. MCP verification includes
audit_store_notewith the reason and selected path when this fallback is used. Checkpoint errors explain when EACCES hides the root-owned system store and tell the operator to run undersudo.Related Issues
Fixes #557, fixes #479.
Validation
cargo fmt --all --checkandgit diff --checkpassed.cargo test -p sysknife-cli --bin sysknife --locked: 317 passed, including the source guard that rejects audit callsites bypassing the shared resolver.cargo test -p sysknife-core --locked: 102 passed plus 1 doctest.bash scripts/check_repo_completeness.shpassed.2,000+.scripts/check_test_reachability.shcould not run because PyYAML/yamllint is not installed in this environment.scripts/render_figures.py --writeis blocked locally because macOS/bin/bash3.2 cannot run the metadata script's associative arrays; no rounded figure changed.None. The focused tests and CLI unit suite pass; CI on this updated head is pending.No live audit store was accessed. No privilege or trust boundary changed; the daemon remains the only privileged executor.
AI assistance: Codex assisted with implementation and tests.