Authentication

Authentication#

claude-review supports two authentication methods for the LLM provider: API keys and Claude Code OAuth.

API Key (default)#

The simplest method. Provide an API key from your LLM provider.

toml
[auth]
method = "api_key"

[llm]
provider = "anthropic"
model = "claude-sonnet-4-6"

Set the key via environment variable:

sh
export ANTHROPIC_API_KEY="sk-ant-..."
# or for OpenAI-compatible providers:
export OPENAI_API_KEY="sk-..."
# or as a generic override for any provider:
export LLM_API_KEY="..."

The key can also be set directly in config.toml via the api_key field under [llm], but environment variables are recommended for security.

Claude Code OAuth#

Use your existing Claude Pro, Max, Team, or Enterprise subscription instead of a separate API key. This uses the same OAuth flow as Claude Code (the CLI tool), so your reviews are billed to your subscription.

Setup#

  1. Set the auth method in your config:

toml
[auth]
method = "oauth"

[llm]
provider = "anthropic"
model = "claude-sonnet-4-6"
# No api_key needed
  1. Run the login command:

sh
claude-review login

This opens your browser to Claude’s authorization page. Sign in with your Claude account. After authorizing, tokens are stored locally and the CLI prints “Login successful.”

Headless / SSH Environments#

For servers without a browser, use the manual flow:

sh
claude-review login --manual

This prints an authorization URL. Visit it on any device, sign in, and copy the authorization code. Paste it back into the terminal.

Token Management#

Tokens are stored at ~/.claude-review/credentials.json (configurable via auth.credentials_path). The file contains an access token, refresh token, and expiry timestamp.

Tokens are automatically refreshed when they approach expiry (5-minute buffer). If the API returns a 401, the client attempts a single refresh and retry before failing.

On Unix systems, the credentials file is created with 0600 permissions (owner-only read/write).

CLI Commands#

Command
Description
claude-review loginAuthenticate via browser OAuth flow
claude-review login --manualAuthenticate with manual code entry
claude-review logoutRemove stored OAuth credentials
claude-review statusShow current authentication status
claude-review serveStart the webhook server (default)

How It Works#

The OAuth flow uses the PKCE (Proof Key for Code Exchange) authorization code grant:

  1. The CLI generates a random code verifier and derives a SHA-256 code challenge.

  2. It starts a local HTTP server on a random port and opens the browser to Claude’s authorization endpoint.

  3. The user signs in and authorizes the application.

  4. Claude redirects back to the local server with an authorization code.

  5. The CLI exchanges the code (with the original verifier) for access and refresh tokens.

  6. Tokens are stored locally and used for subsequent API calls.

When calling the Anthropic API with OAuth, the client uses Authorization: Bearer <token> instead of the x-api-key header, and includes the anthropic-beta: oauth-2025-04-20 beta flag.

OAuth Scopes#

The following scopes are requested during login:

Scope
Purpose
user:profileRead your account profile
user:inferenceMake API calls using your subscription
user:sessions:claude_codeIntegrate with Claude Code sessions
user:mcp_serversAccess MCP server capabilities
user:file_uploadUpload files for analysis

Configuration Reference#

toml
[auth]
method = "oauth"                      # "api_key" or "oauth"
credentials_path = "~/.claude-review/credentials.json"  # Token storage location

Troubleshooting#

“not logged in” error on serve: Run claude-review login before starting the server.

Token refresh fails: Run claude-review login again to re-authenticate. This replaces the stored tokens.

Browser doesn’t open: Use claude-review login --manual and visit the printed URL manually.

Wrong subscription: If you have multiple Claude accounts, make sure you sign in with the account that has an active subscription. Run claude-review logout first to clear any cached tokens, then claude-review login.