Problem
After the chroot key helper fix (PR #1508), the script copy and config path updates work correctly, and the firewall allows traffic through to api.anthropic.com. However, all Anthropic API calls fail with error: "unknown", error_status: null, and zero tokens consumed — indicating the requests reach Anthropic but are rejected.
[entrypoint] ✓ Updated apiKeyHelper path in /host/home/runner/.claude.json
[entrypoint] ✓ Updated apiKeyHelper path in /host/home/runner/.claude/settings.json
[entrypoint] Claude key helper copied to chroot at /tmp/awf-lib/get-claude-key.sh
- ✅ Chroot fix works (paths updated)
- ✅ Squid allows 4 requests to
api.anthropic.com (0 blocked)
- ❌ All 10 API retries fail:
error: "unknown", error_status: null
- ❌ Zero tokens consumed, zero cost — API never successfully authenticated
The ANTHROPIC_API_KEY works fine outside gh-aw (validated by the activation step).
Environment
Authentication Chain Analysis
The expected chain:
Claude Code → apiKeyHelper (get-claude-key.sh)
→ returns "sk-ant-placeholder-key-for-credential-isolation"
→ sends x-api-key: <placeholder> to ANTHROPIC_BASE_URL (http://172.30.0.30:10001)
→ api-proxy strips x-api-key, injects real ANTHROPIC_API_KEY
→ forwards through Squid to api.anthropic.com
→ Anthropic authenticates with real key
The chain breaks somewhere between the api-proxy injecting the key and Anthropic accepting the request.
Hypotheses
H1: Claude Code 2.1.88 auth mechanism mismatch
Claude Code may use a different auth flow than the standard Anthropic SDK:
- Might send
Authorization: Bearer instead of or in addition to x-api-key
- Might use a different API endpoint path (e.g.,
/v1/complete vs /v1/messages)
- Might require an
anthropic-version header value newer than the proxy's default 2023-06-01
The api-proxy strips authorization and x-api-key headers and only injects x-api-key. If Claude Code requires a header the proxy doesn't inject, auth would fail.
H2: ANTHROPIC_AUTH_TOKEN interference
The agent has TWO different placeholder values:
ANTHROPIC_AUTH_TOKEN=placeholder-token-for-credential-isolation (env var, docker-manager.ts:1450)
apiKeyHelper returns sk-ant-placeholder-key-for-credential-isolation (script output)
Claude Code might prefer ANTHROPIC_AUTH_TOKEN over apiKeyHelper for certain operations, sending it as a different header that the proxy doesn't handle. Or the two conflicting values might cause confusion in Claude Code's auth logic.
H3: SSE streaming response not proxied correctly
The error_status: null (not 401/403) suggests Claude Code can't parse the response rather than receiving a clear auth error. The api-proxy uses proxyRequest() which pipes the upstream response back — if SSE chunked encoding is mangled, Claude Code would see "unknown" errors.
H4: Squid CONNECT tunnel issue
The 4 "allowed" Squid requests might be CONNECT tunnel establishments (HTTP 200), not the actual API calls. The real API responses within the tunnel might be failing. Squid logs showing TCP_TUNNEL:HIER_DIRECT with status 200 only means the tunnel was established, not that the API call succeeded.
Suggested Investigation
- Enable api-proxy debug logging and check if requests are being received and forwarded with the correct
x-api-key header
- Compare headers sent by Claude Code 2.1.88 vs what the proxy expects — check if Claude Code sends auth in a header the proxy doesn't handle
- Check the Anthropic response status in the api-proxy logs (before it's sent back to the agent)
- Test with
curl through the same proxy chain to isolate whether it's a Claude Code-specific issue:
curl -v http://172.30.0.30:10001/v1/messages \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{"model":"claude-sonnet-4-20250514","max_tokens":10,"messages":[{"role":"user","content":"hi"}]}'
- Try removing
ANTHROPIC_AUTH_TOKEN from the agent environment to see if it interferes with apiKeyHelper
References
Problem
After the chroot key helper fix (PR #1508), the script copy and config path updates work correctly, and the firewall allows traffic through to
api.anthropic.com. However, all Anthropic API calls fail witherror: "unknown",error_status: null, and zero tokens consumed — indicating the requests reach Anthropic but are rejected.Observed behavior (from gh-aw#23614 comment)
api.anthropic.com(0 blocked)error: "unknown",error_status: nullThe
ANTHROPIC_API_KEYworks fine outside gh-aw (validated by the activation step).Environment
Authentication Chain Analysis
The expected chain:
The chain breaks somewhere between the api-proxy injecting the key and Anthropic accepting the request.
Hypotheses
H1: Claude Code 2.1.88 auth mechanism mismatch
Claude Code may use a different auth flow than the standard Anthropic SDK:
Authorization: Bearerinstead of or in addition tox-api-key/v1/completevs/v1/messages)anthropic-versionheader value newer than the proxy's default2023-06-01The api-proxy strips
authorizationandx-api-keyheaders and only injectsx-api-key. If Claude Code requires a header the proxy doesn't inject, auth would fail.H2:
ANTHROPIC_AUTH_TOKENinterferenceThe agent has TWO different placeholder values:
ANTHROPIC_AUTH_TOKEN=placeholder-token-for-credential-isolation(env var,docker-manager.ts:1450)apiKeyHelperreturnssk-ant-placeholder-key-for-credential-isolation(script output)Claude Code might prefer
ANTHROPIC_AUTH_TOKENoverapiKeyHelperfor certain operations, sending it as a different header that the proxy doesn't handle. Or the two conflicting values might cause confusion in Claude Code's auth logic.H3: SSE streaming response not proxied correctly
The
error_status: null(not 401/403) suggests Claude Code can't parse the response rather than receiving a clear auth error. The api-proxy usesproxyRequest()which pipes the upstream response back — if SSE chunked encoding is mangled, Claude Code would see "unknown" errors.H4: Squid CONNECT tunnel issue
The 4 "allowed" Squid requests might be CONNECT tunnel establishments (HTTP 200), not the actual API calls. The real API responses within the tunnel might be failing. Squid logs showing
TCP_TUNNEL:HIER_DIRECTwith status 200 only means the tunnel was established, not that the API call succeeded.Suggested Investigation
x-api-keyheadercurlthrough the same proxy chain to isolate whether it's a Claude Code-specific issue:ANTHROPIC_AUTH_TOKENfrom the agent environment to see if it interferes withapiKeyHelperReferences
containers/api-proxy/server.js:718-749containers/agent/get-claude-key.shsrc/docker-manager.ts:1438-1457src/docker-manager.ts:1358-1370