allod secret rotate: replace a credential's value across its rotation group #207
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
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/tools!207
Loading…
Reference in a new issue
No description provided.
Delete branch "agent/secret-rotate"
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 rotate <name>replaces a credential's value on the host, the third landing shape besidecreate(first value) andrekey(new recipients). It rotates the whole registry group the credential belongs to from one value on stdin, carries the non-secret fields of the two structured formats forward, runs the repository's checks, commits, pushes, and prints the deploy, verify, and revocation steps from the registry. Nothing changes on any machine until nexus'sallod-toolspin moves; the command compiles only behind thesecrettag, so dev machines still do not carry it.rotate-tokenis untouched in this PR and keeps itsrefresh-local-authjob. The proof is a tagged test suite over fakeage,nix,git, andrclonecovering every format, refusal, dry run, and landing outcome; no live rotation has run, because no agent machine holds an age identity. If it misbehaves, revert this PR; a landed rotation is a commit on a branch that was never merged.Two decisions the issue left open
forgejo-token-groups.jsonandlib.forgejoTokenGroupskeep their names. The rename is cross-repo (archetypes reads the export) and is now its own issue, allod/secrets#22.rotate-token. It installs root-owned netrc bundles under sudo, a privilege class a git-repository command should not hold. When the group carrieslocal_auth_refreshentries the printed steps includerotate-token refresh-local-auth --group <alias>as the operator's next step. Retiring the rest ofrotate-tokenonce this is deployed is allod/nexus#52.What the command does
allod secret rotate <name> [<checkout>] [--dry-run], taggedsecret. The name selects the registry group listing it; every credential in that group is re-encrypted from the one prompted value, the wayrotate-token --groupdoes. No selector flags.create: checkout from the repository registry or the positional; non-default branch; clean tree; every credentialactivewith exactly one agenix consumer, its ciphertext present, itssecrets.nixrecipients including the host identity; registry shape asrotate-token's validator accepts; every group member in exactly one group; formats able to share one prompted value. The branch and tree are rechecked after the value is read, before anything is written.raw-forgejo-tokenverbatim;credential-store-urlkeeps user and host and splices the new token;rclone-remote-stanzakeeps type, host, user, and explicit_tls and replacespasswithrclone obscureoutput. Structured values are refused if they carry whitespace, control characters, or URL delimiters.rcloneis looked up before stdin is read.nix flake check, restore on failure, one commit (rotate <alias> Forgejo tokenforforgejogroups,rotate <alias>otherwise), push. A push failure keeps the commit, still prints every step, then exits non-zero.--dry-runruns every gate above, decrypts nothing, reads no value, runs no checks, and prints the group summary and steps.forgejogroups; the merge step in place of manual git.Risk
R3. Writes to the authoritative secrets repository and pushes, on a non-default branch with a clean tree, every effect built in memory first, checks gating the commit. Worst credible failure after the tests pass is a format carry-forward that differs from
rotate-token's on a real ciphertext; the fake-agetests pin the exact plaintext fed to encryption for each format, and the first live rotation should be run with--dry-runfirst and verified with the printed probe before the old value is revoked.Validation
gofmt -l .empty;go vetandgo test ./...green untagged and withsite,secret, andsite,secret, run by the overseer in the branch worktree after the final commit.rotateis asserted unknown in the untagged build.forgejoandnonegroups with and without the refresh step; checks fail restores; push failure prints steps and keeps the commit; atomic replacement leaves no temporary files.%accepted in a credential-store value, the refresh step phrased as an instruction in dry run, a wrong pointer in the push-failure text), fixed in the third commit and read by the overseer.Not run: a live rotation against real
ageandnixon the host.Refs allod/tools#182
Closes allod/tools#197
Superseded by allod/tools PR 208, which carries this branch's reviewed rotate work (squashed onto current master, adapted to the merged declare dispatcher) and moves declare, create, rotate, and the new migrate onto the credential value-template contract of allod/secrets#23. Nothing here was lost: every landing gate and its tests are in the new PR. The remote branch stays until that PR merges.
Pull request closed