Skip to main content

Login

Two flows, pick whichever fits:

  • Browser flow (default) — opens your default browser, you approve once, CLI gets a 90-day API key
  • Device flow (--device) — no local browser needed; works on SSH, tmux, CI runners

Both end the same way: a sk-... API key stored at ~/.cybrium/config.yml with scopes scan:upload, findings:write, findings:read.

Browser flow

cybrium login

What happens:

  1. The CLI generates a PKCE verifier + S256 challenge.
  2. Binds a local listener on 127.0.0.1:<random-port>/callback.
  3. Opens your default browser to https://app.cybrium.ai/cli-approve with state + challenge in the query string.
  4. You confirm the scopes in the browser. If you're not signed in yet, you'll bounce through the normal login first.
  5. The SPA POSTs an approval to the server, gets a one-time auth code, and 302-redirects to 127.0.0.1:<port>/callback?code=...&state=....
  6. The CLI's listener receives the code, exchanges it for an API key using PKCE, and writes it to ~/.cybrium/config.yml.
  7. Browser shows a ✓ "Cybrium CLI signed in" page — you can close the tab.
$ cybrium login
Opening browser to authorize the CLI…
If the page doesn't open, visit:
https://app.cybrium.ai/cli-approve?code_challenge=...

✓ Logged in. API key stored at /Users/me/.cybrium/config.yml
scopes: scan:upload findings:write findings:read
tenant: 1
expires: 2026-07-13

Device flow

cybrium login --device

What happens:

  1. The CLI POSTs to /api/auth/cli/device/code/ and gets back a user_code (looks like WDJB-MJHT) and a device_code.
  2. CLI prints the code and opens the verification URL.
  3. You go to https://app.cybrium.ai/activate on any device, enter the user_code (or use the pre-filled URL), and approve.
  4. Meanwhile, the CLI polls /api/auth/cli/token/ every 5 seconds. Once you approve, the next poll returns the API key and stores it.
$ cybrium login --device

1. Visit: https://app.cybrium.ai/activate
2. Enter: WDJB-MJHT

(or open the pre-filled URL: https://app.cybrium.ai/activate?code=WDJB-MJHT)

......
✓ Logged in. API key stored at /Users/me/.cybrium/config.yml

Local / dev stacks

For developing against a local backend:

CYBRIUM_API=http://localhost:8000/api \
CYBRIUM_WEB=http://localhost:3001 \
cybrium login
  • CYBRIUM_API — API base URL (default https://app.cybrium.ai/api)
  • CYBRIUM_WEB — Console URL for OAuth consent (default: derived from API host)

In production the two share a host and CYBRIUM_WEB isn't needed.

After login

cybrium whoami
Email: you@example.com
Name: Your Name
Tenant: Acme Corp
Role: admin

The stored token is a tenant-scoped API key — it can ingest scans + read/write findings for that tenant only.

Logout

cybrium logout

Clears the token from your config file. The key itself isn't server-side revoked — delete it explicitly from Settings → API Keys in the platform UI if you want it dead everywhere.

Troubleshooting

timed out waiting for browser approval

The loopback server waits 5 minutes. Most common cause: corporate proxy or browser popup blocker.

Workaround: use --device instead.

PKCE verifier mismatch

You probably restarted the CLI mid-flow. Re-run cybrium login.

Device approved but CLI never finishes

Verify the CLI is still running and reachable to the internet. The device-code poll hits /api/auth/cli/token/ every 5 seconds; network issues show as timeouts here.

Wrong tenant after login

organization_id is auto-bound from the browser session tenant. To target a different one, switch tenants in the web UI before clicking Approve — or use --web to point at a specific tenant subdomain.

Next step