Authentication

The CLI uses a device-code style browser approval flow. The terminal asks the API to create a device authorization, then a signed-in browser approves that user code.

Login

selltraces login
For SSH, CI-like shells, or terminals where opening a browser is not useful:
selltraces login --no-browser

Device login flow

The API only accepts the fixed selltraces-cli client id for CLI device login. Polling returns:
StateAPI response
Pending approval202 with { ok: true, status: "pending" }
Approved200 with { ok: true, status: "approved", token, userId }
Expired410
Already consumed409
Invalid code400

Machine token storage

After approval, the CLI writes the token to:
~/.selltraces/credentials.json
API requests use that token as a bearer credential:
Authorization: Bearer <token>
The web app also supports authenticated browser sessions for the same user-scoped API routes. Routes that can be used by the CLI call the shared getRequestUserId() path, which accepts legacy machine bearer tokens and Better Auth bearer sessions before falling back to browser session cookies.

Logout

selltraces logout
Logout removes this machine’s saved credentials. It does not delete the saved upload policy or local trace ledger, so returning users keep source approvals, blocked terms, and already-synced history.

Local development auth test

Run the web app with real Better Auth enabled:
# apps/web/.env.local
DEV_AUTH_BYPASS=0
BETTER_AUTH_URL=http://localhost:3000
APP_URL=http://localhost:3000
AUTH_REQUIRE_EMAIL_VERIFICATION=0
Then link the source-backed local CLI and run it with an isolated home:
pnpm cli:link-local
export SELLTRACES_TEST_HOME="$(mktemp -d)"

HOME="$SELLTRACES_TEST_HOME" selltraces login --no-browser
The local selltraces shim defaults to http://localhost:3000. The published CLI defaults to https://selltraces.com; use --api or SELLTRACES_API_URL only when intentionally targeting another origin.