Skip to content

Authentication

The CLI authenticates via either an API key (bdk_…) or a JWT (access + refresh). API keys are the right primitive almost everywhere - long-lived, scope-bounded, no refresh-token gymnastics. JWTs only matter inside an interactive session (the one place platform_role is implicit and admin verbs work without an admin scope).

API key (bdk_…) JWT
Lifetime months/years (until revoked) 15-min access + 7-day refresh
Carries platform_role? No - needs explicit admin scope Yes - implicit for @bcdock.io users
Scopes explicit grants per key implicit ("everything you can do")
Storage ~/.config/bcdock/credentials.json (mode 0600) typically not stored - auth login exchanges OTP for an API key directly
Right for agents, CI/CD, scripts, daily CLI use interactive admin work, portal sessions

Three ways to set a credential

Need Use Notes
Persist creds for interactive dev (across shell sessions, across reboots) bcdock auth login Preferred - runs OTP exchange and stores the resulting API key. Requires a TTY.
Persist creds when auth login can't run (admin-scoped keys minted via curl, non-TTY dev environments, restored creds after a ~/.config wipe) bcdock auth set-token <bdk_…> Same on-disk result as auth login, but no OTP step.
Ephemeral creds for one process (CI, sandboxed agent, scripted run, per-call override) BCDOCK_TOKEN env var No disk write - dies with the process. Always wins over stored credentials.

Rule of thumb: never persist secrets to disk in CI - use BCDOCK_TOKEN. On a developer laptop where you'll run bcdock dozens of times a day, persisted credentials via auth login are the right ergonomics.

Interactive login (humans)

bcdock auth login
# Prompts for email → sends OTP → prompts for code → mints an API key
# Stored in ~/.config/bcdock/credentials.json as a bdk_* key (no refresh token)

auth login calls POST /api/v1/auth/email/exchange and stores the resulting API key. The minted key receives the standard scopes (env:read, env:write) automatically. Admin scope is not included by this path - see admin scope below.

Set token (no-OTP persistence)

bcdock auth set-token bdk_abc123...

Use when you have a key already and want to persist it without going through OTP - typically:

  • Admin-scoped keys, which today must be minted via curl POST /api/v1/api-keys against a JWT.
  • Switching the active credentials between accounts on a shared dev machine.
  • Restoring after a ~/.config wipe when you still have the key on hand.

If you find yourself reaching for set-token in CI, stop - use BCDOCK_TOKEN instead. The on-disk credential leaks past the process boundary and complicates secret rotation.

Ephemeral token (CI, sandboxed agents)

export BCDOCK_TOKEN="bdk_abc123..."
bcdock --api-url https://api.bcdock.io me show

BCDOCK_TOKEN overrides any stored credentials and never writes to disk. This is the right shape for:

  • CI/CD runners (token from secrets, exported per job).
  • Cloud-hosted agents (Claude, Copilot Workspace, etc.) without a shared home directory.
  • One-off "use this other key for one command" overrides during testing.

Scopes

API keys are scope-bounded. Select scopes at creation time in the portal /profile/api-keys, or via the OTP exchange path (which always grants the standard three).

Scope Allows
env:read list and inspect environments, view logs
env:write create, delete, hibernate, resume, deploy extensions

JWTs (typically obtained when navigating the portal, or via companies switch which mints a short-lived JWT for the new company context) bypass scope checks - they implicitly carry whatever the user can do. JWTs expire in 15 minutes; this is a feature, not a bug, for interactive use.

Platform admin operations (cross-tenant environment ops, image catalog management, pool lifecycle, billing inspection, waitlist + invite-code minting) are handled by BCDock staff via internal tooling. They are not reachable from the public bcdock CLI and there is no customer-facing scope for them.

Verify

bcdock auth whoami       # core identity (email, role, company)
bcdock me show           # adds status + deletionScheduledAt

whoami is the fast "am I logged in as the right person" check. me show is the same query routed through the LAW-004 surface; preferred when you also want to see deletion status (during 30-day grace) or programmatic JSON output.

Logout

bcdock auth logout
# Best-effort revokes server-side, then clears ~/.config/bcdock/credentials.json

logout clears the on-disk credentials regardless of network success. To revoke a key without clearing local state (e.g., revoking a leaked key from a different machine), use the portal /profile/api-keys page.