Skip to content

Claude Auth

Sia edited this page May 31, 2026 · 2 revisions

Claude Authentication

vibe-coder needs to authenticate Claude Code before sending any prompt. Four mutually-exclusive options, all selectable from the Build environment → Claude login card.

Decision matrix

Option Best when… Needs other machine? OAuth subscription API billing
0. Web OAuth (★) You want zero terminal touch No ✅ Pro/Max
1. Terminal claude login You already have shell access No ✅ Pro/Max
2. File upload You can't reach the container terminal Yes (one-time) ✅ Pro/Max
3. API key You're billed via Anthropic API console No

Option 0 — Semi-automatic web OAuth

The most polished UX. Click Login via web, follow a single browser tab, paste one code back. No terminal, no other machine.

Implementation: server spawns script -q -c "claude auth login" /dev/null, captures the OAuth URL from stdout via regex, exposes it in the UI for the operator to open in a new tab. After Anthropic redirects with an authorization code, the operator pastes it into the form; the server writes it to the child's stdin. CLI completes token exchange and writes ~/.claude/.credentials.json. The server detects the credentials file + exit 0 = success.

No terminal emulator (xterm.js) is exposed; only a single one-line form. Complies with CLAUDE.md §3 "no raw-shell UI" policy.

API: POST /api/env-setup/claude-login/start | submit | cancel, GET /api/env-setup/claude-login/status. State machine:

IDLE → STARTING → AWAITING_CODE → VERIFYING → DONE
                                      ↓
                                   FAILED / CANCELED

Option 1 — Terminal

docker exec -it --user vibe vibe-coder-server claude login

⚠️ Note the --user vibe flag. Without it, docker exec defaults to root, so the credentials land in /root/.claude/.credentials.json, which the server (running as vibe) cannot read.

Option 2 — File upload

Useful when you operate the server remotely and have no docker exec access (Synology NAS UI, etc.).

  1. On a machine where you can run claude login (your laptop), complete the OAuth flow as usual.
  2. Locate ~/.claude/.credentials.json (or %USERPROFILE%\.claude\… on Windows).
  3. Upload it through the web form. Server validates JSON shape + claudeAiOauth.expiresAt (rejects if already expired), backs up any existing file, atomic-writes the new one (0600 permissions).

API: POST /api/env-setup/claude-auth/upload (multipart, single file).

Option 3 — ANTHROPIC_API_KEY

For users billed via the Anthropic API console (sk-ant-…) rather than a Pro/Max subscription.

  1. Settings → Build environment → Claude login → expand Option 3.
  2. Paste the API key (sk-ant-…) into the field.
  3. Server stores it in /home/vibe/.claude/.env.api-key (0600). All claude child processes spawn with ANTHROPIC_API_KEY injected from that file (via ClaudeProcessEnv.applyApiKey).

The OAuth credentials file (if any) is still kept around; the API key takes priority in diagnostics. Delete the API key to revert to OAuth.

API:

  • POST /api/env-setup/claude-auth/api-key {"apiKey":"sk-ant-…"}
  • DELETE /api/env-setup/claude-auth/api-key/delete (or POST)

Storage layout

/home/vibe/.claude/
├── .credentials.json     # OAuth credentials (options 0, 1, 2)
├── .env.api-key          # ANTHROPIC_API_KEY=... (option 3, 0600)
├── .mcp.json             # MCP server registrations (filled by MCP catalog)
└── (other Claude config, conversation history, etc.)

All under the bind mount → ./vibe-coder-data/claude/ → persists across image upgrades.

Refresh tokens

OAuth refresh tokens last 30 days. Once you've successfully logged in (any option except API key), the CLI auto-refreshes the access token silently. You don't need to re-authenticate unless:

  • Refresh token expires (≥30 days unused).
  • You explicitly claude logout.
  • The .credentials.json file is corrupted or deleted.

Clone this wiki locally