Skip to main content

Login, Logout, Whoami

Three commands defined in cmd/crewship/cmd_login.go cover every way the CLI authenticates against a Crewship server. The token lands in ~/.crewship/cli-config.yaml (or the selected profile); subsequent commands pick it up from there. Login and the other top-level commands respect the global --server and --profile flags. --workspace is a global context flag for workspace-scoped commands; login does not select a workspace.

crewship login

Four mutually exclusive modes — pick one. Interactive is the default when no mode flag is set.

Interactive

The interactive flow uses NextAuth’s credentials provider under the hood (CSRF → /api/auth/callback/credentials → session cookie → POST /api/v1/auth/cli-token to mint a permanent CLI token; falls back to the session token if the CLI-token endpoint isn’t available on an older server).

Token

Useful for CI: provision the token once in the web UI under Settings → CLI tokens, drop it into your CI secret store, point env at it.

Google OAuth

The flow is intentionally hybrid: Google’s redirect-URI flow lands the session cookie on the browser, not on the CLI, so the CLI doesn’t try to fake a loopback redirect that would need a new server endpoint. You sign in in the browser, mint a CLI token from settings, paste it back into the terminal — the CLI validates and stores it.

Device-code pairing

Pairing is what the First-run wizard → Pair CLI card hands out. The browser polls the server every few seconds; once the code is redeemed, the wizard’s “Launch Crew” button unlocks.

Non-interactive (systemd / CI / test harnesses)

The default email+password flow prompts for the password via term.ReadPassword, which requires a real TTY and fails outright over a pipe:
--email plus one of two password sources removes the TTY dependency entirely — useful for a systemd timer re-authenticating after a dev-slot reseed, a CI job, or a headless test harness:
Prefer --password-stdin when both work (preferred for CI / scripts — avoids argv leak): an environment variable is readable from /proc/<pid>/environ by anything running as the same user and is inherited by every child process, so on shared machines CREWSHIP_PASSWORD exposes the password more broadly than a stdin pipe does. Reserve the env var for runners that can only inject secrets through the environment. Both go through the same CSRF+credentials exchange and CLI-token mint as interactive login, so the persisted token behaves identically. Passing both --password-stdin and CREWSHIP_PASSWORD is refused (mutually exclusive) rather than silently picking one.

Targeting a profile

Pass --profile <name> (or set CREWSHIP_PROFILE) to authenticate a named server profile instead of the top-level config. The minted token is stored inside that profile. If no default profile is set yet, that profile also becomes current (logging into another profile later does not re-point an existing default):
With no --profile/CREWSHIP_PROFILE, login writes the legacy top-level server/token fields exactly as before. logout is profile-aware too: it clears the active profile’s token and leaves sibling profiles signed in.

Common errors

  • pair: the pair code didn't work — codes expire after 10 minutes — codes have a 10-min TTL. The server intentionally folds wrong code / expired / already consumed into one message to avoid being an enumeration oracle; the most likely cause is the TTL.
  • Google sign-in is not configured on <server> — the server returned enabled=false from /api/v1/auth/google/status. The operator hasn’t set GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET.
  • refusing to overwrite a malformed file — fix or remove ~/.crewship/cli-config.yaml and retry — the config file exists but isn’t valid YAML. Surfaced explicitly so the CLI doesn’t silently wipe your saved server/workspace.
  • --password-stdin and CREWSHIP_PASSWORD are mutually exclusive — both non-interactive password sources were set; drop one.
  • --password-stdin: no password on stdin--password-stdin was passed but stdin had no content (or only whitespace).

crewship logout

Clears the token field in ~/.crewship/cli-config.yaml. Leaves server and workspace alone so the next crewship login re-uses the same profile without retyping the URL. The token is not revoked on the server — to do that, delete it from Settings → CLI tokens in the web UI (DELETE /api/v1/auth/cli-tokens/{tokenId}).

crewship whoami

Hits GET /api/v1/workspaces plus GET /api/v1/auth/cli-token/validate to print the email, server URL, currently selected workspace (if any), and your role in it. The Server: line shows the effective server the command actually dialed — it honours the active profile (--profile / CREWSHIP_PROFILE) with the usual precedence (--server → profile → CREWSHIP_SERVER env → config), so it is the authoritative answer to “which instance am I talking to?”. Useful as a CI smoke check (crewship whoami || exit 1) before running a real mutation.
When no workspace is selected, prints how many are available and how to pick one:

See also