Device Authorization
OAuth 2.0 Device Authorization flow for CLI and headless environments.
The Quickback CLI uses the OAuth 2.0 Device Authorization Grant (RFC 8628) for authentication in headless environments.
Flow
- CLI requests a device code from the API
- User sees a code in the terminal (e.g.,
AUL8-H93S) - User visits the approval URL and enters the code
- CLI polls
POST /auth/v1/device/tokenuntil the code is approved; the response'saccess_tokenis a signed bearer token - CLI calls
POST /cli/exchangewith that token to fetch user and session details
This flow works in SSH sessions, containers, and WSL where browser redirects aren't possible.
Token signing
Better Auth's device-flow token endpoint creates a session and returns its raw session token. Quickback's generated auth config requires signed bearer tokens, so a raw token would be unusable. When deviceAuthorization is enabled, the compiler emits an after hook on /device/token that signs access_token with BETTER_AUTH_SECRET before the response leaves Better Auth. The rest of the response (token_type, expires_in, scope) and the Cache-Control: no-store header are unchanged, and errors such as authorization_pending pass through as-is. The signing call comes from better-call (the same helper Better Auth's bearer plugin verifies with), so the generated package.json declares better-call at the exact version Better Auth depends on whenever deviceAuthorization is enabled.
The generated POST /cli/exchange route only validates a signed token. It doesn't sign anything:
| Request | Response |
|---|---|
Authorization: Bearer <signed token> for a live session | 200 with access_token (the same signed token), token_type, expires_in, session, user |
Authorization: Bearer <unsigned token> | 401 { "error": "invalid_token", "error_description": "A signed bearer token is required; the device-flow token endpoint already returns one." } |
| Missing header, bad signature, or expired session | 401 invalid_token |
/cli/exchange is reachable without authentication, so it must not sign tokens. If it did, anyone holding a raw session token from a database read, backup, or log could turn it into a working bearer token.
See CLI Reference for usage details.