BroomVA

Authentication

Authenticate the CLI with your BroomVA account using device-code flow or manual tokens.

Authentication

The CLI authenticates with the BroomVA platform to access your prompts, skills, and organization resources. Two authentication methods are supported.

The primary authentication method uses the OAuth 2.0 Device Authorization Grant (RFC 8628). This is the same flow used by GitHub CLI, Azure CLI, and other developer tools.

broomva auth login

The flow works as follows:

  1. The CLI sends POST /api/auth/device/code with client_id: "broomva-cli"
  2. The server generates a device code (64-hex-char random string) and a user code (format: ABCD-1234)
  3. The CLI displays both and asks you to open the verification URL in your browser
  Open this URL in your browser:
  https://broomva.tech/device

  Then enter this code:
  ABCD-1234

  Or open the direct link:
  https://broomva.tech/device?code=ABCD-1234

  Waiting for authorization...
  1. You open the URL, sign in (if not already), and enter the user code
  2. The CLI polls POST /api/auth/device/token with grant_type: "urn:ietf:params:oauth:grant-type:device_code" until you approve
  3. On approval, the server signs a JWT via signLifeJWT() and returns it as an access token (with an optional refresh token)
  4. The CLI stores the token in ~/.broomva/config.json
  Authenticated successfully! Token stored in ~/.broomva/config.json

If the server is unreachable or the device-code endpoint is not available, the CLI automatically falls back to the manual flow.

Server-side implementation

The device code flow is implemented across three API endpoints:

EndpointMethodPurpose
/api/auth/device/codePOSTIssue a device code + user code pair
/api/auth/device/authorizePOSTApprove or deny (called from the browser)
/api/auth/device/tokenPOSTPoll for the access token

Code generation: The user code uses a character set that avoids ambiguous characters -- letters ABCDEFGHJKMNPQRSTUVWXYZ (no I, L, O) and digits 23456789 (no 0, 1). This prevents confusion when reading codes aloud or entering them manually.

Rate limiting: The code endpoint is rate-limited to 10 requests/minute per IP. The token endpoint is rate-limited to 5 requests/minute per device code + IP combination. When the token endpoint detects excessive polling, it returns a slow_down error per RFC 8628, and the CLI backs off by an additional 5 seconds.

Expiration: Device codes expire after 15 minutes (expires_in: 900). The polling interval is 5 seconds by default.

Polling behavior

The CLI polls at the interval specified by the server (default: 5 seconds). The server responds with one of these RFC 8628 error codes:

ResponseMeaningCLI action
authorization_pendingUser has not acted yetContinue polling
slow_downPolling too fastBack off by 5 seconds
access_deniedUser denied authorizationExit with error
expired_tokenDevice code expiredExit with error
HTTP 200 + access_tokenUser approvedStore token, exit success

Token format

On approval, the authorize endpoint calls signLifeJWT() to create a signed JWT containing the user's ID and email. The token response includes:

{
  "access_token": "eyJ...",
  "token_type": "Bearer",
  "expires_in": 2592000,
  "refresh_token": "eyJ..."
}

The refresh_token is included when the auth system issues token pairs (introduced in BRO-121).

Manual token flow

If you prefer to copy a token directly from the web UI:

broomva auth login --manual

This flow:

  1. Instructs you to sign in at broomva.tech (email, Google, or GitHub -- accounts with the same email are automatically linked)
  2. Directs you to /api/auth/api-token to generate a token
  3. Prompts you to paste the token
  4. Validates the token against the server via the ApiClient.validateToken() method
  5. Stores the token in ~/.broomva/config.json

Token storage

Tokens are stored in ~/.broomva/config.json:

{
  "token": "brv_...",
  "apiBase": "https://broomva.tech"
}

The file is created with 0600 permissions (owner read/write only). The token is a JWT signed by the platform's auth system (Better Auth) that encodes your user ID and organization memberships.

Treat your token like a password. Anyone with your token can make API requests as you. If you suspect your token has been compromised, revoke it from the web UI and run broomva auth login to get a new one.

Token resolution order

When the CLI needs a token, it checks these sources in order:

  1. --token command-line flag
  2. BROOMVA_TOKEN environment variable
  3. ~/.broomva/config.json file

The first non-empty value wins.

Checking auth status

broomva auth status
# Authenticated (token from config-file)
# Token expires: 2026-04-21T00:00:00Z

With JSON output for scripting:

broomva auth status --json
# {"authenticated":true,"source":"config-file","expiresAt":"2026-04-21T00:00:00Z"}

The status command validates the token against the server. If the token is expired or revoked, it reports the token as invalid.

Printing the raw token

For use in scripts and curl commands:

broomva auth token
# brv_eyJ...

This outputs only the token string with no formatting, suitable for command substitution:

curl -H "Authorization: Bearer $(broomva auth token)" https://broomva.tech/api/...

Logging out

broomva auth logout
# Logged out. Token removed from ~/.broomva/config.json

This removes the token from the local config file. The token remains valid on the server until it expires -- logging out is a local-only operation.

On this page