bypass anthropic proxy for users with own claude credentials

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-05 04:35:34 +00:00
co-authored by Claude Opus 4.6
parent ba9258cc17
commit c54ff9da28
+30 -10
View File
@@ -19,6 +19,14 @@ import type { MessageCost, PiEvent } from '@@/api/pi/types';
const SEND_TIMEOUT_MS = 5 * 60 * 1000;
const PROXY_PORT = process.env.ANTHROPIC_PROXY_PORT ?? '5051';
async function hasOwnCredentials(homeDir: string): Promise<boolean> {
try {
return await Bun.file(join(homeDir, '.claude', '.credentials.json')).exists();
} catch {
return false;
}
}
// Resolve absolute path to claude binary so sudo -u can find it regardless of target user's PATH
const CLAUDE_BIN = (() => {
const result = Bun.spawnSync({ cmd: ['which', 'claude'], stdout: 'pipe', stderr: 'ignore' });
@@ -161,14 +169,19 @@ export async function sendClaudeCode(params: ClaudeCodeParams): Promise<ClaudeCo
}
const isServiceUser = shellUsername === (process.env.USER ?? '');
const userHasCredentials = !isServiceUser && (await hasOwnCredentials(homeDir));
// Service user or users with own credentials use their HOME directly.
// Other users route through the local Anthropic proxy.
const authEnv = isServiceUser
? { HOME: process.env.HOME ?? '' }
: userHasCredentials
? { HOME: homeDir }
: { ANTHROPIC_BASE_URL: `http://127.0.0.1:${PROXY_PORT}`, ANTHROPIC_API_KEY: proxySecret };
// For service user, keep real HOME so Claude Code finds its credentials.
// For other users, route through the local Anthropic proxy.
const env: Record<string, string> = {
...toolEnv,
...(isServiceUser
? { HOME: process.env.HOME ?? '' }
: { ANTHROPIC_BASE_URL: `http://127.0.0.1:${PROXY_PORT}`, ANTHROPIC_API_KEY: proxySecret }),
...authEnv,
PATH: process.env.PATH ?? '',
TERM: 'xterm-256color',
};
@@ -177,6 +190,7 @@ export async function sendClaudeCode(params: ClaudeCodeParams): Promise<ClaudeCo
sessionKey,
username: shellUsername,
isServiceUser,
userHasCredentials,
resume: existingSession ?? null,
});
@@ -319,14 +333,19 @@ export async function sendClaudeCodeStreaming(params: ClaudeCodeStreamingParams)
const { CLAUDECODE: _, ...cleanEnv } = process.env;
const isServiceUser = shellUsername === (process.env.USER ?? '');
const userHasCredentials = !isServiceUser && (await hasOwnCredentials(homeDir));
// Service user or users with own credentials use their HOME directly.
// Other users route through the local Anthropic proxy.
const authEnv = isServiceUser
? { HOME: cleanEnv.HOME ?? '' }
: userHasCredentials
? { HOME: homeDir }
: { ANTHROPIC_BASE_URL: `http://127.0.0.1:${PROXY_PORT}`, ANTHROPIC_API_KEY: proxySecret };
// For service user, keep real HOME so Claude Code finds its credentials.
// For other users, route through the local Anthropic proxy.
const env: Record<string, string> = {
...toolEnv,
...(isServiceUser
? { HOME: cleanEnv.HOME ?? '' }
: { ANTHROPIC_BASE_URL: `http://127.0.0.1:${PROXY_PORT}`, ANTHROPIC_API_KEY: proxySecret }),
...authEnv,
PATH: cleanEnv.PATH ?? '',
TERM: 'xterm-256color',
};
@@ -335,6 +354,7 @@ export async function sendClaudeCodeStreaming(params: ClaudeCodeStreamingParams)
sessionKey,
username: shellUsername,
isServiceUser,
userHasCredentials,
cwd: workDir,
resume: existingSession ?? null,
});