Skip to content

feat(003): auth + control-plane API client (login, whoami, api module)#2

Merged
bartekus merged 1 commit into
mainfrom
003-auth-api-client
Jul 15, 2026
Merged

feat(003): auth + control-plane API client (login, whoami, api module)#2
bartekus merged 1 commit into
mainfrom
003-auth-api-client

Conversation

@bartekus

Copy link
Copy Markdown
Contributor

Summary

Implements spec 003 (auth + control-plane API client): the auth and api modules, stagecraft login (browser-assisted bearer-token handoff) and stagecraft whoami, a 0600 per-base-url credentials store, a uniform API error taxonomy, GET-only retry with jitter, and a global --debug flag.

The auth mechanism is recorded in the spec: the preferred RFC 8252 loopback OIDC flow needs control-plane additions that do not exist yet (a public rauthy client with a loopback redirect, and a token-return endpoint), so the paste fallback is the sanctioned v1. The credentials store and bearer replay are independent of acquisition, so the loopback flow drops in later with no change to the store or the api module.

Testing

  • cargo fmt --check, cargo clippy --all-targets -- -D warnings, cargo test (36 tests: credentials 0600 round-trip and stale-temp tightening, GET-only retry, 401 to login hint, whoami happy/sad via httpmock, whoami JSON shape)
  • spec-spine compile && spec-spine index check && spec-spine lint --fail-on-warn && spec-spine couple

Manual e2e against a live control plane is deferred per spec section 1: the control plane is pre-code, so no plane is reachable. Spec 003 stays implementation: in-progress with a dated Status note until that check can run.

Spec-Drift-Waiver: spec 003 fills in the scaffold that spec 002 established. 002 section 2 placed the src/ tree and the login/whoami command stubs specifically "so later specs fill them in" and predicted "Async arrives with spec 003 (tokio + reqwest)". The 002-owned paths changed here (Cargo.toml, Cargo.lock, src/cli.rs, src/commands.rs) together with the new src/api.rs and src/auth.rs modules that 003 establishes are exactly that scaffold fill-in; no 002 design is contradicted, so this is a coupling waiver, not a coherence override.

Implement spec 003. `stagecraft login` performs the browser-assisted
bearer-token handoff chosen in the spec's 2026-07-14 amendment: paste a
control-plane session token (piped or at a prompt), validate it against
GET /api/v1/auth/me, then store it in ~/.config/stagecraft/credentials.toml
at mode 0600, keyed by base URL. `stagecraft whoami` GETs the same endpoint
and renders id/email, exiting 1 when unauthenticated.

The api module gives every later verb a typed, authenticated request path:
a uniform error taxonomy (network, auth, api-4xx with server message,
api-5xx), retry with jitter for idempotent GETs only, and a global --debug
flag that dumps request/response metadata to stderr without credential
material. reqwest is rustls-only (never native-tls); tokio drives the async
verbs on a per-invocation runtime.

Auth decision (recorded in the spec): the preferred RFC 8252 loopback OIDC
flow needs control-plane additions that do not exist yet (a public rauthy
client with a loopback redirect, and a token-return endpoint), so the paste
fallback is the sanctioned v1. The credentials store and bearer replay are
independent of acquisition, so the loopback flow drops in later with no
change to the store or the api module.

Testing: cargo fmt --check, clippy -D warnings, and 35 tests (credentials
0600 round-trip and permission tightening, GET-only retry, 401 to login
hint, whoami happy/sad via httpmock, whoami JSON shape). Manual e2e against
a live control plane is deferred per spec §1: the control plane is pre-code,
so no plane is reachable; the spec stays implementation: in-progress with a
dated Status note. Spine gates green (compile, index check, lint, couple).

Spec-Drift-Waiver: spec 003 fills in the scaffold spec 002 established
(002 §2 placed the src/ tree and login/whoami stubs "so later specs fill
them in" and predicted "Async arrives with spec 003 (tokio + reqwest)").
The 002-owned paths here (Cargo.toml, Cargo.lock, src/cli.rs,
src/commands.rs) plus the new src/api.rs and src/auth.rs modules are that
fill-in; no 002 design is contradicted.
@bartekus
bartekus merged commit 74ddeb4 into main Jul 15, 2026
2 checks passed
@bartekus
bartekus deleted the 003-auth-api-client branch July 15, 2026 03:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant