Signing in
How speko-cli authenticates, what it stores, and how to revoke a terminal.
speko-cli loginPrints a short code and a URL. A human approves it in a browser — that step cannot be automated, and it is the only one that cannot.
Why a device grant
speko-cli login uses the RFC 8628 device authorization grant
rather than a loopback redirect, because the CLI often runs where no browser can
reach it: a container, an SSH session, a coding agent's sandbox. A loopback
redirect assumes localhost is the same machine as the browser. Frequently it
is not.
It never blocks an agent
When output is not a terminal — which is the case for every coding agent — or
when --no-wait is passed, login prints the URL, writes the pending grant
down, and exits 0. Run it again to finish once a human has approved.
speko-cli login --no-wait # prints the URL, returns immediately
speko-cli login # run again to completeThis matters: a command that blocks for fifteen minutes hangs an agent's whole session, and the agent will abandon the task rather than wait.
What it stores
A session token, in ~/.config/speko/credentials.json at mode 0600 (or
under XDG_CONFIG_HOME where set).
That token is as powerful as being signed in — treat the file as a secret.
A CLI session is deliberately weaker than a browser one
speko-cli whoami shows three scopes where a browser session holds six:
speko:read speko:write speko:executeAbsent are speko:credentials, speko:billing and speko:compliance. So a
terminal cannot read the organization's master MCP key or webhook signing
secret, even though the same login works in both places. The server marks the
session's origin when it is minted, and that marker is not derived from anything
the client sends.
Revoking
speko-cli auth list # every signed-in terminal, current one marked
speko-cli auth revoke <id> # end one session
speko-cli auth revoke --all # end every CLI session, including this one
speko-cli logout # local only — clears the file, session stays validlogout is local and says so. Revoking is what actually ends access.
auth list and the console's CLI devices page read the same endpoints, so the
two cannot disagree about what is signed in.