refactor: remove CLAUDE_CODE_OAUTH_TOKEN references and update authentication to use ANTHROPIC_API_KEY exclusively

This commit is contained in:
Cody Seibert
2025-12-15 14:33:58 -05:00
parent 54b977ee1b
commit d42857ec26
13 changed files with 21 additions and 88 deletions

View File

@@ -150,21 +150,17 @@ npm run lint
Automaker supports multiple authentication methods (in order of priority): Automaker supports multiple authentication methods (in order of priority):
| Method | Environment Variable | Description | | Method | Environment Variable | Description |
| -------------------- | ------------------------- | --------------------------------------------------------- | | ---------------- | -------------------- | ------------------------------- |
| OAuth Token (env) | `CLAUDE_CODE_OAUTH_TOKEN` | From `claude setup-token` - uses your Claude subscription | | API Key (env) | `ANTHROPIC_API_KEY` | Anthropic API key |
| OAuth Token (stored) | — | Stored in app credentials file | | API Key (stored) | — | Anthropic API key stored in app |
| API Key (stored) | — | Anthropic API key stored in app |
| API Key (env) | `ANTHROPIC_API_KEY` | Pay-per-use API key |
**Recommended:** Use `CLAUDE_CODE_OAUTH_TOKEN` if you have a Claude subscription.
### Persistent Setup (Optional) ### Persistent Setup (Optional)
Add to your `~/.bashrc` or `~/.zshrc`: Add to your `~/.bashrc` or `~/.zshrc`:
```bash ```bash
export CLAUDE_CODE_OAUTH_TOKEN="YOUR_TOKEN_HERE" export ANTHROPIC_API_KEY="YOUR_API_KEY_HERE"
``` ```
Then restart your terminal or run `source ~/.bashrc`. Then restart your terminal or run `source ~/.bashrc`.

View File

@@ -33,25 +33,15 @@ cd automaker
npm install npm install
``` ```
**Step 3:** Get your Claude subscription token: **Step 3:** Set your Anthropic API key (optional - you can also enter it in the app's setup wizard):
```bash ```bash
claude setup-token export ANTHROPIC_API_KEY="sk-ant-..."
``` ```
This command will authenticate you via your browser and print a token to your terminal. Alternatively, you can enter your API key directly in the Automaker setup wizard when you launch the app.
> **⚠️ Warning:** This command will print your token to your terminal. Be careful if you're streaming or sharing your screen, as the token will be visible to anyone watching. **Step 4:** Start the development server:
**Step 4:** Export the Claude Code OAuth token in your shell (optional - you can also enter it in the app's setup wizard):
```bash
export CLAUDE_CODE_OAUTH_TOKEN="your-token-here"
```
Alternatively, you can enter your token directly in the Automaker setup wizard when you launch the app.
**Step 5:** Start the development server:
```bash ```bash
npm run dev:electron npm run dev:electron

View File

@@ -2,9 +2,6 @@ import type { NextConfig } from "next";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
output: "export", output: "export",
env: {
CLAUDE_CODE_OAUTH_TOKEN: process.env.CLAUDE_CODE_OAUTH_TOKEN || "",
},
}; };
export default nextConfig; export default nextConfig;

View File

@@ -11,7 +11,7 @@ export async function POST(request: NextRequest) {
const { apiKey } = await request.json(); const { apiKey } = await request.json();
// Use provided API key or fall back to environment variable // Use provided API key or fall back to environment variable
const effectiveApiKey = apiKey || process.env.ANTHROPIC_API_KEY || process.env.CLAUDE_CODE_OAUTH_TOKEN; const effectiveApiKey = apiKey || process.env.ANTHROPIC_API_KEY;
if (!effectiveApiKey) { if (!effectiveApiKey) {
return NextResponse.json( return NextResponse.json(

View File

@@ -55,9 +55,7 @@ export function AuthenticationStatusDisplay({
<div className="flex items-center gap-2 text-muted-foreground"> <div className="flex items-center gap-2 text-muted-foreground">
<Info className="w-3 h-3 shrink-0" /> <Info className="w-3 h-3 shrink-0" />
<span> <span>
{claudeAuthStatus.method === "oauth_token_env" {claudeAuthStatus.method === "oauth_token"
? "Using CLAUDE_CODE_OAUTH_TOKEN"
: claudeAuthStatus.method === "oauth_token"
? "Using stored OAuth token (subscription)" ? "Using stored OAuth token (subscription)"
: claudeAuthStatus.method === "api_key_env" : claudeAuthStatus.method === "api_key_env"
? "Using ANTHROPIC_API_KEY" ? "Using ANTHROPIC_API_KEY"

View File

@@ -50,30 +50,21 @@ const DATA_DIR = process.env.DATA_DIR || "./data";
const ENABLE_REQUEST_LOGGING = process.env.ENABLE_REQUEST_LOGGING !== "false"; // Default to true const ENABLE_REQUEST_LOGGING = process.env.ENABLE_REQUEST_LOGGING !== "false"; // Default to true
// Check for required environment variables // Check for required environment variables
// Claude Agent SDK supports EITHER OAuth token (subscription) OR API key (pay-per-use)
const hasAnthropicKey = !!process.env.ANTHROPIC_API_KEY; const hasAnthropicKey = !!process.env.ANTHROPIC_API_KEY;
const hasOAuthToken = !!process.env.CLAUDE_CODE_OAUTH_TOKEN;
if (!hasAnthropicKey && !hasOAuthToken) { if (!hasAnthropicKey) {
console.warn(` console.warn(`
╔═══════════════════════════════════════════════════════════════════════╗ ╔═══════════════════════════════════════════════════════════════════════╗
║ ⚠️ WARNING: No Claude authentication configured ║ ║ ⚠️ WARNING: No Claude authentication configured ║
║ ║ ║ ║
║ The Claude Agent SDK requires authentication to function. ║ ║ The Claude Agent SDK requires authentication to function. ║
║ ║ ║ ║
Option 1 - Subscription (OAuth Token): Set your Anthropic API key:
║ export CLAUDE_CODE_OAUTH_TOKEN="your-oauth-token" ║
║ ║
║ Option 2 - Pay-per-use (API Key): ║
║ export ANTHROPIC_API_KEY="sk-ant-..." ║ ║ export ANTHROPIC_API_KEY="sk-ant-..." ║
║ ║ ║ ║
║ Or use the setup wizard in Settings to configure authentication. ║ ║ Or use the setup wizard in Settings to configure authentication. ║
╚═══════════════════════════════════════════════════════════════════════╝ ╚═══════════════════════════════════════════════════════════════════════╝
`); `);
} else if (hasOAuthToken) {
console.log(
"[Server] ✓ CLAUDE_CODE_OAUTH_TOKEN detected (subscription auth)"
);
} else { } else {
console.log("[Server] ✓ ANTHROPIC_API_KEY detected (API key auth)"); console.log("[Server] ✓ ANTHROPIC_API_KEY detected (API key auth)");
} }

View File

@@ -112,9 +112,7 @@ export class ClaudeProvider extends BaseProvider {
*/ */
async detectInstallation(): Promise<InstallationStatus> { async detectInstallation(): Promise<InstallationStatus> {
// Claude SDK is always available since it's a dependency // Claude SDK is always available since it's a dependency
const hasAnthropicKey = !!process.env.ANTHROPIC_API_KEY; const hasApiKey = !!process.env.ANTHROPIC_API_KEY;
const hasOAuthToken = !!process.env.CLAUDE_CODE_OAUTH_TOKEN;
const hasApiKey = hasAnthropicKey || hasOAuthToken;
const status: InstallationStatus = { const status: InstallationStatus = {
installed: true, installed: true,

View File

@@ -35,19 +35,9 @@ export function setRunningState(
* Helper to log authentication status * Helper to log authentication status
*/ */
export function logAuthStatus(context: string): void { export function logAuthStatus(context: string): void {
const hasOAuthToken = !!process.env.CLAUDE_CODE_OAUTH_TOKEN;
const hasApiKey = !!process.env.ANTHROPIC_API_KEY; const hasApiKey = !!process.env.ANTHROPIC_API_KEY;
logger.info(`${context} - Auth Status:`); logger.info(`${context} - Auth Status:`);
logger.info(
` CLAUDE_CODE_OAUTH_TOKEN: ${
hasOAuthToken
? "SET (" +
process.env.CLAUDE_CODE_OAUTH_TOKEN?.substring(0, 20) +
"...)"
: "NOT SET"
}`
);
logger.info( logger.info(
` ANTHROPIC_API_KEY: ${ ` ANTHROPIC_API_KEY: ${
hasApiKey hasApiKey
@@ -56,7 +46,7 @@ export function logAuthStatus(context: string): void {
}` }`
); );
if (!hasOAuthToken && !hasApiKey) { if (!hasApiKey) {
logger.warn("⚠️ WARNING: No authentication configured! SDK will fail."); logger.warn("⚠️ WARNING: No authentication configured! SDK will fail.");
} }
} }

View File

@@ -15,9 +15,7 @@ export function createProvidersHandler() {
const providers: Record<string, any> = { const providers: Record<string, any> = {
anthropic: { anthropic: {
available: statuses.claude?.installed || false, available: statuses.claude?.installed || false,
hasApiKey: hasApiKey: !!process.env.ANTHROPIC_API_KEY,
!!process.env.ANTHROPIC_API_KEY ||
!!process.env.CLAUDE_CODE_OAUTH_TOKEN,
}, },
google: { google: {
available: !!process.env.GOOGLE_API_KEY, available: !!process.env.GOOGLE_API_KEY,

View File

@@ -74,7 +74,6 @@ export async function getClaudeStatus() {
hasStoredOAuthToken: !!getApiKey("anthropic_oauth_token"), hasStoredOAuthToken: !!getApiKey("anthropic_oauth_token"),
hasStoredApiKey: !!getApiKey("anthropic"), hasStoredApiKey: !!getApiKey("anthropic"),
hasEnvApiKey: !!process.env.ANTHROPIC_API_KEY, hasEnvApiKey: !!process.env.ANTHROPIC_API_KEY,
hasEnvOAuthToken: !!process.env.CLAUDE_CODE_OAUTH_TOKEN,
// Additional fields for detailed status // Additional fields for detailed status
oauthTokenValid: false, oauthTokenValid: false,
apiKeyValid: false, apiKeyValid: false,
@@ -148,11 +147,7 @@ export async function getClaudeStatus() {
} }
// Environment variables override stored credentials (higher priority) // Environment variables override stored credentials (higher priority)
if (auth.hasEnvOAuthToken) { if (auth.hasEnvApiKey) {
auth.authenticated = true;
auth.oauthTokenValid = true;
auth.method = "oauth_token_env";
} else if (auth.hasEnvApiKey) {
auth.authenticated = true; auth.authenticated = true;
auth.apiKeyValid = true; auth.apiKeyValid = true;
auth.method = "api_key_env"; // API key from ANTHROPIC_API_KEY env var auth.method = "api_key_env"; // API key from ANTHROPIC_API_KEY env var

View File

@@ -31,16 +31,8 @@ export function createStoreApiKeyHandler() {
setApiKey(provider, apiKey); setApiKey(provider, apiKey);
// Also set as environment variable and persist to .env // Also set as environment variable and persist to .env
// IMPORTANT: OAuth tokens and API keys must be stored separately if (provider === "anthropic" || provider === "anthropic_oauth_token") {
// - OAuth tokens (subscription auth) -> CLAUDE_CODE_OAUTH_TOKEN // Both API key and OAuth token use ANTHROPIC_API_KEY
// - API keys (pay-per-use) -> ANTHROPIC_API_KEY
if (provider === "anthropic_oauth_token") {
// OAuth token from claude setup-token (subscription-based auth)
process.env.CLAUDE_CODE_OAUTH_TOKEN = apiKey;
await persistApiKeyToEnv("CLAUDE_CODE_OAUTH_TOKEN", apiKey);
logger.info("[Setup] Stored OAuth token as CLAUDE_CODE_OAUTH_TOKEN");
} else if (provider === "anthropic") {
// Direct API key (pay-per-use)
process.env.ANTHROPIC_API_KEY = apiKey; process.env.ANTHROPIC_API_KEY = apiKey;
await persistApiKeyToEnv("ANTHROPIC_API_KEY", apiKey); await persistApiKeyToEnv("ANTHROPIC_API_KEY", apiKey);
logger.info("[Setup] Stored API key as ANTHROPIC_API_KEY"); logger.info("[Setup] Stored API key as ANTHROPIC_API_KEY");

View File

@@ -12,7 +12,6 @@ describe("claude-provider.ts", () => {
vi.clearAllMocks(); vi.clearAllMocks();
provider = new ClaudeProvider(); provider = new ClaudeProvider();
delete process.env.ANTHROPIC_API_KEY; delete process.env.ANTHROPIC_API_KEY;
delete process.env.CLAUDE_CODE_OAUTH_TOKEN;
}); });
describe("getName", () => { describe("getName", () => {
@@ -254,15 +253,6 @@ describe("claude-provider.ts", () => {
expect(result.authenticated).toBe(true); expect(result.authenticated).toBe(true);
}); });
it("should detect CLAUDE_CODE_OAUTH_TOKEN", async () => {
process.env.CLAUDE_CODE_OAUTH_TOKEN = "oauth-token";
const result = await provider.detectInstallation();
expect(result.hasApiKey).toBe(true);
expect(result.authenticated).toBe(true);
});
it("should return hasApiKey false when no keys present", async () => { it("should return hasApiKey false when no keys present", async () => {
const result = await provider.detectInstallation(); const result = await provider.detectInstallation();

View File

@@ -179,9 +179,8 @@ Routes models that:
#### Authentication #### Authentication
Requires one of: Requires:
- `ANTHROPIC_API_KEY` environment variable - `ANTHROPIC_API_KEY` environment variable
- `CLAUDE_CODE_OAUTH_TOKEN` environment variable
#### Example Usage #### Example Usage
@@ -704,9 +703,8 @@ describe("Provider Integration", () => {
### Claude Provider ### Claude Provider
```bash ```bash
# Required (one of): # Required:
ANTHROPIC_API_KEY=sk-ant-... ANTHROPIC_API_KEY=sk-ant-...
CLAUDE_CODE_OAUTH_TOKEN=...
``` ```
### Codex Provider ### Codex Provider