Bug description
Using claude-code-action@v1 with ANTHROPIC_BASE_URL pointing to a LiteLLM proxy results in a 403 Forbidden nginx error. The same credentials and endpoint work fine with the Anthropic SDK (@anthropic-ai/sdk) from the same GitHub Actions runner.
Reproduction
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.LITELLM_API_KEY }}
prompt: "Review this PR"
settings: >-
{"env":{"ANTHROPIC_AUTH_TOKEN":"${{ secrets.LITELLM_API_KEY }}","ANTHROPIC_BASE_URL":"https://litellm.example.com"}}
env:
ANTHROPIC_BASE_URL: https://litellm.example.com
Error
Failed to authenticate. API Error: 403 <html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
</body>
</html>
What works from the same runner
- name: SDK test (works)
env:
ANTHROPIC_API_KEY: ${{ secrets.LITELLM_API_KEY }}
ANTHROPIC_BASE_URL: https://litellm.example.com
run: |
cd /tmp && npm install @anthropic-ai/sdk@latest
node -e "
const Anthropic = require('@anthropic-ai/sdk');
new Anthropic().messages.create({
model: 'claude-sonnet-4-6', max_tokens: 10,
messages: [{role: 'user', content: 'hi'}]
}).then(r => console.log('SUCCESS:', r.content[0].text));
"
This returns SUCCESS: Hi there! How are you... — proving the endpoint, credentials, and network path all work.
Configurations attempted
| Config |
Result |
anthropic_api_key only |
403 |
ANTHROPIC_CUSTOM_HEADERS: "Authorization: Bearer <key>" |
403 |
settings with ANTHROPIC_AUTH_TOKEN (matching Claude Code's setup.py) |
403 |
DISABLE_PROMPT_CACHING + CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC |
403 |
classify_inline_comments: false |
403 (main SDK call still fails) |
Analysis
The 403 originates from the Claude Code binary spawned by @anthropic-ai/claude-agent-sdk, not from the action's JavaScript or the Anthropic SDK. The agent SDK's internal HTTP client appears to make API calls differently from the standard @anthropic-ai/sdk.
The LiteLLM proxy requires Authorization: Bearer or x-api-key headers. The standard SDK sends x-api-key and works. The agent SDK binary seems to either:
- Make a side-channel API call to
api.anthropic.com directly (bypassing ANTHROPIC_BASE_URL)
- Not forward
ANTHROPIC_AUTH_TOKEN from settings to its HTTP client
- Use a different auth mechanism that the proxy rejects
Environment
claude-code-action@v1
- LiteLLM proxy (v1.82.3) → AWS Bedrock
- GitHub Actions ubuntu-latest (Node v20.20.1)
- Claude Code CLI works locally with the same LiteLLM proxy via
ANTHROPIC_AUTH_TOKEN in ~/.claude/settings.json
Bug description
Using
claude-code-action@v1withANTHROPIC_BASE_URLpointing to a LiteLLM proxy results in a403 Forbiddennginx error. The same credentials and endpoint work fine with the Anthropic SDK (@anthropic-ai/sdk) from the same GitHub Actions runner.Reproduction
Error
What works from the same runner
This returns
SUCCESS: Hi there! How are you...— proving the endpoint, credentials, and network path all work.Configurations attempted
anthropic_api_keyonlyANTHROPIC_CUSTOM_HEADERS: "Authorization: Bearer <key>"settingswithANTHROPIC_AUTH_TOKEN(matching Claude Code's setup.py)DISABLE_PROMPT_CACHING+CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICclassify_inline_comments: falseAnalysis
The 403 originates from the Claude Code binary spawned by
@anthropic-ai/claude-agent-sdk, not from the action's JavaScript or the Anthropic SDK. The agent SDK's internal HTTP client appears to make API calls differently from the standard@anthropic-ai/sdk.The LiteLLM proxy requires
Authorization: Bearerorx-api-keyheaders. The standard SDK sendsx-api-keyand works. The agent SDK binary seems to either:api.anthropic.comdirectly (bypassingANTHROPIC_BASE_URL)ANTHROPIC_AUTH_TOKENfrom settings to its HTTP clientEnvironment
claude-code-action@v1ANTHROPIC_AUTH_TOKENin~/.claude/settings.json