Support per-target bearers in pi-provider #36
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/nexus#36
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Teach
pi-providerto give a single target its own bearer for a provider, so an operator can adopt the per-target credentials thatallod/secretsissue #16 makes expressible without hand-editing a registry or an Age ciphertext.Primary goals:
Current state
retargetis the only command that changes which machines reach a provider, and it is whole-credential by construction:scripts/pi-provider:119documents--targetas a replacement list, the retarget branch plans an encrypted token for every token of the credential, andprompt_and_encryptat:1185takes one hidden prompt per planned token before writing anything.collect_recipientsat:1086then reads one recipient set for the credential and asserts every token shares it, which is exactly right while a credential has one bearer for all its targets and has no meaning once each target has its own.So there is currently no way to say "add this machine, with this bearer, leave the others alone". Extending the target list re-encrypts the one shared ciphertext to a wider recipient set, which is the behaviour the linked contract issue exists to make optional.
Ordering
This cannot be designed before
allod/secretsissue #16 settles the registry shape, because the command surface follows from it: whether a target carries a credential reference, and whether a provider's credentials are addressed by target, determines whether this is a new flag on an existing command or a new command. Filed now so the tool half is tracked rather than discovered late; do not start it while the contract shape is open.Scope
In scope: the command surface for per-target bearers, the recipient assertions that keep each ciphertext narrow, the migration path for an existing shared credential, and the dry-run output that shows an operator exactly which machines gain and lose access before anything is written.
Out of scope: the contract change itself, tracked in
allod/secretsissue #16. Also out of scope: any change to how a shared credential behaves for deployments that keep using one.Delivered — branch
agent/per-provider-target-cliat97c172c, one commit on master44c18dc, built in a worktree on nix-dev, unpushed. Nothing merged; the relay hands the commit to this repo.What lands, against this issue's primary goals:
pi-provider target claim <credential> <dev-vm> <name>— adds a target with a bearer only it holds: one hidden prompt, one new ciphertext encrypted to that machine's keys plus the hypervisor, existing ciphertexts and recipient sets untouched.pi-provider target rotate <credential> <dev-vm> <name>— moves a claim to a fresh named token; the new ciphertext lands before the registry repoints, and the old one is retired once nothing claims or defaults to it. The all-claimed/default-claimed edge reassigns the deployment default in the same pass (dry-run printsDeployment default moves: <old> -> <new>).lib.piCredentialRecipients), not duplicated in bash.retarget,token remove, and discovery handle mixed plain/claimed credentials; shared-credential behavior is unchanged.docs/credentials.md— composed, resumable, with its one known limitation tracked in allod/nexus#83 (the last hop to zero shared targets).Validation:
bash tests/pi-provider.sh— 387 assertions, exit 0 (the pre-change suite was 336; every pre-existing case still passes, two fixture expectations updated where they encoded per-target-impossible behavior). One cold cross-family review pass (codexgpt-5.6-sol) found three should-fix defects — the schema port's stale global-uniqueness rule, a raw-object comparison that lockedadd/discovery out of mixed credentials, and an undeliverable rotate-on-claimed-default — all reproduced, fixed in the same commit, plus comment trims.Handoff — from nexus:
(
wt-nexusis a symlink on nix-dev to the worktree; the registry-id form alone would read the main checkout's HEAD.) Then pushagent/per-provider-target-cliand open the PR against master: suggested body —Closes allod/nexus#36andCloses allod/secrets#16(per that issue's scope note, the PR landing the tool closes the contract issue),Refs allod/nexus#83.## RiskR3 (secret custody, cross-repo tool surface);## Validationthe suite line and review summary above.Two owner-ruled changes to the record above, landed before relay — the branch is now
3186172(still one commit, still unpushed):targetnoun group:pi-provider grant <provider> <machine> [token-name](token named after the machine by default) andpi-provider rotate <provider> <machine> [new-token-name](no new name: rotate in place; with one: rename-and-retire, default moving with the claim). Readgrant/rotatewherever the record above saystarget claim/target rotate. Suite now 410 assertions, exit 0, overseer-run on3186172.Receive line, PR guidance, risk and the review history are unchanged. The suggested PR body's Validation line should read:
bash tests/pi-provider.js...bash tests/pi-provider.sh, 410 assertions, exit 0; one cold codex review round plus a rename round, overseer-verified.One more owner pass before relay, docs-only: the prose in
docs/credentials.mdnow uses one vocabulary —grant/rotateas the acts,shared token/claimed tokenas the states (defined once;claimedsurvives only because the tool's error strings use it). Final branch state:8330432, one commit, still unpushed. Receive line and PR guidance unchanged; suite 410 assertions, overseer-run.Landed as allod/nexus#95 from allod-dev: the delivered commit relayed by patch artifact, rebased onto master past allod/nexus#94 (one seam fix: master's
classify_addcalledprovider_credentialwith one argument; andadd --models-filenow runs on a split provider, with a test), suite 443 assertions, provisioning-contract check green, one more cold codex round. The PR carriesCloses allod/secrets#16.