Conversation
vladimirrott
left a comment
There was a problem hiding this comment.
Thank you for this, and welcome. You took the part of #483 that was easiest to skip, the request to pin the wording so it cannot drift back, and you did it rather than writing a sentence saying why it was hard. The preamble rewrite is accurate: it names the sequential-gate framing, the User=sysknife line, and the three grants that reach root on their own, and it points the reader at packaging/sysknife-sudoers where the honest wording already lived.
One blocking item, and it is the guard rather than the prose.
The pin cannot fire on the file it was written for. reject_pattern runs over claim_files, which check_public_claims.sh reads from CLAIM_FILES in check_evidence_claims.py. SECURITY.md is not in that list:
$ python3 -c "
import importlib.util
spec = importlib.util.spec_from_file_location('c','scripts/check_evidence_claims.py')
m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m)
print('SECURITY.md screened:', 'SECURITY.md' in m.CLAIM_FILES)
print('files:', len(m.CLAIM_FILES))"
SECURITY.md screened: False
files: 16
I applied your reject_pattern line verbatim to main, put the retired sentence back into SECURITY.md, and ran the check:
$ grep -c 'Every layer is independent' SECURITY.md
1
$ bash scripts/check_public_claims.sh; echo "rc=$?"
Published figures match the evidence artifacts.
Public claims are internally consistent.
rc=0
Green, with the exact sentence the pin exists to reject sitting live in the tree. Adding SECURITY.md to CLAIM_FILES is the fix. Please check what else that turns red before you push: the file is long and the other reject_pattern calls will start seeing it for the first time, which may surface real wording to fix or may need the pattern scoped.
Whatever you land, show the mutation in the PR: the sentence restored, the check red, the sentence removed, the check green. A guard that has never been observed failing is the defect this tracker catches most, and it is the one thing #483 asked for that nothing else in the diff can demonstrate.
Two smaller notes, neither blocking:
scripts/check_public_claims.sh goes from mode 100755 to 100644 in the diff. The release rehearsal calls it as bash scripts/check_public_claims.sh so nothing breaks today, but it is almost certainly not what you meant. chmod +x and amend.
The apt-get grant you cite as trailing-wildcard is spelled env DEBIAN_FRONTEND=... NEEDRESTART_MODE=a /usr/bin/apt-get *, and v0.19.0 and v0.20.0 have since narrowed sixteen of the grant families your text describes, including systemctl and useradd. Rebase on main and the ROOT_SHELL_UNITS section will need one adjustment: systemctl now carries per-subcommand constraints, so sudo -n /usr/bin/systemctl start rescue.target is refused by the grant itself. The denylist-is-not-containment point still stands and is still worth making; the worked example needs a different verb.
Once the pin bites and the mode bit is back, this merges. Say the word if you would rather I take the CLAIM_FILES half and leave you the prose.
If you administer Linux boxes yourself, sysknife doctor and sysknife audit verify are read-only and take nothing but a checkout, and I would rather hear what they get wrong on a real host than guess.
What
Rewrite the Security Model preamble in
SECURITY.mdso it matches the trust boundary already described inpackaging/sysknife-sudoers, and pin the replacement wording inscripts/check_public_claims.sh.sysknifeservice account is root-equivalent by design.ROOT_SHELL_UNITSexample: the denylist stops unit names from the LLM/MCP path; it is not containment.Why
Closes #483.
SECURITY.md:43-44andpackaging/sysknife-sudoers:9-12describe the same trust boundary and disagree. All five layers run inside one process assysknife, and that account holdsuseradd,systemctl, and a trailing-wildcardapt-get— each reaches root on its own. The sudoers header is accurate; the independence sentence invites a reader to treatROOT_SHELL_UNITSas containment.check_public_claims.shYes, the replacement wording can be pinned there, and this PR pins it:
A sentence that drifted once will drift again.
How checked
SECURITY.mdagainstpackaging/sysknife-sudoersandpackaging/sysknife-daemon.service.ROOT_SHELL_UNITSincrates/sysknife-daemon/src/actions/validate.rs(refusesdebug-shell/emergency/rescue/runlevel1/singlefor typed actions) and kept both what it does and what it does not do in one place.SECURITY.mdfor sentences leaning on independence; Layer 4 already carries the right register ("This boundary protects against an untrusted MCP agent, not against arbitrary malware already running as the same Linux user").Note
#483 was offered to @mikevillari. If that work is already underway, please close this in favour of it — happy to rebase or drop.