Skip to content

Commit 5bbcbb9

Browse files
authored
[awf] API proxy: correct OpenAI base URL injection for Codex /v1/responses routing (#2066)
* Initial plan * fix: use root OpenAI base URL for api-proxy sidecar Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/8ce1feb1-b26f-482b-a53d-897a5827e183 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 49e9508 commit 5bbcbb9

File tree

5 files changed

+18
-18
lines changed

5 files changed

+18
-18
lines changed

docs/api-proxy-sidecar.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ When enabled, the API proxy sidecar:
3333
│ │ │ Agent Container │ │
3434
│ │ │ 172.30.0.20 │ │
3535
│ │ │ OPENAI_BASE_URL= │ │
36-
│ │ │ http://172.30.0.30:10000/v1│────┘
36+
│ │ │ http://172.30.0.30:10000 │────┘
3737
│ │ │ ANTHROPIC_BASE_URL= │
3838
│ │ │ http://172.30.0.30:10001 │
3939
│ │ └──────────────────────────────┘
@@ -76,7 +76,7 @@ sudo awf --enable-api-proxy \
7676
-- npx @openai/codex -p "write a hello world function"
7777
```
7878

79-
The agent container automatically uses `http://172.30.0.30:10000/v1` as the OpenAI base URL.
79+
The agent container automatically uses `http://172.30.0.30:10000` as the OpenAI base URL.
8080

8181
### Claude Code example
8282

@@ -138,7 +138,7 @@ The agent container receives **redacted placeholders** and proxy URLs:
138138

139139
| Variable | Value | When set | Description |
140140
|----------|-------|----------|-------------|
141-
| `OPENAI_BASE_URL` | `http://172.30.0.30:10000/v1` | `OPENAI_API_KEY` provided to host | Redirects OpenAI SDK to proxy |
141+
| `OPENAI_BASE_URL` | `http://172.30.0.30:10000` | `OPENAI_API_KEY` provided to host | Redirects OpenAI SDK to proxy |
142142
| `ANTHROPIC_BASE_URL` | `http://172.30.0.30:10001` | `ANTHROPIC_API_KEY` provided to host | Redirects Anthropic SDK to proxy |
143143
| `ANTHROPIC_AUTH_TOKEN` | `placeholder-token-for-credential-isolation` | `ANTHROPIC_API_KEY` provided to host | Placeholder token (real auth via BASE_URL) |
144144
| `CLAUDE_CODE_API_KEY_HELPER` | `/usr/local/bin/get-claude-key.sh` | `ANTHROPIC_API_KEY` provided to host | Helper script for Claude Code CLI |
@@ -231,7 +231,7 @@ When you pass `--enable-api-proxy`:
231231

232232
```
233233
Agent Code
234-
↓ (HTTP request to 172.30.0.30:10000/v1)
234+
↓ (HTTP request to 172.30.0.30:10000)
235235
Node.js API Proxy
236236
↓ (strips client auth headers)
237237
↓ (injects Authorization: Bearer $OPENAI_API_KEY)

docs/authentication-architecture.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ AWF uses a **3-container architecture** when API proxy mode is enabled:
4141
│ ✓ HTTP_PROXY=172.30.0.10:3128 │ │ ✓ ANTHROPIC_BASE_URL= │
4242
│ ✓ HTTPS_PROXY=172.30.0.10:3128 │ │ http://172.30.0.30:10001 │
4343
│ │ │ ✓ OPENAI_BASE_URL= │
44-
│ Ports: │ │ http://172.30.0.30:10000/v1
44+
│ Ports: │ │ http://172.30.0.30:10000
4545
│ - 10000 (OpenAI proxy) │◄──────│ ✓ GITHUB_TOKEN=ghp_... │
4646
│ - 10001 (Anthropic proxy) │ │ (protected by one-shot-token) │
4747
│ │ │ │
@@ -113,7 +113,7 @@ agent:
113113
environment:
114114
# NO API KEYS - only base URLs pointing to api-proxy
115115
- ANTHROPIC_BASE_URL=http://172.30.0.30:10001
116-
- OPENAI_BASE_URL=http://172.30.0.30:10000/v1
116+
- OPENAI_BASE_URL=http://172.30.0.30:10000
117117
# GitHub token for MCP servers (protected separately)
118118
- GITHUB_TOKEN=ghp_...
119119
networks:
@@ -174,7 +174,7 @@ The agent container sees these environment variables:
174174

175175
```bash
176176
ANTHROPIC_BASE_URL=http://172.30.0.30:10001
177-
OPENAI_BASE_URL=http://172.30.0.30:10000/v1
177+
OPENAI_BASE_URL=http://172.30.0.30:10000
178178
```
179179

180180
These are standard environment variables recognized by the official SDKs:
@@ -209,7 +209,7 @@ import openai
209209

210210
client = openai.OpenAI()
211211
# SDK reads OPENAI_BASE_URL from environment
212-
# Sends request to http://172.30.0.30:10000/v1 instead of api.openai.com
212+
# Sends request to http://172.30.0.30:10000 instead of api.openai.com
213213

214214
response = client.chat.completions.create(
215215
model="gpt-4",
@@ -250,7 +250,7 @@ Without the NAT `RETURN` rule, traffic to `172.30.0.30` would be redirected to S
250250

251251
**Traffic flow for OpenAI/Codex:**
252252

253-
1. Agent SDK makes HTTP request to `172.30.0.30:10000/v1`
253+
1. Agent SDK makes HTTP request to `172.30.0.30:10000`
254254
2. iptables allows direct TCP connection (NAT `RETURN` rule)
255255
3. API proxy receives request on port 10000
256256
4. API proxy injects `Authorization: Bearer sk-...` header

src/docker-manager.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,7 +2345,7 @@ describe('docker-manager', () => {
23452345
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
23462346
const agent = result.services.agent;
23472347
const env = agent.environment as Record<string, string>;
2348-
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000/v1');
2348+
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000');
23492349
});
23502350

23512351
it('should configure HTTP_PROXY and HTTPS_PROXY in api-proxy to route through Squid', () => {
@@ -2372,7 +2372,7 @@ describe('docker-manager', () => {
23722372
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
23732373
const agent = result.services.agent;
23742374
const env = agent.environment as Record<string, string>;
2375-
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000/v1');
2375+
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000');
23762376
expect(env.ANTHROPIC_BASE_URL).toBe('http://172.30.0.30:10001');
23772377
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('sk-ant-placeholder-key-for-credential-isolation');
23782378
expect(env.CLAUDE_CODE_API_KEY_HELPER).toBe('/usr/local/bin/get-claude-key.sh');
@@ -2395,7 +2395,7 @@ describe('docker-manager', () => {
23952395
const agent = result.services.agent;
23962396
const env = agent.environment as Record<string, string>;
23972397
expect(env.ANTHROPIC_BASE_URL).toBeUndefined();
2398-
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000/v1');
2398+
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000');
23992399
});
24002400

24012401
it('should set AWF_API_PROXY_IP in agent environment', () => {
@@ -2467,7 +2467,7 @@ describe('docker-manager', () => {
24672467
// Agent should NOT have the raw API key — only the sidecar gets it
24682468
expect(env.OPENAI_API_KEY).toBeUndefined();
24692469
// Agent should have OPENAI_BASE_URL to proxy through sidecar
2470-
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000/v1');
2470+
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000');
24712471
} finally {
24722472
if (origKey !== undefined) {
24732473
process.env.OPENAI_API_KEY = origKey;
@@ -2490,7 +2490,7 @@ describe('docker-manager', () => {
24902490
// CODEX_API_KEY should NOT be passed to agent when api-proxy is enabled
24912491
expect(env.CODEX_API_KEY).toBeUndefined();
24922492
// OPENAI_BASE_URL should be set when api-proxy is enabled with openaiApiKey
2493-
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000/v1');
2493+
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000');
24942494
} finally {
24952495
if (origKey !== undefined) {
24962496
process.env.CODEX_API_KEY = origKey;
@@ -2512,7 +2512,7 @@ describe('docker-manager', () => {
25122512
// Even with envAll, agent should NOT have OPENAI_API_KEY when api-proxy is enabled
25132513
expect(env.OPENAI_API_KEY).toBeUndefined();
25142514
// Agent should have OPENAI_BASE_URL to proxy through sidecar
2515-
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000/v1');
2515+
expect(env.OPENAI_BASE_URL).toBe('http://172.30.0.30:10000');
25162516
} finally {
25172517
if (origKey !== undefined) {
25182518
process.env.OPENAI_API_KEY = origKey;

src/docker-manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,8 +1802,8 @@ export function generateDockerCompose(
18021802
// container names in chroot mode
18031803
environment.AWF_API_PROXY_IP = networkConfig.proxyIp;
18041804
if (config.openaiApiKey) {
1805-
environment.OPENAI_BASE_URL = `http://${networkConfig.proxyIp}:${API_PROXY_PORTS.OPENAI}/v1`;
1806-
logger.debug(`OpenAI API will be proxied through sidecar at http://${networkConfig.proxyIp}:${API_PROXY_PORTS.OPENAI}/v1`);
1805+
environment.OPENAI_BASE_URL = `http://${networkConfig.proxyIp}:${API_PROXY_PORTS.OPENAI}`;
1806+
logger.debug(`OpenAI API will be proxied through sidecar at http://${networkConfig.proxyIp}:${API_PROXY_PORTS.OPENAI}`);
18071807
if (config.openaiApiTarget) {
18081808
logger.debug(`OpenAI API target overridden to: ${config.openaiApiTarget}`);
18091809
}

src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ export interface WrapperConfig {
615615
*
616616
* When the corresponding API key is provided, the following environment
617617
* variables are set in the agent container:
618-
* - OPENAI_BASE_URL=http://api-proxy:10000/v1 (set when OPENAI_API_KEY is provided)
618+
* - OPENAI_BASE_URL=http://api-proxy:10000 (set when OPENAI_API_KEY is provided)
619619
* - ANTHROPIC_BASE_URL=http://api-proxy:10001 (set when ANTHROPIC_API_KEY is provided)
620620
* - COPILOT_API_URL=http://api-proxy:10002 (set when COPILOT_GITHUB_TOKEN or COPILOT_API_KEY is provided)
621621
* - CLAUDE_CODE_API_KEY_HELPER=/usr/local/bin/get-claude-key.sh (set when ANTHROPIC_API_KEY is provided)

0 commit comments

Comments
 (0)