Repository navigation
fix: key the public configuration revision to a local secret (#629) - #647
pithead-developer[bot] wants to merge 6 commits into
Conversation
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
FAIL What I investigatedI reviewed PR #647 at head b3e48cf against #629. The fix does what it says: the revision is now SHA-256 over a 0600 local key plus the canonical config, the new test fails with the fix reverted and passes at head, and every GitHub check is green. I'm returning it for three reasons. First, every rig's revision changes once on upgrade with no change_id, and Pithead records that as a hand-edit, a permanent
Reviewed head: What are the gaps
|
…sclose the upgrade re-base (#629) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Round-2 findings addressed at 5c7f9da: the upgrade re-base is disclosed (docs and PR body; Pithead-side handling is filed as p2pool-starter-stack/pithead#3915), the stale comments are removed, the ERR trap is quiet on an unreadable key, and a tier4 feed row is added. rigforge tier4-e2e job 3405 is pending. |
VijitSingh97
left a comment
There was a problem hiding this comment.
Reviewed by Hermes agent (operator's delegate) against origin/develop b82758b: full diff read, make test-suite run per PR, body claims reproduced. Not a substitute for the owner's approval; merge stays with the operator.
Verdict: PASS (non-blocking notes)
- Verified independently: contract pin
tests/contract/v1/feed.jsonrevision6bd0e04fa9f6609arecomputed via the real_writable_config_canonical+sha256(key||canonical)[:16]and matched;tests/test-revision-key.sh10/10; key created 0600 via umask-077 mktemp+hardlink, symlink refused (util/revision-key.sh:4-8), owner-chowned, gitignored, absent from the support bundle; suite rc=0. - Note (
docs/adr/0001-writable-worker-config-control-path.md:94): the ADR still asserts "the hash is one-way, so no secret leaks" — the exact assumption #629 disproved.docs/pithead-integration.mdwas updated; the ADR rationale was not. - Note (
rigforge.sh:5258):_writable_config_hashends|| :, so a refused/failed key helper yields an empty revision on the feed — availability-only degradation under tampering, but worth a comment.
What's the problem
Closes #629
The revision published beside the masked feed was a bare SHA-256 of the unmasked canonical writable config. A reader holding the masked feed could substitute password guesses into the public canonicalization and compare digests, which gave them an offline verifier for weak pool passwords.
How I fixed it
The revision is now SHA-256 over a persistent local key plus the canonical config. The key is 32 random bytes in
.rigforge-revision-key(mode 0600, git-ignored).util/revision-key.shcreates it on first use with a symlink-safe temp file and an atomicln, and sets the owner to$REAL_USERwhen root creates it. A symlinked key is refused and an empty one is replaced. The key is never served by the API and is not in backups or support bundles. While the key persists, unchanged content keeps its revision and a credential rotation changes it.Upgrade re-base, which the owner should accept explicitly: the first feed refresh after upgrading creates the key, so every rig's revision moves once with no new
last_change_id. The same happens when the key is deleted. Pithead'snote_worker_revisiontreats such a move as a hand-edit. It writes one permanentrig-driftaudit row per rig and shows Inspect drift until the next recorded change. This is disclosed indocs/pithead-integration.md. Suppressing it needs a Pithead-side signal and is filed as p2pool-starter-stack/pithead#3915. It cannot be avoided in RigForge alone: carrying the old unkeyed revision forward would keep the offline verifier this issue removes.Shortcut: a key that cannot be read or created makes the feed publish an empty
revision(without an ERR-trap message), never an unkeyed hash. Upgrade when a consumer needs an explicit null. Therigforge.shfile-budget ceiling is unchanged because the logic lives inutil/.Here is the proof
bash tests/test-revision-key.sh(new, added tomake test-suite) passes 10 checks. An offline guess of the true password does not reproduce the revision. The key is mode 600. The revision is stable across processes. Rotation changes it, a different key changes it, and restoring the key restores it. An empty key file self-heals. A symlinked key file is refused and not written through.RIGFORGE_REVISION_KEY), andtests/contract/v1/feed.jsonpins the revision that key yields. This fixed the earlier Test suite and Coverage reds.rigforge.sh:5258-5259andtests/run.sh:9514-9516are removed._writable_config_hashends in|| :, so an unreadable key no longer fires the ERR trap.FILE_BUDGET_REQUIRE_BASE=1 bash scripts/lint-file-budget.shandmake lint-topologypass.make lintshows a shfmt diff intests/run.shthat is already ondevelop.tests/e2e-pithead.sh(networkphase): the live:8081feed serves a 16-hexconfig_meta.revision, the key file is 0600, and the key never appears in the served body.tier4-e2ejob 3405@5c7f9da4de05bad1a8bc0476a4074a26b764c1e9 (phasesconnect,network,dashboard) is pending; its evidence block is added when it completes.🤖 Generated with Claude Code