Getting started: human identity (atc auth login)
This is the quickstart for a person authenticating to an atc-server
control plane with the atc CLI — as opposed to ../development/building-from-source.md, which
walks through shipping software to a device. It assumes an atc-server is
already running somewhere and you know its URL; if you’re standing up the
server itself, see docs/runbooks/workos-identity-setup.md (WorkOS) or
docs/runbooks/local-identity-setup.md (WorkOS-free).
Mental model
A server exposes exactly one of four auth methods, discovered automatically — you never configure the CLI to match it:
| Server mode | What atc auth login does |
|---|---|
none (anonymous, trusted-network) | Records a local profile; nothing to authenticate |
static_token | Prompts for (or reads via --token-stdin/--token-file) a shared bearer token |
local_token | Same as above, but the token is a per-user JWT an operator minted for you |
workos_device | Opens a browser approval flow (RFC 8628 device authorization) |
atc never accepts a token on the command line — only an interactive prompt,
stdin, or a file. That’s deliberate: a token on argv ends up in shell history
and ps.
First login
atc auth login --server https://atc.example.com
- If the server is
workos_device:atcprints a URL and a short code, then opens the URL in your default browser. Approve in the browser, andatcfinishes automatically once you approve — no need to press anything locally.atcdoes not open the browser over SSH, on Linux with no graphical display, or with--no-browser(orATC_NO_BROWSER=1). Then open the printed URL yourself. If the browser cannot start, the login continues and prints the reason. - If the server is a token mode:
atcprompts for the token on your terminal (input hidden, never echoed). Get the token from whoever administers the server (a shared admin token, or one minted for you personally inlocalmode). - If the server is
none: you’re done immediately — there was nothing to authenticate.
A successful login activates a profile (default name default) that
every later atc command uses automatically. Confirm it:
atc auth status
Working with more than one server
Name a profile per server so you can switch between them:
atc auth login --server https://staging.example.com --profile staging
atc auth login --server https://prod.example.com --profile prod
atc auth profiles # see everything you have stored
atc auth use staging # switch which one is active
Everything after login (push, ota status, etc.) uses whichever profile is
active — there’s no need to repeat --profile on every command.
Logging out
atc auth logout
For a WorkOS login this actually revokes the session server-side (not just a
local delete) — the CLI confirms the revocation before wiping local state. If
it can’t confirm (network blip, server hiccup), it says “logout incomplete”
rather than silently claiming success; run atc auth logout --retry to resume.
Full recovery paths (including the un-revocable case) are in
docs/runbooks/workos-identity-operations.md.
When something goes wrong
| Symptom | What’s happening | Fix |
|---|---|---|
| “profile is already bound to a different organization” | You’re re-logging in with --org different from the profile’s existing binding | atc auth remove <profile> first, then log in fresh |
| “has an unfinished logout” refusing a new login | A prior atc auth logout didn’t confirm revocation (quarantine) | atc auth logout --profile <name> --retry, or see the operations runbook |
Login works but ota/admin commands still 401 | A stale ATC_SERVER_TOKEN env var is shadowing your stored profile | atc auth status flags this — unset ATC_SERVER_TOKEN |
| Commands reach another server or org than your login | An exported ATC_SERVER_URL or ATC_SERVER_ORG comes before your login and atc.toml | unset ATC_SERVER_URL ATC_SERVER_ORG |
| No browser available (headless box) | The workos_device flow needs a human to approve somewhere | Approve from any device/browser — the printed URL isn’t tied to the machine running atc. atc skips the browser launch itself when it finds no display or an SSH session |
| Keyring backend errors | No keyring daemon on this host | atc auth login --credential-store file |
Full day-to-day operations (session revocation, incident recovery, mode
transitions) live in docs/runbooks/workos-identity-operations.md.
See also
docs/runbooks/workos-identity-setup.md— stand up a WorkOS-backed server.docs/runbooks/workos-identity-operations.md— login/logout deep dive, quarantine recovery, session revocation.docs/runbooks/workos-identity-rotation.md— key/JWKS rotation (plus the fail-closed readiness kill switch: a signed lease or the explicitATC_WORKOS_READINESS_INSECURE=1opt-out) (server operators).docs/runbooks/local-identity-setup.md— the WorkOS-freelocalmode.