mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-10 15:05:40 +00:00
5784d907c0
* feat(cli): PAD_TOKEN environment override for stored credentials (#879) Layer 1 of #879: if PAD_TOKEN is set, the CLI uses it as the bearer token and skips the credential-store lookup — gh's GH_TOKEN convention. Reads never write credentials.json, so a read-only override sidesteps the multi-agent identity contention completely; the store is never touched under the override. Per the acceptance grounding notes: - NewClientFromURL resolves PAD_TOKEN before the per-server store lookup (the single token-attachment chokepoint). - whoami no longer lies under the override: it skips the store short-circuit and reports the effective identity via a real /me fetch, with an 'Auth: PAD_TOKEN environment override' line. - auth login/logout print a gh-style stderr notice when the override is active. logout additionally pins its server-side session invalidation to the STORED token — an unpinned Logout() after the constructor change would have invalidated the env token's session — and skips the server call when there is no stored session. - pad init's status line and server info's report disclose the override (env_token_override field; the auth probe uses the token every other command would use). Zero behaviour change when PAD_TOKEN is unset. Token minting stays web-only; a minimal 'pad token' CLI is offered as a follow-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(cli): review round 1 — init fails on a rejected PAD_TOKEN; login shortcut skipped under the override; logout asymmetry documented Per the PR #1160 round-1 review: - Bug 1: pad init's auth step no longer falls back to stored credentials when a set PAD_TOKEN is rejected — it fails with the distinct rejected-token message (mirroring whoami), which also makes the status line's override disclosure truthful. Test drives the real padInitCmd flow and asserts the stored identity is never consulted. - Bug 2: login's 'Already logged in as <stored user>' shortcut is skipped when the override is active — it reads the store, and firing it right after envTokenNotice contradicted the notice. A second test pins the unchanged no-override shortcut behaviour. - Doc ask: the deliberate logout asymmetry (the env token's own session is never invalidated; its lifecycle belongs to the minter, GH_TOKEN posture) is now stated in env_token.go's doc comment and the README PAD_TOKEN section. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
34 lines
1.4 KiB
Go
34 lines
1.4 KiB
Go
package cli
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// EnvToken returns the value of the PAD_TOKEN environment variable,
|
|
// trimmed of surrounding whitespace. When non-empty, it overrides any
|
|
// credential stored in ~/.pad/credentials.json — the same convention as
|
|
// gh's GH_TOKEN (issue #879, layer 1).
|
|
//
|
|
// Why an env override at all: the credential store is per-server, not
|
|
// per-process, so several agent processes on one machine cannot act as
|
|
// different Pad users without contending over the file. Reads never
|
|
// write credentials.json (only login/setup/logout do), so a read-only
|
|
// override sidesteps the identity-switching contention completely —
|
|
// each process carries its own token in its environment and the store
|
|
// is never touched.
|
|
//
|
|
// Accepts either token type the server takes (padsess_ session or
|
|
// pad_ API token); API tokens are the intended fit (mint under
|
|
// Settings → API tokens in the web UI).
|
|
//
|
|
// Lifecycle asymmetry, deliberate: `pad auth logout` never invalidates
|
|
// the env token's own server-side session — it pins its Logout() call
|
|
// to the STORED token and only deletes the stored entry. The env
|
|
// token's lifecycle belongs to whoever minted it (revoke it where it
|
|
// was minted), exactly gh's GH_TOKEN posture. This is the read-only
|
|
// contract applied to logout, not an oversight.
|
|
func EnvToken() string {
|
|
return strings.TrimSpace(os.Getenv("PAD_TOKEN"))
|
|
}
|