Store multiple Pi bearer tokens and select one per process #36
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
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/strategy#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?
Let each managed Pi credential retain several encrypted named bearer tokens and let Pi select among them without changing providers, endpoints, or models.
Provider and token semantics
A provider remains an endpoint/API/model catalogue selected through
/model. A named token is an opaque bearer accepted by every provider attached to the same logical credential—for example, ordinary and promotional quota for one service./tokennever changes provider or model. Selection is per logical credential, so providers sharing that credential switch together while separate credentials remain independent.Token names are operator-chosen identifiers matching
^[a-z][a-z0-9-]{0,62}$. Generic code must not infer quota, age, priority, or exhaustion from a name.Startup selection
For each credential, a fresh Pi process resolves:
If an invalid remembered name is ignored, interactive Pi reports that it became stale. An unresolved non-interactive process fails with an actionable diagnostic. Adding a token never activates it or changes the deployment default. There is no startup token-selection flag in this scope.
Remembered state is a user-owned mode-
0600XDG state file containing only credential and token names. It is a preference, not a credential registry, and is safe to regenerate.Live
/tokeninterfacePi exposes only:
/token— show status and a picker for the current provider's logical credential;/token <name>— select a provisioned named token;/token cancel— cancel a pending switch.The command never accepts bearer input. When Pi is idle, selection takes effect immediately and is remembered. While a request or queued work is active, it records a pending switch; the active request and already queued work retain the old token, and activation waits until the agent is settled with no queued messages. The latest pending choice wins.
/token cancelremoves it.Activation re-registers every provider sharing the credential through Pi's supported extension provider API. It does not reach into private runtime objects or mutate extension-visible authorization headers. Concurrent Pi processes may select different tokens; changing remembered state does not retroactively alter another process's active selection.
Pi 0.84.2 supports this design: runtime API-key overlays are non-persistent, and supported
registerProvider()calls recompose provider authentication immediately. Token-specific command-backed keys avoid Pi's exact-command process cache while retaining the bearer-only stdout pipe.Lifecycle and storage
Host-side
pi-providerowns named-token creation, replacement, default selection, removal, recipient reprovisioning, and listing. Pi only selects names already provisioned on the VM. Each token has its own Age ciphertext and volatile mode-0600runtime file. Plaintext may cross only hidden lifecycle input, Age stdin, volatile delivery, and Pi's credential stdout pipe; it must not enter repositories, the Nix store, generated JSON, argv, environment variables, diagnostics, or persistent plaintext files.Removing a provisioned token removes it on targets through the existing rebuild/reconcile flow. A stale remembered name then follows normal startup resolution. There is no separate Pi retirement registry, automatic HTTP-error failover, retry, balance probing, or provider-side revocation.
Existing singleton credentials migrate forward without bearer re-entry: their ciphertext becomes the named token
default, and registry metadata declares it as the deployment default. The new implementation does not preserve downgrade compatibility with the legacy layout; rollback after migration is by roll-forward repair or by restoring both old data and old code together.Validation
Synthetic checks must prove independent add/rotation/removal of named tokens; singleton migration; shared-provider switching; startup precedence and non-interactive refusal; picker and minimal command behavior; immediate and pending live switching; latest-wins/cancel; two concurrent processes pinned to different selections; atomic mode-
0600remembered state; stale selection handling; generated activation/rebuild/reboot/removal behavior; and bearer non-disclosure across repositories, store closures, generated artifacts, argv, environment, diagnostics, and persistent home.Scope
In scope: the public credential registry contract, Nexus lifecycle commands, libvirt runtime delivery, Pi selection extension and command-backed authentication, forward migration, documentation, deployment composition, and synthetic generated-behavior checks across
allod/secrets,allod/nexus,allod/archetypes, andallod/deploy.Out of scope: real endpoint names, provider/model IDs, tokens, targets, or recipient keys in public history; provider-side issuance/revocation; automatic quota detection or failover; process-only startup overrides; microVM delivery; hiding delivered credentials from agents sharing Pi's Unix account; and private live-provider rollout.