Skip to content

Commit 12486e2

Browse files
authored
[WIP] Refactor API proxy secret-isolation tests to reduce duplicate code (#5305)
* Initial plan * test: deduplicate api-proxy key isolation env scaffolding * test: fix api-proxy env helper typing --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent cce6b4d commit 12486e2

1 file changed

Lines changed: 44 additions & 91 deletions

File tree

Lines changed: 44 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { generateDockerCompose, WrapperConfig, baseConfig, mockNetworkConfig, useTempWorkDir } from './service-test-setup.test-utils';
22
import { mockNetworkConfigWithProxy } from './api-proxy-service.test-utils';
3+
import { NetworkConfig } from './squid-service';
34

45
// Create mock functions (must remain per-file — jest.mock() is hoisted before imports)
56

@@ -10,6 +11,28 @@ jest.mock('execa', () => require('../test-helpers/mock-execa.test-utils').execaM
1011
let mockConfig: WrapperConfig;
1112

1213
describe('API proxy sidecar: API key isolation', () => {
14+
const withEnvVar = (name: keyof NodeJS.ProcessEnv, value: string, assertion: () => void): void => {
15+
const original = process.env[name];
16+
process.env[name] = value;
17+
try {
18+
assertion();
19+
} finally {
20+
if (original !== undefined) {
21+
process.env[name] = original;
22+
} else {
23+
delete process.env[name];
24+
}
25+
}
26+
};
27+
28+
const getAgentEnvironment = (
29+
config: WrapperConfig,
30+
networkConfig: NetworkConfig = mockNetworkConfigWithProxy
31+
): NodeJS.ProcessEnv => {
32+
const result = generateDockerCompose(config, networkConfig);
33+
return result.services.agent.environment ?? {};
34+
};
35+
1336
useTempWorkDir(
1437
baseConfig,
1538
(config) => {
@@ -20,165 +43,95 @@ describe('API proxy sidecar: API key isolation', () => {
2043

2144
it('should not leak ANTHROPIC_API_KEY to agent when api-proxy is enabled', () => {
2245
// Simulate the key being in process.env (as it would be in real usage)
23-
const origKey = process.env.ANTHROPIC_API_KEY;
24-
process.env.ANTHROPIC_API_KEY = 'sk-ant-secret-key';
25-
try {
46+
withEnvVar('ANTHROPIC_API_KEY', 'sk-ant-secret-key', () => {
2647
const configWithProxy = { ...mockConfig, enableApiProxy: true, anthropicApiKey: 'sk-ant-secret-key' };
27-
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
28-
const agent = result.services.agent;
29-
const env = agent.environment as Record<string, string>;
48+
const env = getAgentEnvironment(configWithProxy);
3049
// Agent should NOT have the raw API key — only the sidecar gets it
3150
expect(env.ANTHROPIC_API_KEY).toBeUndefined();
3251
// Agent should have the BASE_URL to reach the sidecar instead
3352
expect(env.ANTHROPIC_BASE_URL).toBe('http://172.30.0.30:10001');
3453
// Agent should have placeholder token for Claude Code compatibility
3554
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('sk-ant-placeholder-key-for-credential-isolation');
36-
} finally {
37-
if (origKey !== undefined) {
38-
process.env.ANTHROPIC_API_KEY = origKey;
39-
} else {
40-
delete process.env.ANTHROPIC_API_KEY;
41-
}
42-
}
55+
});
4356
});
4457

4558
it('should not leak OPENAI_API_KEY to agent when api-proxy is enabled', () => {
4659
// Simulate the key being in process.env (as it would be in real usage)
47-
const origKey = process.env.OPENAI_API_KEY;
48-
process.env.OPENAI_API_KEY = 'sk-secret-key';
49-
try {
60+
withEnvVar('OPENAI_API_KEY', 'sk-secret-key', () => {
5061
const configWithProxy = { ...mockConfig, enableApiProxy: true, openaiApiKey: 'sk-secret-key' };
51-
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
52-
const agent = result.services.agent;
53-
const env = agent.environment as Record<string, string>;
62+
const env = getAgentEnvironment(configWithProxy);
5463
// Agent should NOT have the real API key — only the sidecar holds it.
5564
// A placeholder is injected so Codex/OpenAI clients route through OPENAI_BASE_URL
5665
// (Codex v0.121+ bypasses OPENAI_BASE_URL when no key is present in the env).
5766
expect(env.OPENAI_API_KEY).toBe('sk-placeholder-for-api-proxy');
5867
expect(env.OPENAI_API_KEY).not.toBe('sk-secret-key');
5968
// Agent should have OPENAI_BASE_URL to proxy through sidecar
6069
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000');
61-
} finally {
62-
if (origKey !== undefined) {
63-
process.env.OPENAI_API_KEY = origKey;
64-
} else {
65-
delete process.env.OPENAI_API_KEY;
66-
}
67-
}
70+
});
6871
});
6972

7073
it('should not leak CODEX_API_KEY to agent when api-proxy is enabled with envAll', () => {
7174
// Simulate the key being in process.env AND envAll enabled.
7275
// The host's real CODEX_API_KEY must not reach the agent; a placeholder is
7376
// injected instead so Codex routes through OPENAI_BASE_URL (api-proxy).
74-
const origKey = process.env.CODEX_API_KEY;
75-
process.env.CODEX_API_KEY = 'sk-codex-secret';
76-
try {
77+
withEnvVar('CODEX_API_KEY', 'sk-codex-secret', () => {
7778
const configWithProxy = { ...mockConfig, enableApiProxy: true, openaiApiKey: 'sk-test', envAll: true };
78-
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
79-
const agent = result.services.agent;
80-
const env = agent.environment as Record<string, string>;
79+
const env = getAgentEnvironment(configWithProxy);
8180
// CODEX_API_KEY placeholder is set; the real host key must not be present
8281
expect(env.CODEX_API_KEY).toBe('sk-placeholder-for-api-proxy');
8382
expect(env.CODEX_API_KEY).not.toBe('sk-codex-secret');
8483
// OPENAI_BASE_URL should be set when api-proxy is enabled with openaiApiKey
8584
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000');
86-
} finally {
87-
if (origKey !== undefined) {
88-
process.env.CODEX_API_KEY = origKey;
89-
} else {
90-
delete process.env.CODEX_API_KEY;
91-
}
92-
}
85+
});
9386
});
9487

9588
it('should not leak OPENAI_API_KEY to agent when api-proxy is enabled with envAll', () => {
9689
// Simulate envAll scenario (smoke-codex uses --env-all).
9790
// Even with envAll, the real key must not reach the agent; a placeholder is used instead.
98-
const origKey = process.env.OPENAI_API_KEY;
99-
process.env.OPENAI_API_KEY = 'sk-openai-secret';
100-
try {
91+
withEnvVar('OPENAI_API_KEY', 'sk-openai-secret', () => {
10192
const configWithProxy = { ...mockConfig, enableApiProxy: true, openaiApiKey: 'sk-openai-secret', envAll: true };
102-
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
103-
const agent = result.services.agent;
104-
const env = agent.environment as Record<string, string>;
93+
const env = getAgentEnvironment(configWithProxy);
10594
// Placeholder is set; real key must not be passed to agent
10695
expect(env.OPENAI_API_KEY).toBe('sk-placeholder-for-api-proxy');
10796
expect(env.OPENAI_API_KEY).not.toBe('sk-openai-secret');
10897
// Agent should have OPENAI_BASE_URL to proxy through sidecar
10998
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000');
110-
} finally {
111-
if (origKey !== undefined) {
112-
process.env.OPENAI_API_KEY = origKey;
113-
} else {
114-
delete process.env.OPENAI_API_KEY;
115-
}
116-
}
99+
});
117100
});
118101

119102
it('should not leak ANTHROPIC_API_KEY to agent when api-proxy is enabled with envAll', () => {
120-
const origKey = process.env.ANTHROPIC_API_KEY;
121-
process.env.ANTHROPIC_API_KEY = 'sk-ant-secret';
122-
try {
103+
withEnvVar('ANTHROPIC_API_KEY', 'sk-ant-secret', () => {
123104
const configWithProxy = { ...mockConfig, enableApiProxy: true, anthropicApiKey: 'sk-ant-secret', envAll: true };
124-
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
125-
const agent = result.services.agent;
126-
const env = agent.environment as Record<string, string>;
105+
const env = getAgentEnvironment(configWithProxy);
127106
// Even with envAll, agent should NOT have ANTHROPIC_API_KEY when api-proxy is enabled
128107
expect(env.ANTHROPIC_API_KEY).toBeUndefined();
129108
expect(env.ANTHROPIC_BASE_URL).toBe('http://172.30.0.30:10001');
130109
// But should have placeholder token for Claude Code compatibility
131110
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('sk-ant-placeholder-key-for-credential-isolation');
132-
} finally {
133-
if (origKey !== undefined) {
134-
process.env.ANTHROPIC_API_KEY = origKey;
135-
} else {
136-
delete process.env.ANTHROPIC_API_KEY;
137-
}
138-
}
111+
});
139112
});
140113

141114
it('should pass GITHUB_API_URL to agent when api-proxy is enabled with envAll', () => {
142115
// GITHUB_API_URL must remain in the agent environment even when api-proxy is enabled.
143116
// The Copilot CLI needs it to locate the GitHub API (token exchange, user info, etc.).
144117
// Copilot-specific calls route through COPILOT_API_URL → api-proxy regardless.
145118
// See: github/gh-aw#20875
146-
const origUrl = process.env.GITHUB_API_URL;
147-
process.env.GITHUB_API_URL = 'https://api.github.com';
148-
try {
119+
withEnvVar('GITHUB_API_URL', 'https://api.github.com', () => {
149120
const configWithProxy = { ...mockConfig, enableApiProxy: true, copilotGithubToken: 'ghp_test_token', envAll: true };
150-
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
151-
const agent = result.services.agent;
152-
const env = agent.environment as Record<string, string>;
121+
const env = getAgentEnvironment(configWithProxy);
153122
// GITHUB_API_URL should be passed to agent even when api-proxy is enabled
154123
expect(env.GITHUB_API_URL).toBe('https://api.github.com');
155124
// COPILOT_API_URL should also be set to route Copilot calls through the api-proxy
156125
expect(env.COPILOT_API_URL).toBe('http://172.30.0.30:10002');
157-
} finally {
158-
if (origUrl !== undefined) {
159-
process.env.GITHUB_API_URL = origUrl;
160-
} else {
161-
delete process.env.GITHUB_API_URL;
162-
}
163-
}
126+
});
164127
});
165128

166129
it('should pass GITHUB_API_URL to agent when api-proxy is NOT enabled with envAll', () => {
167-
const origUrl = process.env.GITHUB_API_URL;
168-
process.env.GITHUB_API_URL = 'https://api.github.com';
169-
try {
130+
withEnvVar('GITHUB_API_URL', 'https://api.github.com', () => {
170131
const configNoProxy = { ...mockConfig, enableApiProxy: false, envAll: true };
171-
const result = generateDockerCompose(configNoProxy, mockNetworkConfig);
172-
const agent = result.services.agent;
173-
const env = agent.environment as Record<string, string>;
132+
const env = getAgentEnvironment(configNoProxy, mockNetworkConfig);
174133
// When api-proxy is NOT enabled, GITHUB_API_URL should be passed through
175134
expect(env.GITHUB_API_URL).toBe('https://api.github.com');
176-
} finally {
177-
if (origUrl !== undefined) {
178-
process.env.GITHUB_API_URL = origUrl;
179-
} else {
180-
delete process.env.GITHUB_API_URL;
181-
}
182-
}
135+
});
183136
});
184137
});

0 commit comments

Comments
 (0)