lacs-project / lacs-project/sysknife

audit verify says OK over a wiped log, so an empty store and a deleted one read the same

Open
#338 8 comments 0 reactions 0 assignees View on GitHub
bug help wanted medium
Dominant language
Rust
Stars
12
Forks
19
Avg merge
18h 57m
Merged PRs (30d)
116

Description

`sysknife audit verify` reports success over a database whose rows have all been deleted.

```
$ sqlite3 daemon.sqlite 'DELETE FROM transactions; DELETE FROM audit_events;'
$ sysknife audit verify
OK: 0 row(s) verified in .../daemon.sqlite
NOTE: no independent checkpoint anchor is configured, so removal of the newest rows
would not be detectable — a truncated chain still verifies. Set SYSKNIFE_CHECKPOINT_DB
and run `sysknife audit checkpoint` periodically; see docs/the-audit-chain.md.
OK: 0 approval event(s) verified
OK: 0 row(s) still match the approval event they committed to
$ echo $?
0
```

Three previously signed actions were deleted. The verdict is `OK` and the exit code is 0.

## Why this is not simply a bug

A forward hash chain cannot detect the removal of its own tail without an external anchor. That is what checkpoint anchoring exists for, the tool says so in the NOTE, and `docs/the-audit-chain.md` explains it. Nothing here is hidden.

The problem is what an operator reads. Two very different states produce the same headline:

- a fresh install where nothing has run yet
- a host where the entire trail was deleted

Both print `OK` and exit 0. The one line that distinguishes them is a NOTE the reader has to interpret, below a verdict that already told them everything is fine.

## Scope

Make the verdict carry the distinction the tool already knows:

- **Zero rows and no anchor configured** is not `OK`. It is "nothing to verify, and this command cannot tell an empty log from a deleted one". A distinct exit code, or at minimum a different word than `OK`, gives a monitoring script something to alert on.
- **Zero rows with an anchor configured** genuinely is verifiable: the anchor either names a tip that should exist or it does not. That case can stay `OK` or become an explicit failure, and the anchor is what makes the difference.
- The `--json` shape should carry the same distinction, since that is what automation reads.

Worth considering alongside it: whether the daemon should anchor on a schedule by default rather than only when `SYSKNIFE_CHECKPOINT_DB` is set, so the mitigating control is not opt-in on a product whose subject is tamper evidence. That is a bigger decision and can be split out.

## Tests first

A test that writes rows, deletes them, and asserts the verdict is not the same one a fresh store produces. Then a second that configures an anchor and asserts the truncation is caught, so the fix is proved to add detection rather than only to change wording.

## Difficulty

`medium`. The verdict logic is small; deciding the exit-code contract is the part that needs care, and #335 is already open on exit codes generally.

## Getting started

[CONTRIBUTING.md](https://github.com/lacs-project/sysknife/blob/main/CONTRIBUTING.md) has the build and test commands, and [docs/the-audit-chain.md](https://github.com/lacs-project/sysknife/blob/main/docs/the-audit-chain.md) covers what the chain does and does not protect. No CLA and no copyright waiver. The project is MIT.

Contributor guide

Open the contributing guide

Research direction

Read CONTRIBUTING.md and docs/the-audit-chain.md, then run the sqlite reproduction and locate the implementation of `sysknife audit verify`, including its JSON and exit-code handling. Done means a fresh empty store and a wiped store without an anchor produce distinct results, an anchored truncation is detected, and the same distinction appears in `--json` output.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, sqlite
Domain
cli, databases, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.