Auth APIs
Device code flow endpoints for CLI authentication — generate, exchange, refresh.
Auth APIs
These endpoints implement the Device Authorization Grant (RFC 8628) for CLI authentication. See Authentication Flows for the complete flow.
Device Code Flow
POST /api/auth/cli/generate
Called by the browser (authenticated user) to approve a CLI login attempt.
Requires: Active browser session (Supabase auth cookie).
Body:
{
"device_code": "uuid-from-cli"
}Effect:
- Creates a
cli_loginsrecord with the device code, user profile ID, and a 6-character verification code - The verification code is displayed in the browser for the user to type into the CLI
POST /api/auth/cli/exchange
Called by the CLI to exchange the device code + verification code for tokens.
No authentication required (the device code + verification code pair is the proof).
Body:
{
"device_code": "uuid-from-cli"
}Validation:
- Looks up the
cli_loginsrecord by device code - Verifies that
profile_idis set (meaning the browser approved the login)
Response:
{
"access_token": "jwt...",
"refresh_token": "jwt...",
"provider_token": "git-oauth-token",
"user_email": "user@example.com"
}Token Details:
- Access token: 1-hour TTL, HS256 signed with
CLI_JWT_SECRET - Refresh token: 90-day TTL, same signing
JWT payload:
{
"sub": "user-uuid",
"email": "user@example.com",
"type": "access",
"iss": "urn:example:issuer",
"aud": "urn:example:audience"
}POST /api/auth/cli/refresh
Called by the CLI when the access token expires.
Body:
{
"refresh_token": "jwt..."
}Response:
{
"access_token": "new-jwt...",
"refresh_token": "new-jwt..."
}Both tokens are rotated on refresh — the old refresh token is invalidated.
OAuth Callback
GET /api/auth/callback
Handles the OAuth redirect from Supabase after provider authentication. Captures the authorization code and provider token, then redirects to the intended page.
The middleware intercepts OAuth callbacks to save provider_token before the redirect reaches the final destination.