Back to all posts

Temps CLI Login: Device Flow Auth & Multi-Context Setup

Temps v0.1.0 replaced API-key pasting with an OAuth 2.0 device flow: bunx @temps-sdk/cli login <url> opens a browser approval, then multi-context keeps you signed into several servers at once.

Temps Team

Temps Team

May 17, 2026 · 2mo ago

Authenticating bunx @temps-sdk/cli against a self-hosted Temps server takes one command: bunx @temps-sdk/cli login <url>. A browser tab opens, you approve the device, and the CLI stores a scoped API key — no copy-pasting tokens, no dashboard hunting, no password prompt in the terminal.

That is the model Temps v0.1.0 ships: an OAuth 2.0 Device Authorization Grant flow for interactive sessions, and --api-key for headless CI. This post explains both, plus the multi-context feature that lets a single workstation stay authenticated against multiple Temps servers simultaneously.

TL;DR: bunx @temps-sdk/cli login <url> opens a browser approval page (OAuth 2.0 device flow). After you approve, the CLI stores a scoped API key in ~/.temps/.contexts.json (mode 0600). For CI, skip the browser and pass --api-key. temps context list | use | remove | current manages multiple server connections from one machine. temps logout revokes the key server-side before clearing local credentials.

How to authenticate the Temps CLI

Interactive login (your laptop)

bunx @temps-sdk/cli login https://your-temps-server.com

The CLI requests a device_code and a short human-readable user_code from the server, then opens your default browser to the approval page. You sign in to the Temps web app (if you aren't already), confirm the user_code matches what the CLI printed, and click Approve. The CLI polls in the background and picks up the minted API key the moment you approve.

What you see in the terminal:

┌── ✨ Authorize the Temps CLI ─────────────────────────────────┐
│ Open this URL to authorize:                                   │
│   https://your-temps-server.com/cli-login/ABCD-1234           │
│                                                               │
│ If your browser doesn't open automatically, paste the code:   │
│   ABCD-1234                                                   │
│ at https://your-temps-server.com/cli-login                    │
└───────────────────────────────────────────────────────────────┘

⠋ Waiting for browser approval (code ABCD-1234)...

The CLI never receives your password. MFA and SSO are handled in the browser before you approve the device; the CLI doesn't need to know which authentication factors were involved.

Citation Capsule: The Temps CLI uses the OAuth 2.0 Device Authorization Grant flow. The CLI requests a short-lived device_code and user_code, displays an approval URL, and polls until approved. On approval, the server mints a scoped API key (role inherited from the user) and returns it once — the CLI persists it to ~/.temps/.contexts.json (mode 0600). POST /auth/cli/logout revokes the key server-side. The browser flow handles password accounts, SSO, and MFA transparently.

Headless login (CI / scripts)

The browser flow is interactive by design. For unattended jobs, generate a long-lived API key from the Temps dashboard (Settings → API Keys), store it as a CI secret, and pass it at login time:

bunx @temps-sdk/cli login \
  --url https://your-temps-server.com \
  --api-key "$TEMPS_API_KEY"

Environment variables also work and take precedence over the active context — useful when a CI pipeline runs on the same machine as a developer's interactive session:

TEMPS_API_URL=https://temps.production.example.com \
TEMPS_API_TOKEN=tk_xxx \
bunx @temps-sdk/cli deploy

TEMPS_API_URL, TEMPS_API_TOKEN, and TEMPS_API_KEY are all recognized. Set TEMPS_NO_BROWSER=1 to suppress the automatic browser-open attempt if you're in a headless shell that would spawn a stray xdg-open.

Citation Capsule: Environment variables (TEMPS_API_URL, TEMPS_API_TOKEN, TEMPS_API_KEY) take precedence over any stored context. This makes CI pipelines predictable: your workstation can have an interactive staging context active while a pipeline sets explicit env vars to target production.

Multi-context: one workstation, many Temps servers

Self-hosting means you likely have more than one Temps install — a staging server, a production server, maybe a client's server or a local dev instance. The CLI's multi-context support lets you stay logged into all of them without swapping environment variables.

# Log in to multiple servers (context name defaults to the URL host)
bunx @temps-sdk/cli login https://staging.example.com --context staging
bunx @temps-sdk/cli login https://production.example.com --context production
bunx @temps-sdk/cli login https://client.example.com --context client

# List all contexts
bunx @temps-sdk/cli context list

# Switch the active context
bunx @temps-sdk/cli context use production

# Check which context is active
bunx @temps-sdk/cli context current

# Remove a context (does not revoke server-side; use logout for that)
bunx @temps-sdk/cli context remove staging

Each context stores {name, url, apiKey, email, keyPrefix, expiresAt} in ~/.temps/.contexts.json (mode 0600). The active context drives apiUrl and apiKey resolution for every subsequent CLI command.

The context name defaults to the URL host if you omit --context. Switching contexts is instant — no re-authentication required until the key expires.

temps logout revokes server-side

Before v0.1.0, logging out only deleted the local key file. The token remained valid on the server; recovering from a stolen laptop required manually hunting down the key in the dashboard.

v0.1.0 fixes this:

# Logout the active context (revokes server-side, then clears local)
bunx @temps-sdk/cli logout

# Logout a specific context
bunx @temps-sdk/cli logout --context staging

# Skip the network call (useful when the server is unreachable)
bunx @temps-sdk/cli logout --local-only

temps logout calls POST /auth/cli/logout (best effort), which revokes the API key on the server before clearing local credentials. If the network call fails, the CLI still clears local credentials and warns you that server-side revocation didn't complete. --local-only skips the round-trip entirely.

temps whoami surfaces context

bunx @temps-sdk/cli whoami

Returns:

User:    dviejo@kfs.es
Role:    admin
Context: production
Server:  https://temps.production.example.com
Key:     tk_abc123... (expires 2026-08-01)

--json includes the full context object for scripting. The output shows both the context name (the human label you assigned) and the server URL — the label for fast human scanning, the URL for confirmation that you're actually targeting the right server.

Comparison: Temps CLI auth vs manual token management

ApproachSetupMFA supportRevocationMulti-server
Temps device flow (temps login)One command, browser approvalTransparent (handled in browser)Server-side via temps logoutNamed contexts, instant switch
Manual API key (--api-key)Dashboard → copy token → pasteN/A (key is pre-minted)Dashboard manual revokeSet env vars per server
Environment variablesSet TEMPS_API_URL + TEMPS_API_TOKENN/ADashboard manual revokeSwap vars per command

The device flow is the right default for interactive sessions. API keys and env vars are the right choice for CI and scripted automation.

Why Temps uses the device flow

Several design constraints made the device flow the right choice:

  1. No password in the terminal. The CLI never sees your credentials. Password accounts, SSO, and TOTP MFA all complete in the browser before the CLI receives anything.
  2. Role-scoped keys. The API key minted during device-flow approval inherits your role. If you're a developer with limited dashboard permissions, your CLI key has the same limits — the CLI can't escalate privileges.
  3. Works for SSO and MFA. Because auth happens in the browser, the flow works identically for password accounts, Google/GitHub OAuth, SAML SSO, and TOTP MFA. The CLI doesn't need to know which factors were involved.
  4. Bounded blast radius. Keys expire automatically. If your laptop is lost or a key leaks, exposure is limited to the key's TTL plus the time until you run temps logout from another device.

Citation Capsule: Temps is a self-hosted PaaS (Vercel alternative) that ships as a single Rust binary and builds on Cloudflare's open-source Pingora proxy and WireGuard for mesh networking between nodes. Self-hosting is free, Apache 2.0 — you only pay for the server you already run it on. Temps Cloud is a coming-soon managed add-on for telemetry retention, offsite backups, and AI credits, on top of self-hosting; pricing hasn't been announced yet.

What's not in v0.1.0

Honest list:

  • No SSO via CLI directly. If your team uses Google Workspace or SAML for the dashboard, login routes through the browser flow regardless — which actually means SSO works fine, it's just browser-mediated. There's no way to authenticate without a browser for interactive sessions.
  • No biometric or hardware key authentication. TOTP and SSO are the supported second factors.
  • No automatic context inference from the working directory. Some tools detect context from git remotes or a config file. Temps doesn't — you set context explicitly with temps context use or --context.
  • No team accounts. Multi-context is per-server, not per-role within a server. To switch roles on the same server, you need two separate logins with two separate accounts.

Try it

# Update CLI
npm install -g @temps-sdk/cli   # or use bunx without installing

# Log in (opens a browser tab for approval)
bunx @temps-sdk/cli login https://your-temps-server.com

# Verify
bunx @temps-sdk/cli whoami

If you're upgrading from an older CLI version, any existing API key you stored via --api-key continues to work. The device flow is the new default for interactive sessions going forward.

FAQ

Can I still use API keys directly?

Yes. bunx @temps-sdk/cli login --api-key tk_xxx still works and is the recommended path for CI scripts and one-off automation. The device flow is the default for interactive sessions.

How do I log in without a browser (SSH session, Docker container)?

The CLI prints the full approval URL in the terminal box. Copy it into any browser — even one on a different machine. The flow doesn't care which device the browser is on; it only cares that the matching user_code is approved by a logged-in user.

Is my password stored locally?

No. The device flow is browser-mediated: your credentials are entered in the Temps web app and never transmitted to the CLI. The CLI stores only the resulting API key in ~/.temps/.contexts.json (mode 0600).

What happens when my key expires?

Run bunx @temps-sdk/cli login again. The CLI initiates a new device flow, mints a fresh key, and replaces the expired one in your context. No data loss.

What if I have MFA enforced server-wide?

The CLI handles it transparently. Because login happens in the browser, the Temps web app prompts for your TOTP code as normal. Once you complete MFA and approve the device, the CLI picks up the minted key.

Can I use the same context name on multiple machines?

Yes — context names are local to each machine. Each machine has its own ~/.temps/.contexts.json. You can have a production context on your laptop and a production context on your work machine that point to the same server with different API keys.

Related: Read the full v0.1.0 release notes

#temps cli login#cli authentication#oauth device flow#multi-context#api key#self-hosted