--- title: 'Sign in and out' description: 'Authenticate the CLI with the device-code flow, and revoke the session again' position: 4 --- # Sign in and out > The two commands on this page write and remove the same file. > `stackbone login` writes the session to `~/.stackbone/credentials.json` and > `stackbone logout` removes it again. Nothing else on disk holds it. > Both wrap their `--json` output in the shared > [`{ "schema_version": 1, ... }` envelope](/docs/cli/reference/conventions#json-output) > and follow the common [exit codes](/docs/cli/reference/conventions#exit-codes). ## stackbone login Authenticate the CLI via the device-code flow (RFC 8628). Stores the session in `~/.stackbone/credentials.json` (chmod 600). The command prints a short user code and a verification URL, then waits until you approve the request. It opens the URL for you unless you pass `--no-browser` or the environment looks headless. The code expires on its own. A login you deny, or never approve, ends with exit code `2`. > [!NOTE] > The code box is printed in human mode only. With `--json` the command emits > one payload when the flow finishes and nothing before it, so run `--json` > login only where the browser can open by itself. | Flag | Type | Description | | -------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------- | | `--no-browser` | boolean | Print the verification URL + code instead of opening the browser. Auto-detected when `CI`, `SSH_CLIENT`, or `SSH_TTY` is set. | **JSON payload** ```jsonc { "schema_version": 1, "user": { "id": "...", "email": "..." }, "control_plane_url": "https://api.stackbone.ai", "expires_at": "2026-...", } ``` **Exit codes**: `0` ok, `2` auth, `1` generic. Once you are signed in, [`stackbone whoami`](/docs/cli/reference/inspection#stackbone-whoami) shows the user and the organization the session points at. ## stackbone logout Revoke the active session and drop it from disk. No flags. The credentials file holds one session per control plane you signed in to, and marks one of them active. `logout` revokes the active session on the server, removes it from the file, and promotes the next remaining session to active. The CLI deletes the file only when the last session goes, so signing out of one control plane leaves the others alone. Server-side revocation is best effort. A network failure does not stop the CLI from clearing the local session, so this machine still ends up signed out. **JSON payload** ```jsonc { "schema_version": 1, "control_plane_url": "https://api.stackbone.ai", "previous_user": { "id": "...", "email": "..." } /* or null */, } ``` **Exit codes**: `0` ok, `1` generic. Running `logout` with no session is not an error: the payload carries `"previous_user": null`.