Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/docker-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,7 @@ describe('docker-manager', () => {
const agent = result.services.agent;
const env = agent.environment as Record<string, string>;
expect(env.ANTHROPIC_BASE_URL).toBe('http://172.30.0.30:10001');
expect(env.CLAUDE_CODE_API_KEY_HELPER).toBe('/usr/local/bin/get-claude-key.sh');
});

it('should set both BASE_URL variables when both keys are provided', () => {
Expand All @@ -1577,6 +1578,7 @@ describe('docker-manager', () => {
const env = agent.environment as Record<string, string>;
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000');
expect(env.ANTHROPIC_BASE_URL).toBe('http://172.30.0.30:10001');
expect(env.CLAUDE_CODE_API_KEY_HELPER).toBe('/usr/local/bin/get-claude-key.sh');
});

it('should not set OPENAI_BASE_URL in agent when only Anthropic key is provided', () => {
Expand All @@ -1586,6 +1588,7 @@ describe('docker-manager', () => {
const env = agent.environment as Record<string, string>;
expect(env.OPENAI_BASE_URL).toBeUndefined();
expect(env.ANTHROPIC_BASE_URL).toBe('http://172.30.0.30:10001');
expect(env.CLAUDE_CODE_API_KEY_HELPER).toBe('/usr/local/bin/get-claude-key.sh');
});

it('should not set ANTHROPIC_BASE_URL in agent when only OpenAI key is provided', () => {
Expand Down Expand Up @@ -1614,6 +1617,22 @@ describe('docker-manager', () => {
expect(env.no_proxy).toContain('172.30.0.30');
});

it('should set CLAUDE_CODE_API_KEY_HELPER when Anthropic key is provided', () => {
const configWithProxy = { ...mockConfig, enableApiProxy: true, anthropicApiKey: 'sk-ant-test-key' };
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
const agent = result.services.agent;
const env = agent.environment as Record<string, string>;
expect(env.CLAUDE_CODE_API_KEY_HELPER).toBe('/usr/local/bin/get-claude-key.sh');
});

it('should not set CLAUDE_CODE_API_KEY_HELPER when only OpenAI key is provided', () => {
const configWithProxy = { ...mockConfig, enableApiProxy: true, openaiApiKey: 'sk-test-key' };
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
const agent = result.services.agent;
const env = agent.environment as Record<string, string>;
expect(env.CLAUDE_CODE_API_KEY_HELPER).toBeUndefined();
});

it('should not leak ANTHROPIC_API_KEY to agent when api-proxy is enabled', () => {
// Simulate the key being in process.env (as it would be in real usage)
const origKey = process.env.ANTHROPIC_API_KEY;
Expand Down
5 changes: 5 additions & 0 deletions src/docker-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,11 @@ export function generateDockerCompose(
if (config.anthropicApiKey) {
environment.ANTHROPIC_BASE_URL = `http://${networkConfig.proxyIp}:10001`;
logger.debug(`Anthropic API will be proxied through sidecar at http://${networkConfig.proxyIp}:10001`);

// Set API key helper for Claude Code CLI to use credential isolation
// The helper script returns a placeholder key; real authentication happens via ANTHROPIC_BASE_URL
environment.CLAUDE_CODE_API_KEY_HELPER = '/usr/local/bin/get-claude-key.sh';
logger.debug('Claude Code API key helper configured: /usr/local/bin/get-claude-key.sh');
}

logger.info('API proxy sidecar enabled - API keys will be held securely in sidecar container');
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ export interface WrapperConfig {
* variables are set in the agent container:
* - OPENAI_BASE_URL=http://api-proxy:10000 (set when OPENAI_API_KEY is provided)
* - ANTHROPIC_BASE_URL=http://api-proxy:10001 (set when ANTHROPIC_API_KEY is provided)
* - CLAUDE_CODE_API_KEY_HELPER=/usr/local/bin/get-claude-key.sh (set when ANTHROPIC_API_KEY is provided)
*
* API keys are passed via environment variables:
* - OPENAI_API_KEY - Optional OpenAI API key for Codex
Expand Down
Loading