feat(cli): auth scaffold — login/logout/auth status + config + backend client (cli#83)#85
Merged
Merged
Conversation
…d client (cli#83)
RFC-0001 (backend#830) Phase-1 CLI side, scaffolded ahead of the backend
device-grant so it activates the moment backend#835 ships.
- internal/config: ~/.tracebloc config store (0600, atomic write) — backend
env + user token + active client. Fully functional + unit-tested.
- internal/api: backend REST client. CLIENT_ENV -> {dev,stg,prod} base URL
(matches the installer's _backend_url); proxy + CA aware (honors
HTTP(S)_PROXY / NO_PROXY + the system cert pool, for corporate-proxy
networks); the RFC 8628 device-flow methods (RequestDeviceCode + PollToken
with the authorization_pending / slow_down / expired_token / access_denied
states). Unit-tested via httptest.
- internal/cli: `tracebloc login` (device flow — show URL + code, poll, store
the token), `logout`, `auth status`. `client create/list/use` are stubbed
(cli#84 — they need the user token from login + provisioning backend#836).
login calls /device/code + /device/token, which land in backend#835; until
then it reports that the backend doesn't support browser sign-in yet. Builds,
gofmt-clean, unit-tested (config round-trip + 0600 mode; api URL map +
device-flow poll states); `tracebloc --help` lists the new verbs.
Part of cli#83 / backend#830 (end-to-end login activates with backend#835).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Author
|
👋 Heads-up — Code review queue is at 33 / 30 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
…86) * feat(cli): authenticate with Bearer + verify token on login (cli#83) Completes `tracebloc login` against the now-built device-grant endpoints (backend#846). The token the flow issues is a ClientAccessToken, which the backend authenticates as `Authorization: Bearer` (ClientAccessTokenAuthentication, backend#835) — not the legacy DRF `Token` scheme the client was sending on authenticated requests, which would have failed to authenticate a logged-in token. - internal/api: authenticated requests now send `Bearer <token>` (was `Token`); add get() + WhoAmI() (GET /userinfo/) to confirm the token + fetch the account. - login now verifies the freshly-issued token (best-effort) and stores/shows the account ("Signed in as you@co.com"); a failed lookup never fails a valid sign-in. - tests: WhoAmI sends Bearer + parses the identity; a 401 surfaces as an APIError. The device-flow contract (paths/fields/error codes) was already aligned with backend#846 — verified, unchanged. Stacked on cli#85 (auth scaffold). go build/vet/test green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(cli): cover the login command end-to-end + add test seams (cli#83) internal/api was unit-tested, but the login / logout / auth status COMMANDS weren't. Adds auth_test.go driving the full device-flow command against an httptest backend whose shapes match backend#846 — so it also guards the CLI<->backend contract that the Token->Bearer fix corrected: - login: device_code -> authorization_pending -> token -> WhoAmI(Bearer) -> "Signed in as ..." with config persisted; the 404 "unsupported backend" gate (asserts no token is stored); access_denied. - logout clears the token; auth status (signed-in + not-signed-in). Two unexported test seams in auth.go — newAPIClient (point at an httptest server) and pollAfter (fire the poll immediately) — since the flow otherwise makes real HTTP calls on a timer. go build / vet / test green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
RFC-0001 (epic backend#830) — the CLI auth side, scaffolded ahead of the backend device-grant so it activates the moment backend#835 ships. Part of cli#83.
What's here
internal/config—~/.tracebloc/config.jsonstore (mode0600, atomic write): backend env + user token + active client. Fully functional + tested.internal/api— backend REST client:CLIENT_ENV→{dev,stg,prod}base URL, kept in lock-step with the installer's_backend_url;HTTP(S)_PROXY/NO_PROXY+ the system cert pool — RFC-0001 must work behind a corporate / TLS-inspecting proxy, backend#830 Q1);RequestDeviceCode+PollToken, with theauthorization_pending/slow_down/expired_token/access_deniedstates). Tested viahttptest.internal/cli—tracebloc login(device flow: print URL + code, poll, store the token),logout,auth status.client create/list/useare stubbed (that's cli#84 — they need the user token fromlogin+ provisioning backend#836).Functional now vs pending #835
logindevice-flow logiclogout,auth statusclient create/list/useTest plan
gofmtclean ·go build ./...·go test ./...(all 8 packages) green.internal/config: save/load round-trip,0600mode, missing-file→empty, clear.internal/api:BaseURL/ResolveEnvmapping;RequestDeviceCode+PollToken(pending→slow_down→success, and denied) viahttptest.tracebloc --helplistslogin/logout/auth/client.Opening as a reviewable scaffold (not a draft) — the config + api are fully functional, and
logindegrades gracefully until backend#835. Reviewers can merge now or hold for #835.🤖 Generated with Claude Code