allod secret rotate: read the credential-store URL grammar as data #216
No reviewers
Labels
No labels
blocked
bug
decision
duplicate
enhancement
help wanted
invalid
landed?
question
ready-to-merge
stale
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/tools!216
Loading…
Reference in a new issue
No description provided.
Delete branch "agent/credential-url-predicate"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
allod secret rotatestops carrying its own copy of the credential-store URL rule. The regular expression and the blank-line class that decide whether a credential can feed a local auth refresh are now read from the secrets flake'slib.credentialStoreUrlexport at rotation time, next to thelib.credentialEncodingsread the command already makes, and the hand-written Go copy with its comment claiming parity with allod/archetypes and allod/nexus is deleted. What changes for a running machine: a rotation against a secrets checkout whose flake lacks that export is refused by name, pointing at allod/secrets#29, before anything is rotated, and an export whose grammar is empty or does not compile is refused rather than matching everything. What stays identical: which templates are accepted, because the exported expression is equivalent to the deleted literal and the shared 26-vector table pins both sides, and every other step of rotation. What proves it is the predicate test, which reads the table checked in undertestdataas a byte copy of the secrets file, a table test of the export decoding, the flake'sgo-checks, and a dry run of the built binary against the secrets PR worktree and against a checkout at current master. If this is wrong the symptom is rotate refusing a group with a message naminglib.credentialStoreUrl, and the fix is a straight revert. A deployment's private fork of allod/secrets must merge the template change from allod/secrets#29 before this build ofallodrotates against it.Refs allod/secrets#29
What changed
cmd/allod/secret_rotate.go:credentialStoreURLTemplateand its parity comment are gone;credentialStoreURLGrammarholds the two compiled expressions;nixEvalCredentialStoreURLreadslib.credentialStoreUrlthrough the existingnixEvalJSONpath and hands the result todecodeCredentialStoreURLGrammar, a pure function that maps nix'sdoes not provide attributewording to the named refusal, refuses an emptylineorblank_line, and compiles both;isCredentialStoreURLSourcetakes the grammar and, to agree with the table, also refuses a credential carryingformat(the registry decoder already refuses such a registry earlier, so this is not a new refusal on the rotation path);validateGroupMetadatapasses the grammar through.cmd/allod/testdata/credential-store-url.json: byte copy of the secrets file (grammar plus vectors). Until the archetypescredential-store-url-paritycheck lands,cmpagainst the secrets checkout is the witness that it has not drifted.cmd/allod/secret_value_test.go:TestIsCredentialStoreURLSourceruns the table;TestDecodeCredentialStoreURLGrammarcovers the missing-export text, an unrelated error passed through, an emptyline, a non-compilingline, and the real file. The hand-written accept and refuse lists are gone.secret_test.goandsecret_rotate_test.gowire the new eval seam into the existing fixture the waysecretEvalEncodingsis wired.Risk
R3. This is a cross-repo interface: rotation now depends on an export of the secrets flake, and a deployment's private fork must carry it before this build rotates against it, which is auth and secrets sequencing. What holds it there rather than higher: the accepted set is unchanged and pinned by the table on both sides, every new failure mode fails closed before rotation starts with a named message, and rollback is a straight revert.
Validation
Run by the overseer in the worktree at commit
5b5b5c2, withCGO_ENABLED=0undernix shell nixpkgs#go:cmp cmd/allod/testdata/credential-store-url.json <secrets PR worktree>/credential-store-url.json— silent.gofmt -l ./cmd ./internal— empty;go vet ./...— clean.go test ./...,go test -tags secret ./...,go test -tags site,secret ./...— all ok.-tags secret,site,allod secret rotate forgejo-https-token-allod-dev <secrets PR worktree> --dry-runreadslib.credentialStoreUrland proceeds to the group metadata guard, which refuses the public template's group for declaring noservice(pre-existing, unrelated). The same against a branch checkout at current allod/secrets master —could not evaluate lib.credentialStoreUrl in <checkout>: the secrets checkout does not export lib.credentialStoreUrl and predates allod/secrets#29.Run by the worker, output read by the overseer:
nix build path:.#checks.x86_64-linux.go-checks— built.blank_lineto[[:space:]]fails the test naming the carriage-return, vertical-tab and form-feed vectors; reverted,cmpsilent again.Cold cross-family review: codex
gpt-5.6-sol, reasoning efforthigh, on the commit before the fix round (e3254c3). One major, fixed: a missing or nulllinecompiled to an empty expression that matched everything; empty fields are now refused by name. Minor, fixed: the missing-export mapping was untested; it is now a pure function with a table test using nix's exact wording. Minor, body corrected: theformatrefusal is unreachable on the production path because the decoder refuses first; the exported expression is equivalent to, not identical with, the deleted literal; risk raised from R2 to R3 for the cross-repo sequencing. Findings after the fix round are settled by the runs above, not by another reading.5b5b5c2aceto08b381892b