-
Notifications
You must be signed in to change notification settings - Fork 6
fix: exclude API keys from agent when api-proxy is enabled #814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: exclude API keys from agent when api-proxy is enabled #814
Conversation
25f50ec
into
claude/fix-github-actions-workflow-again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR aims to fix a security issue where API keys were incorrectly passed to the agent container when api-proxy is enabled. The api-proxy sidecar architecture requires that API keys exist only in the sidecar container, with the agent communicating via BASE_URL environment variables pointing to the proxy.
Changes:
- Added logic to exclude ANTHROPIC_API_KEY and OPENAI_API_KEY from EXCLUDED_ENV_VARS when api-proxy is enabled (for --env-all mode)
- Modified selective pass-through to conditionally add ANTHROPIC_API_KEY only when api-proxy is NOT enabled
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // When api-proxy IS enabled, the key goes to the sidecar only (not to agent) | ||
| if (process.env.ANTHROPIC_API_KEY && !willUseApiProxy) { | ||
| environment.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; | ||
| } |
Copilot
AI
Feb 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistency: OPENAI_API_KEY is missing from the selective pass-through logic. While ANTHROPIC_API_KEY is conditionally passed to the agent only when api-proxy is NOT enabled (lines 397-401), there is no equivalent handling for OPENAI_API_KEY.
This creates an asymmetry where:
- If api-proxy is disabled: ANTHROPIC_API_KEY is passed to agent, but OPENAI_API_KEY is not (unless using --env-all)
- If api-proxy is enabled: Neither key should be passed (correctly handled for ANTHROPIC_API_KEY)
To maintain consistency with the api-proxy architecture and to support OpenAI usage without api-proxy, consider adding similar logic for OPENAI_API_KEY after line 401.
| } | |
| } | |
| // OpenAI API key for OpenAI-based models | |
| // Only pass OPENAI_API_KEY to agent when api-proxy is NOT enabled | |
| // When api-proxy IS enabled, the key goes to the sidecar only (not to agent) | |
| if (process.env.OPENAI_API_KEY && !willUseApiProxy) { | |
| environment.OPENAI_API_KEY = process.env.OPENAI_API_KEY; | |
| } |
| // When api-proxy is enabled, exclude API keys from agent environment | ||
| // The keys are passed to the api-proxy sidecar only (not to the agent) | ||
| const willUseApiProxy = config.enableApiProxy && (config.openaiApiKey || config.anthropicApiKey); | ||
| if (willUseApiProxy) { | ||
| EXCLUDED_ENV_VARS.add('ANTHROPIC_API_KEY'); | ||
| EXCLUDED_ENV_VARS.add('OPENAI_API_KEY'); | ||
| } |
Copilot
AI
Feb 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test coverage: The changes introduce important security logic to exclude API keys from the agent environment when api-proxy is enabled. However, there are no tests verifying that ANTHROPIC_API_KEY and OPENAI_API_KEY are actually excluded from the agent environment when api-proxy is enabled.
Consider adding test cases that:
- Verify ANTHROPIC_API_KEY is NOT in agent.environment when api-proxy is enabled and anthropicApiKey is provided
- Verify OPENAI_API_KEY is NOT in agent.environment when api-proxy is enabled and openaiApiKey is provided
- Test the --env-all scenario to ensure API keys are excluded even when envAll is true
| const willUseApiProxy = config.enableApiProxy && (config.openaiApiKey || config.anthropicApiKey); | ||
| if (willUseApiProxy) { | ||
| EXCLUDED_ENV_VARS.add('ANTHROPIC_API_KEY'); | ||
| EXCLUDED_ENV_VARS.add('OPENAI_API_KEY'); | ||
| } |
Copilot
AI
Feb 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition for willUseApiProxy (line 325) is inconsistent with the condition used to create the api-proxy service (line 917 and elsewhere). The willUseApiProxy check is:
config.enableApiProxy && (config.openaiApiKey || config.anthropicApiKey)
But the api-proxy service creation check is:
config.enableApiProxy && networkConfig.proxyIp && (config.openaiApiKey || config.anthropicApiKey)
This creates a discrepancy: if networkConfig.proxyIp is falsy, API keys would be excluded from the agent environment but no api-proxy service would be created. While proxyIp appears to always be set in practice (line 1099), the logic should be consistent. Consider adding the networkConfig.proxyIp check to the willUseApiProxy condition for consistency and defensive programming.
…ng (#802) * Initial plan * fix(ci): add BASE_URL environment variables for CODEX api-proxy routing CODEX was not being directed to use the api-proxy because the OPENAI_BASE_URL and ANTHROPIC_BASE_URL environment variables were not explicitly set in the smoke-codex workflow. While AWF automatically sets these variables when generating the docker-compose configuration (if API keys are present), explicitly setting them in the workflow env ensures they are available to the CODEX agent for routing API calls through the api-proxy sidecar. This fix adds: - OPENAI_BASE_URL=http://api-proxy:10000 - ANTHROPIC_BASE_URL=http://api-proxy:10001 to the 'Run Codex' step environment variables. Fixes job failure in run 63483600453. * fix(ci): remove API keys from agent env when api-proxy is enabled (#803) * Initial plan * fix(ci): remove API keys from agent env when api-proxy is enabled When api-proxy is enabled (indicated by BASE_URL environment variables), API keys should NOT be exposed to the agent container for security. The api-proxy sidecar holds the credentials and injects auth headers. Previously, the workflow was passing both: - CODEX_API_KEY and OPENAI_API_KEY (should NOT be in agent env) - OPENAI_BASE_URL and ANTHROPIC_BASE_URL (should be in agent env) This defeated the security isolation provided by api-proxy. Changes: - Removed CODEX_API_KEY and OPENAI_API_KEY from agent environment block - Kept OPENAI_BASE_URL and ANTHROPIC_BASE_URL for routing to api-proxy - The awf CLI still receives keys via `sudo -E` and `--env-all` - awf passes keys only to api-proxy container, not agent container Security model: - awf reads keys from host environment (process.env) - awf passes keys only to api-proxy sidecar (src/docker-manager.ts:908-909) - Agent only receives BASE_URL variables (src/docker-manager.ts:948-955) - api-proxy injects auth headers and routes through Squid 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]> Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * fix(firewall): add api-proxy to allowed domains when enabled (#804) * Initial plan * fix(firewall): add api-proxy to allowed domains when enabled Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * fix(squid): handle bare hostnames without leading dot for api-proxy (#805) * Initial plan * fix(squid): handle bare hostnames without leading dot for api-proxy Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * fix(agent): enable direct api-proxy access and remove api key from env (#807) * Initial plan * fix(agent): enable direct api-proxy access and remove api key from env - Add iptables bypass for api-proxy in setup-iptables.sh - Pass AWF_ENABLE_API_PROXY env var from docker-manager.ts - Remove ANTHROPIC_API_KEY from agent env in workflows - Update postprocess script to strip API key from compiled workflows Fixes agent->api-proxy connectivity and security vulnerability where API key was exposed to agent container instead of isolated to api-proxy. --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> * fix: pass ANTHROPIC_API_KEY to validation in all Claude workflows (#808) * Initial plan * fix: pass ANTHROPIC_API_KEY to validation step in smoke-claude workflow Co-authored-by: lpcox <[email protected]> * fix: pass ANTHROPIC_API_KEY to validation in all Claude workflows Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * fix: only enable api-proxy when API keys are provided (#810) * Initial plan * fix: only enable api-proxy when API keys are provided Co-authored-by: lpcox <[email protected]> * feat(workflow): enable api-proxy for smoke-claude workflow - Add --enable-api-proxy flag to awf command - Add --anthropic-api-key flag to pass API key to api-proxy sidecar - Add ANTHROPIC_API_KEY to env block for agent step - API key is shared with api-proxy, kept out of agent container - Agent uses ANTHROPIC_BASE_URL to direct requests to api-proxy Co-authored-by: lpcox <[email protected]> * refactor(workflow): remove redundant --enable-api-proxy flag The --enable-api-proxy flag defaults to true (src/cli.ts:724), so it doesn't need to be explicitly specified. The api-proxy sidecar will automatically deploy when API keys are present. See docs/api-proxy-sidecar.md:51 which states "The API proxy is enabled by default and automatically deploys when API keys are present" Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * fix: remove unknown --anthropic-api-key flag from smoke-claude workflow (#811) * Initial plan * fix: remove unknown --anthropic-api-key flag from smoke-claude workflow Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * fix: use api-proxy IP address instead of hostname for BASE_URL (#813) * Initial plan * fix: use api-proxy IP address instead of hostname for BASE_URL Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * fix: use api-proxy IP address instead of hostname for BASE_URL (#813) (#815) * Initial plan * fix: use api-proxy IP address instead of hostname for BASE_URL (#813) Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * fix(api-proxy): use IP address for API base URLs to avoid DNS issues In chroot mode, Docker container hostname resolution can fail because the DNS resolver may not properly reach Docker's embedded DNS. Use the api-proxy IP address directly (e.g., http://172.30.0.30:10001) instead of the hostname (http://api-proxy:10001) to eliminate DNS resolution as a failure point. Also add test coverage for the host-iptables api-proxy ACCEPT rule. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * fix: exclude API keys from agent when api-proxy is enabled (#814) * Initial plan * fix: exclude API keys from agent when api-proxy is enabled --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> * fix(agent): use AWF_API_PROXY_IP env var for api-proxy iptables rules (#817) * Initial plan * fix(agent): use AWF_API_PROXY_IP env var for api-proxy iptables Move api-proxy iptables rules to use pre-set AWF_API_PROXY_IP environment variable instead of dynamic hostname resolution, and place FILTER rules in the correct position (after NAT setup, before final DROP rule). Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * Add debug logging for BASE_URL environment variables in agent container (#816) * Initial plan * feat: add debug logging for BASE_URL environment variables Add logging to display ANTHROPIC_BASE_URL and OPENAI_BASE_URL values that are set for the agent container. This helps debug configuration issues when running Claude Code CLI in the workflow. The logging is added after the Docker Compose config is generated, showing whether BASE_URL variables are set or using defaults. Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * fix: simplify api-proxy iptables bypass condition (#819) * Initial plan * fix: simplify api-proxy iptables bypass condition The NAT bypass for api-proxy traffic was checking both AWF_ENABLE_API_PROXY and AWF_API_PROXY_IP, but this was too strict. When the HTTP_PROXY environment variable is set, HTTP clients will send requests through the proxy unless NO_PROXY is configured or iptables rules prevent it. The issue was that the NAT bypass required both flags, causing traffic to 172.30.0.30 (api-proxy) to be sent through Squid when it should go directly. Squid then blocked these requests because the IP address wasn't in the domain whitelist. The fix simplifies the condition to only check AWF_API_PROXY_IP, matching the pattern used for the OUTPUT FILTER ACCEPT rules (lines 285-289). This ensures that when AWF_API_PROXY_IP is set, traffic to that IP bypasses Squid at the NAT level, preventing HTTP clients from routing through the proxy regardless of HTTP_PROXY settings. Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> * Initial plan (#818) Co-authored-by: anthropic-code-agent[bot] <[email protected]> * fix: add api-proxy IP to squid allowlist (#820) * Initial plan * fix: add api-proxy IP to squid allowlist Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> --------- Co-authored-by: anthropic-code-agent[bot] <[email protected]> Co-authored-by: lpcox <[email protected]> Co-authored-by: Landon Cox <[email protected]> Co-authored-by: Jiaxiao (mossaka) Zhou <[email protected]> Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
When api-proxy is enabled,
ANTHROPIC_API_KEYandOPENAI_API_KEYwere incorrectly passed to the agent container environment. These keys should only exist in the api-proxy sidecar, with the agent communicating viabase_urlpointing to the proxy.Changes
EXCLUDED_ENV_VARSset whenconfig.enableApiProxyis true and keys are present--env-allcase) to conditionally addANTHROPIC_API_KEYonly when api-proxy is NOT enabledImplementation
Detection uses the same condition as api-proxy service creation:
This ensures both
--env-alland selective pass-through respect the api-proxy architecture.