The AWF firewall includes a Node.js-based API proxy sidecar (enabled by default) that securely holds LLM API credentials and automatically injects authentication headers while routing all traffic through Squid to respect domain whitelisting.
When enabled, the API proxy sidecar:
- Isolates credentials: API keys never exposed to agent container
- Auto-authentication: Automatically injects Bearer tokens and API keys
- Dual provider support: Supports both OpenAI (Codex) and Anthropic (Claude) APIs
- Transparent proxying: Agent code uses standard environment variables
- Squid routing: All traffic routes through Squid to respect domain whitelisting
┌─────────────────────────────────────────────────┐
│ AWF Network (172.30.0.0/24) │
│ │
│ ┌──────────────┐ ┌─────────────────┐ │
│ │ Squid │◄──────│ Node.js Proxy │ │
│ │ 172.30.0.10 │ │ 172.30.0.30 │ │
│ └──────┬───────┘ └─────────────────┘ │
│ │ ▲ │
│ │ ┌──────────────────────────────┐ │
│ │ │ Agent Container │ │
│ │ │ 172.30.0.20 │ │
│ │ │ OPENAI_BASE_URL= │ │
│ │ │ http://172.30.0.30:10000 │────┘
│ │ │ ANTHROPIC_BASE_URL= │
│ │ │ http://172.30.0.30:10001 │
│ │ └──────────────────────────────┘
│ │
└─────────┼─────────────────────────────────────┘
│ (Domain whitelist enforced)
↓
api.openai.com or api.anthropic.com
Traffic Flow:
- Agent makes request to
172.30.0.30:10000or172.30.0.30:10001 - API proxy injects authentication headers
- API proxy routes through Squid via HTTP_PROXY/HTTPS_PROXY
- Squid enforces domain whitelist (only allowed domains pass)
- Request reaches api.openai.com or api.anthropic.com
The API proxy is enabled by default and automatically deploys when API keys are present:
# Set API keys in environment
export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
# API proxy automatically enabled (no flag needed)
awf --allow-domains api.openai.com,api.anthropic.com \
-- your-command
# Explicitly enable if needed (same as default)
awf --enable-api-proxy \
--allow-domains api.openai.com,api.anthropic.com \
-- your-commandTo disable the API proxy when not needed:
awf --no-enable-api-proxy \
--allow-domains github.com \
-- your-commandexport OPENAI_API_KEY="sk-..."
awf --enable-api-proxy \
--allow-domains api.openai.com \
-- npx @openai/codex -p "write a hello world function"The agent container will automatically use http://172.30.0.30:10000 as the base URL.
export ANTHROPIC_API_KEY="sk-ant-..."
awf --enable-api-proxy \
--allow-domains api.anthropic.com \
-- claude-code "write a hello world function"The agent container will automatically use http://172.30.0.30:10001 as the base URL.
export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
awf --enable-api-proxy \
--allow-domains api.openai.com,api.anthropic.com \
-- your-multi-llm-toolWhen API keys are provided, the sidecar sets these environment variables in the agent container:
| Variable | Value | When Set | Description |
|---|---|---|---|
OPENAI_BASE_URL |
http://172.30.0.30:10000 |
When OPENAI_API_KEY is provided |
OpenAI API proxy endpoint |
ANTHROPIC_BASE_URL |
http://172.30.0.30:10001 |
When ANTHROPIC_API_KEY is provided |
Anthropic API proxy endpoint |
These are standard environment variables recognized by:
- OpenAI Python SDK
- OpenAI Node.js SDK
- Anthropic Python SDK
- Anthropic TypeScript SDK
- Codex CLI tools
- Claude Code CLI
API keys are held in the sidecar container, not the agent:
- Agent code cannot read API keys from environment
- Compromised agent cannot exfiltrate credentials
- Keys are not exposed to the agent container’s stdout/stderr logs
- Keys are stored in sidecar and deployment configuration on disk; protect host filesystem and config accordingly (only non-sensitive key prefixes may be logged for debugging)
The proxy enforces domain-level egress control:
- Agent can only reach
api-proxyhostname - Sidecar routes ALL traffic through Squid proxy
- Squid enforces domain whitelist (L7 filtering)
- No firewall exemption needed for sidecar
The sidecar has strict resource constraints:
- 512MB memory limit
- 100 process limit
- All unnecessary capabilities dropped
no-new-privilegessecurity option
When API keys are present (or --enable-api-proxy is explicitly set):
- Node.js API proxy starts at 172.30.0.30
- API keys passed via environment variables
- HTTP_PROXY/HTTPS_PROXY configured to route through Squid
- Agent container waits for sidecar health check
Agent Code
↓ (makes HTTP request to 172.30.0.30:10000)
Node.js API Proxy
↓ (injects Authorization: Bearer $OPENAI_API_KEY)
↓ (routes via HTTP_PROXY to Squid)
Squid Proxy
↓ (enforces domain whitelist)
↓ (TLS connection to api.openai.com)
OpenAI API
The Node.js proxy automatically adds:
- OpenAI:
Authorization: Bearer $OPENAI_API_KEY - Anthropic:
x-api-key: $ANTHROPIC_API_KEYandanthropic-version: 2023-06-01
awf [OPTIONS] -- COMMANDAPI Proxy behavior (enabled by default):
- Automatically deploys when
OPENAI_API_KEYorANTHROPIC_API_KEYis present - Use
--no-enable-api-proxyto disable explicitly
Environment variables (at least one needed for deployment):
OPENAI_API_KEY- OpenAI API keyANTHROPIC_API_KEY- Anthropic API key
Recommended domain whitelist:
api.openai.com- For OpenAI/Codexapi.anthropic.com- For Anthropic/Claude
The sidecar container:
- Image:
ghcr.io/github/gh-aw-firewall/api-proxy:latest - Base:
node:22-alpine - Network:
awf-netat172.30.0.30 - Ports: 10000 (OpenAI), 10001 (Anthropic)
- Proxy: Routes via Squid at
http://172.30.0.10:3128
API proxy healthcheck on /health endpoint:
- Interval: 5s
- Timeout: 3s
- Retries: 5
- Start period: 5s
⚠️ API proxy enabled but no API keys found in environment
Set OPENAI_API_KEY or ANTHROPIC_API_KEY to use the proxy
Solution: Export API keys before running awf:
export OPENAI_API_KEY="sk-..."
# or
export ANTHROPIC_API_KEY="sk-ant-..."Check if API proxy container started:
docker ps | grep awf-api-proxyView API proxy logs:
docker logs awf-api-proxyEnsure domains are whitelisted:
--allow-domains api.openai.com,api.anthropic.comCheck Squid logs for denials:
docker exec awf-squid cat /var/log/squid/access.log | grep DENIED- Only supports OpenAI and Anthropic APIs
- Keys must be in environment (not file-based)
- No support for Azure OpenAI endpoints
- No request/response logging (by design for security)
Potential improvements:
- Support for additional LLM providers
- Request rate limiting
- Token usage tracking
- Key rotation support
- Vault integration for key storage