> ## Documentation Index
> Fetch the complete documentation index at: https://docs.app.strix.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI login

> Sign in from the Strix CLI with the device authorization flow

export const ScarfPixel = () => <img referrerPolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=831669b6-b4bd-42cb-8832-2122c03e1d5f" alt="" width="1" height="1" style={{
  position: "absolute",
  width: 0,
  height: 0,
  opacity: 0,
  pointerEvents: "none"
}} />;

<ScarfPixel />

The CLI login endpoints let a terminal or a coding agent create a Strix account and get an API token without a dashboard visit. The flow uses OAuth 2.0 device authorization. The open-source CLI runs this flow with the `strix cloud login` command.

## Start device authorization

This endpoint does not require authentication. The browser step establishes the user identity.

```bash theme={null}
curl -X POST "https://app.strix.ai/api/v1/cli/login"
```

The response contains a `user_code`, a `verification_uri_complete`, a `device_code`, an `expires_in` value, and a poll `interval` in seconds. Show the `user_code` to the user and open `verification_uri_complete` in a browser. Keep the `device_code` private.

## Poll for completion

Poll this endpoint with the `device_code` at the returned interval.

```bash theme={null}
curl -X POST "https://app.strix.ai/api/v1/cli/login/poll" \
  -H "Content-Type: application/json" \
  -d '{"device_code": "<DEVICE_CODE>", "scope_profile": "recommended", "client_instance_id": "<STABLE_INSTALLATION_ID>", "device_name": "macOS CLI · a1b2c3d4"}'
```

Choose `scope_profile` as `minimal`, `recommended`, or `full`, or send a custom `scopes` array. The server always includes the minimum scopes `scans:read`, `scans:write`, and `billing:read`; the member's role caps the final set. The CLI exposes `--scope-profile` and `--scopes`.

The open-source CLI generates one opaque `client_instance_id` per installation and a privacy-safe `device_name` that contains no hostname. Sending both makes later sign-ins from the same installation replace that session's secret and expiry in the same database row instead of creating an unlimited series of keys. Different installations remain separately visible and revocable in **Settings → API Access** as CLI sessions. Omit both fields only for compatibility with an older client.

Without either field, the server uses Recommended: the three minimum scopes plus `vulnerabilities:read`, `vulnerabilities:write`, `schedules:read`, `schedules:write`, `assets:read`, `assets:write`, `organizations:read`, `uploads:write`, and `billing:write`. This lets an admin agent complete the user-approved Link/MPP credit top-up flow when a scan needs credits. Credential creation through `tokens:write` still requires Full or an explicit custom scope request. Workspace listing and switching the current CLI session do not themselves require `organizations:read` or `tokens:write`. Scopes that the member's role cannot receive are omitted.

While the user has not confirmed in the browser, the response is an error with the code `authorization_pending`. Continue to poll. If the response code is `slow_down`, increase the poll interval by 5 seconds.

## Interactive workspace and scope selection

Send `"interactive": true` in the poll request to select a workspace and scopes after the browser step. When the user confirms in the browser, the response then contains `selection_required: true`, a short-lived `selection_token`, the workspaces of the user, and the full scope catalog with descriptions. Each scope entry shows if the scope is part of the minimum set, if it is a default, and the lowest member role that can receive it.

Complete the login with the selection:

```bash theme={null}
curl -X POST "https://app.strix.ai/api/v1/cli/login/complete" \
  -H "Content-Type: application/json" \
  -d '{"selection_token": "<SELECTION_TOKEN>", "organization_id": "<uuid>", "scope_profile": "minimal"}'
```

The workspace must be one of the memberships of the user. The server always includes the minimum scopes. The role of the member limits the final set. The selection token expires after 10 minutes. The `strix cloud login` command uses this flow in an interactive terminal. It offers a workspace picker and the scope presets Recommended, Full access, and Minimal. The `--workspace` flag selects a workspace by name or ID without a prompt.

When the user confirms, the response contains the account and a personal API token:

```json theme={null}
{
  "api_token": "strix_...",
  "organization_id": "<uuid>",
  "organization_name": "My workspace",
  "email": "user@example.com",
  "expires_at": "2026-11-24T00:00:00.000Z",
  "is_new_user": true,
  "scopes": ["scans:read", "scans:write", "billing:read"],
  "scope_ceiling": ["scans:read", "scans:write", "billing:read"],
  "requested_scopes": ["scans:read", "scans:write", "billing:read"],
  "scope_profile": "minimal",
  "token_id": "<uuid>",
  "credential_source": "cli",
  "device_name": "macOS CLI · a1b2c3d4"
}
```

The `api_token` value is shown only once. Store it in a secure location. `scope_ceiling` is the immutable maximum authority accepted at this login; workspace and profile changes can narrow it but cannot widen it. Broader access requires another browser sign-in. For a first-time user, Strix creates the account and a default workspace automatically. The token is valid for 90 days.

## CLI output and automation

In a terminal, `strix cloud` output is compact and action-oriented: lists favor names, branches, lifecycle states, and numbered selectors. Internal organization and user IDs are omitted, while a required selector that is too long for a compact table is repeated losslessly in a copyable block. Paginated lists print the next `--page` or `--offset`, and detail views prioritize useful prose within a safe terminal bound. A bare resource group with a safe read operation runs its default list/read action; use `-h` or `help` to list that group's verbs. Pass `--json` for the complete record.

When stdout is redirected or is not a terminal, output automatically becomes JSON and the CLI never prompts. Binary downloads are the exception: redirect their raw bytes intentionally, or use `--output FILE --json` to write the file and receive structured download metadata.

## Workspaces

A personal token belongs to one workspace. Use these endpoints to list the workspaces of the user, create a workspace, and retarget the active personal token to another workspace. All three need a personal token from the login flow. A service token belongs to a single workspace and cannot use them.

### List workspaces

```bash theme={null}
curl -X GET "https://app.strix.ai/api/v1/workspaces" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"
```

**Required scope:** none. The bearer must be a personal token. Keeping this recovery operation scope-independent lets a Minimal CLI session discover and switch workspaces.

Each entry contains `id`, `name`, `role`, and `current`.

In an interactive terminal, the CLI presents the entries as a numbered list and hides the long IDs from the compact table. JSON output still contains the complete records:

```bash theme={null}
strix cloud workspaces             # numbered human-readable list
strix cloud workspaces --json      # complete records for agents
```

### Create a workspace

```bash theme={null}
curl -X POST "https://app.strix.ai/api/v1/workspaces" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Team"}'
```

**Required scope:** `organizations:write` and an admin role. This scope is not part of the Recommended preset.

The user becomes the admin of the new workspace.

### Switch the active token to another workspace

```bash theme={null}
curl -X POST "https://app.strix.ai/api/v1/workspaces/<ORGANIZATION_ID>/token" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "X-Strix-Workspace: <CURRENT_ORGANIZATION_ID>" \
  -H "Content-Type: application/json" \
  -d '{"scope_profile": "minimal"}'
```

**Required scope:** none. The bearer must be a personal token.

The user must be a member of the workspace. An ordinary switch preserves the server-side requested profile, then the target-workspace role caps its effective scopes. A `scope_profile` or custom `scopes` request may narrow within `scope_ceiling`; a request beyond the ceiling returns `403` and requires login again. The endpoint retargets the same row and keeps its bearer secret and expiry, making an exact retry safe after a lost response.

```bash theme={null}
strix cloud workspaces use 3              # number from the current list
strix cloud workspace use "My Team"       # singular alias and exact name
strix cloud workspaces use <WORKSPACE_ID> # stable ID for automation
strix cloud session scopes               # effective scopes and login ceiling
strix cloud session scopes set minimal   # narrow without logging in again
```

`workspace` and `workspaces` are aliases. The `use` selector accepts a displayed number, exact case-insensitive name, or workspace ID. If names are duplicated, use the displayed number or ID. A list number is convenient for a person but is not a stable automation identifier; an agent should use the ID from `--json`. Ordinary switching does not ask for scopes again. `workspaces use --json` returns the resulting profile, granted/requested/ceiling scopes, expiry, CLI-session metadata, and a `stored` boolean without returning the bearer secret. The CLI updates local metadata only after success and never persists `--token` or `STRIX_API_TOKEN` overrides.

## Session safety and revocation

Managed CLI-session requests include `X-Strix-Workspace` with the organization selected when the process started. If another shell switches the same device session, a stale command receives `409 workspace_session_changed` instead of silently running against the new workspace. JSON CLI output preserves the error code plus current and expected workspace IDs for agent recovery. `GET /workspaces`, `GET /cli/session`, and an exact workspace-switch retry remain available for recovery; stale processes cannot change scopes or revoke the session. Direct API clients using a CLI session should send the same header; ordinary API tokens are unchanged.

```bash theme={null}
strix cloud session                        # fetch remote session state
strix cloud session scopes --json          # effective/requested/ceiling scopes
strix cloud session scopes set recommended
strix cloud logout                         # remote revoke, then local deletion
strix cloud logout --local-only            # deliberate emergency local cleanup
```

`GET /api/v1/cli/session` returns the current session. `PATCH` changes `scope_profile` or custom `scopes` within the ceiling. `DELETE` revokes that same bearer without requiring `tokens:write`. Normal logout keeps the local token after transport or server failures so revocation can be retried; a definitive success or already-invalid (`401`) response permits local deletion. Revoked and expired CLI-session rows are retained for a bounded audit window, then purged.

## Tab completion

Completion is generated by the source CLI as well as packaged binaries. It
therefore works with `uv run strix` too:

```bash theme={null}
source <(strix completions zsh)
# From a source checkout:
source <(uv run strix completions zsh)
# bash: source <(strix completions bash)
# fish: strix completions fish | source
```

Add the appropriate command to the shell startup file to enable it in future
terminals. Completion covers cloud groups, verbs, flags, and singular resource
aliases; it does not send a request or expose token values.
