Configure an LLM gateway for Claude Code
Claude Code sends model traffic to api.anthropic.com unless environment variables route it elsewhere: to Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, Claude Platform on AWS, or an LLM gateway through ANTHROPIC_BASE_URL. A gateway needs a gateway credential as well; with only the base URL set, a saved claude.ai login still pays for every request.
This page is for the developer who has to connect to the route their company chose, and for the tech lead or platform engineer who rolls that route out to a team. Security approved Claude Code on one condition: no developer laptop calls Anthropic directly, and every token is billed to the company’s AWS account with a name attached. You have the gateway URL, a Bedrock account, and forty developers who are already signed in with personal subscriptions.
What you’ll walk away with from gateway routing
Section titled “What you’ll walk away with from gateway routing”- A decision table for choosing between a cloud provider, Anthropic’s Claude apps gateway, and a gateway you already run
- Working configuration for each cloud provider and for any Anthropic-format gateway, including LiteLLM
- A managed-settings block that routes the whole team without anyone editing a shell profile
- A verification routine that proves each session uses the route, without inspecting every laptop
- A failure table for the errors gateway routing produces, with the fix for each
Every variable, command and error string on this page was checked against the Claude Code documentation and the installed CLI, version 2.1.283, on 2026-09-26. Which route your organization should use for data residency and zero data retention is a separate decision: see where the model runs.
Which route should you choose?
Section titled “Which route should you choose?”A cloud provider changes who serves the model. A gateway changes who holds the credential. You can combine both: a gateway in front of Amazon Bedrock is a common pattern.
| Route | How Claude Code reaches it | Pick it when | What it costs you |
|---|---|---|---|
| Cloud provider, direct | CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX, CLAUDE_CODE_USE_FOUNDRY or CLAUDE_CODE_USE_ANTHROPIC_AWS, plus the provider’s own credentials | Billing and data must stay in your cloud account, and each developer already has cloud credentials | Per-developer cloud IAM, provider-specific model IDs, and model defaults that differ per provider |
| Claude apps gateway | claude gateway --config gateway.yaml on a Linux server; developers sign in with /login through your OIDC identity provider | You want SSO sign-in, model allowlists and managed settings per IdP group, and OTLP usage metrics without running a third-party product | A PostgreSQL database, a private-network hostname, and no service-token sign-in, so CI connects to the provider directly |
| Your own gateway (LiteLLM, Kong, an internal proxy) | ANTHROPIC_BASE_URL plus ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY or apiKeyHelper | The organization already runs one for other LLM traffic and wants one budget and audit log | The gateway must forward every header and request field each new Claude Code release sends, or features break |
Every route turns off some features, so check them before you commit:
- The claude.ai subscription stops paying. While a gateway credential or
apiKeyHelperis active, requests bill per token to whoever owns the credential the gateway forwards. - Remote Control and voice dictation stop working. Both need a claude.ai identity. Remote Control is also off whenever
ANTHROPIC_BASE_URLpoints at a non-Anthropic host. - Slack and cloud sessions bypass the route. They always use Anthropic’s API and ignore gateway variables, so do not enable them for users whose traffic must stay on the gateway.
- WebSearch disappears on Amazon Bedrock and on Claude apps gateway sessions.
Route Claude Code to a cloud provider
Section titled “Route Claude Code to a cloud provider”Each provider has its own switch variable and credential chain. Amazon Bedrock and Google Cloud also have a setup wizard: run /setup-bedrock or /setup-vertex in a session, and it writes the result to the env block of ~/.claude/settings.json.
Submit the Anthropic use-case form once per account in the Bedrock model catalog, then give each developer’s role this policy:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowModelAndInferenceProfileAccess", "Effect": "Allow", "Action": [ "bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream", "bedrock:ListInferenceProfiles", "bedrock:GetInferenceProfile" ], "Resource": [ "arn:aws:bedrock:*:*:inference-profile/*", "arn:aws:bedrock:*:*:application-inference-profile/*", "arn:aws:bedrock:*:*:foundation-model/*" ] } ]}The official policy adds an aws-marketplace statement for first-time model subscription; keep it on the account that subscribes. Then, in the terminal:
export CLAUDE_CODE_USE_BEDROCK=1export AWS_PROFILE=bedrock-dev # SSO profile; the standard AWS credential chain appliesexport AWS_REGION=us-east-1 # optional when the profile sets a regionexport ANTHROPIC_DEFAULT_OPUS_MODEL='us.anthropic.claude-opus-5-5'export ANTHROPIC_DEFAULT_HAIKU_MODEL='us.anthropic.claude-haiku-4-5-20251001-v1:0'claudeClaude Code resolves models to cross-region inference profiles (us., eu., apac., or global., chosen from your region). Set ANTHROPIC_BEDROCK_REGION_PREFIX=global to prefer global profiles. The Mantle endpoint, which serves the Anthropic Messages format on Bedrock, is a separate switch (CLAUDE_CODE_USE_MANTLE=1) with its own bedrock-mantle: IAM actions and model IDs such as anthropic.claude-sonnet-5.
Google Cloud’s Agent Platform (formerly Vertex AI) keeps the VERTEX spelling in its variables. Grant roles/aiplatform.user, enable the Claude models in Model Garden, then run:
gcloud services enable aiplatform.googleapis.comgcloud auth application-default login
export CLAUDE_CODE_USE_VERTEX=1export CLOUD_ML_REGION=globalexport ANTHROPIC_VERTEX_PROJECT_ID=acme-ai-prodexport ANTHROPIC_DEFAULT_OPUS_MODEL='claude-opus-5-5'export ANTHROPIC_DEFAULT_HAIKU_MODEL='claude-haiku-4-5@20251001'claudeNot every model is served on the global endpoint. For a model that is not, set a per-model region such as VERTEX_REGION_CLAUDE_HAIKU_4_5=us-east5. In CI, use workload identity federation instead of a service-account key file.
Deploy the Claude models in your Foundry resource first; the model variables must match those deployment names, because Foundry has no startup model check.
export CLAUDE_CODE_USE_FOUNDRY=1export ANTHROPIC_FOUNDRY_RESOURCE=acme-foundry # your Azure resource nameexport ANTHROPIC_DEFAULT_OPUS_MODEL='claude-opus-5-5'export ANTHROPIC_DEFAULT_SONNET_MODEL='claude-sonnet-5'claudeWith neither ANTHROPIC_FOUNDRY_API_KEY nor ANTHROPIC_FOUNDRY_AUTH_TOKEN set, Claude Code uses the Azure default credential chain, so a developer signed in with az login needs no key. Pin models here: an unpinned Foundry session defaults to Sonnet 4.5, its opus alias resolves to Opus 4.6, and a Sonnet 4.5 session starts in Manual permission mode because auto mode does not support that model.
Claude Platform on AWS is the Anthropic-operated API with AWS authentication and AWS Marketplace billing. The Marketplace subscription creates a new Anthropic organization, separate from any you already have, so use the workspace ID and keys from that organization.
export CLAUDE_CODE_USE_ANTHROPIC_AWS=1export ANTHROPIC_AWS_WORKSPACE_ID=wrkspc_01ABCDEFGHIJKLMNexport AWS_REGION=us-east-1claudeClaude Code signs requests with SigV4 through the standard AWS credential chain; a workspace API key in ANTHROPIC_AWS_API_KEY is the alternative. Bedrock and Foundry take precedence in routing, so unset CLAUDE_CODE_USE_BEDROCK and CLAUDE_CODE_USE_FOUNDRY first.
Pin models on every provider before a team rollout. Aliases such as opus and sonnet resolve to defaults built into each Claude Code version, and those defaults differ per provider: on Bedrock and Google Cloud the sonnet alias is Sonnet 4.5 unless you set ANTHROPIC_DEFAULT_SONNET_MODEL. Opus 5.5 needs Claude Code v2.1.280 or later; the stable release channel was still on 2.1.274 on 2026-09-26, where the Bedrock and Google Cloud default is Opus 5. Current model IDs and prices live on the models hub.
Connect Claude Code to an LLM gateway
Section titled “Connect Claude Code to an LLM gateway”Any gateway that accepts the Anthropic Messages API at POST /v1/messages works. Ask the gateway team for two things: the base URL and a credential. The base URL is the host, without /v1; Claude Code appends the path itself.
-
Test the gateway before Claude Code touches it. A one-token request isolates gateway problems from configuration problems:
Terminal window export ANTHROPIC_BASE_URL=https://llm-gateway.internal.example.comexport ANTHROPIC_AUTH_TOKEN="$(vault kv get -field=api_key secret/llm-gateway/claude-code)"curl -sS -w '\n%{http_code}\n' -X POST "$ANTHROPIC_BASE_URL/v1/messages" \-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \-H "anthropic-version: 2023-06-01" \-H "content-type: application/json" \-d '{"model": "claude-opus-5-5", "max_tokens": 1, "messages": [{"role": "user", "content": "."}]}'A body starting with
{"id":"msg_means the route works. An unknown-model error still proves the URL and credential; a401means the gateway reads a different header. -
Pick the credential variable by the header the gateway reads.
ANTHROPIC_AUTH_TOKENis sent asAuthorization: Bearer,ANTHROPIC_API_KEYasx-api-key, and anapiKeyHelpercommand’s output as both. When nobody told you which, start withANTHROPIC_AUTH_TOKENand switch on a401. AnANTHROPIC_API_KEYneeds a one-time approval in an interactive session. -
Start
claudefrom the same shell and run/status. The Status tab must show anAnthropic base URLline with the gateway address and anAuth tokenorAPI keyline naming your variable. ALogin methodline naming a claude.ai account means the subscription is still paying. -
Persist the values in the
envblock of~/.claude/settings.json, not only in your shell. Background agents hosted by the supervisor do not reliably inherit shell exports, and a settings-file value wins over a shell export. Never put the credential in a project’s.claude/settings.json, which is committed.
To fetch a rotating credential instead of storing one, point apiKeyHelper at a script that prints only the key. Claude Code caches the output for five minutes; set CLAUDE_CODE_API_KEY_HELPER_TTL_MS to change that. From v2.1.227, any extra line the script prints, such as a banner, makes the helper fail.
{ "apiKeyHelper": "~/bin/get-gateway-key.sh", "env": { "ANTHROPIC_BASE_URL": "https://llm-gateway.internal.example.com", "ANTHROPIC_CUSTOM_HEADERS": "X-Team: payments", "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1" }}ANTHROPIC_CUSTOM_HEADERS adds routing or tenant headers (separate pairs with \n). Model discovery adds the gateway’s /v1/models list to the /model picker.
Run LiteLLM as the gateway
Section titled “Run LiteLLM as the gateway”LiteLLM is an open-source gateway with virtual keys, budgets, and request logging (★59.6k on GitHub and version 1.102.1 on PyPI, both read 2026-09-26). Anthropic does not endorse or audit it. On 2026-03-24, PyPI versions 1.82.7 and 1.82.8 shipped a credential stealer; both have been removed, so always install a pinned version:
uv tool install 'litellm[proxy]==1.102.1'Keep provider keys out of the file: the os.environ/ prefix tells LiteLLM to read a value from the environment. Name each route after the model ID Claude Code requests.
model_list: - model_name: claude-opus-5-5 litellm_params: model: anthropic/claude-opus-5-5 api_key: os.environ/ANTHROPIC_API_KEY - model_name: claude-haiku-4-5 litellm_params: model: anthropic/claude-haiku-4-5 api_key: os.environ/ANTHROPIC_API_KEY
general_settings: master_key: os.environ/LITELLM_MASTER_KEY database_url: os.environ/LITELLM_DATABASE_URL # needed for per-developer virtual keyslitellm --config litellm_config.yaml --port 4000Developers then set ANTHROPIC_BASE_URL to the proxy and ANTHROPIC_AUTH_TOKEN to their own LiteLLM virtual key, never the master key. Set ANTHROPIC_DEFAULT_HAIKU_MODEL=claude-haiku-4-5 on the client so background calls ask for a name the proxy routes. The individual-developer side of LiteLLM, Claude Code Router and local models is covered in gateways and local models.
Route a gateway to a cloud provider
Section titled “Route a gateway to a cloud provider”When the gateway exposes a provider’s native format instead of the Anthropic one, use that provider’s base URL variable and tell Claude Code not to sign requests, because the gateway holds the cloud credential:
export CLAUDE_CODE_USE_BEDROCK=1export ANTHROPIC_BEDROCK_BASE_URL=https://llm-gateway.internal.example.com/bedrockexport CLAUDE_CODE_SKIP_BEDROCK_AUTH=1export ANTHROPIC_AUTH_TOKEN="$GATEWAY_TOKEN" # only if the gateway wants its own tokenThe equivalents are ANTHROPIC_VERTEX_BASE_URL with CLAUDE_CODE_SKIP_VERTEX_AUTH, ANTHROPIC_BEDROCK_MANTLE_BASE_URL with CLAUDE_CODE_SKIP_MANTLE_AUTH, ANTHROPIC_AWS_BASE_URL for Claude Platform on AWS, and ANTHROPIC_FOUNDRY_BASE_URL with ANTHROPIC_FOUNDRY_API_KEY. Leave AWS_BEARER_TOKEN_BEDROCK unset: if it is set, it replaces your gateway token even with auth skipped.
Roll the route out to the whole team
Section titled “Roll the route out to the whole team”Developers should configure nothing. Deliver the route in the env block of the managed settings file (/etc/claude-code/managed-settings.json on Linux, /Library/Application Support/ClaudeCode/managed-settings.json on macOS, C:\Program Files\ClaudeCode\managed-settings.json on Windows) and let an apiKeyHelper fetch each developer’s own key:
{ "env": { "ANTHROPIC_BASE_URL": "https://llm-gateway.internal.example.com", "ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-5-5", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-4-5", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" }, "apiKeyHelper": "/usr/local/bin/get-gateway-key"}A managed ANTHROPIC_BASE_URL cannot be overridden by a developer’s shell export. Four rules keep the rollout from locking people out:
- Never add
forceLoginMethodorforceLoginOrgUUIDnext to a gateway credential. Either key blocksANTHROPIC_API_KEY,ANTHROPIC_AUTH_TOKENandapiKeyHelperat startup. - Use the file, not server-managed settings. Server-managed settings need a direct connection to
api.anthropic.com, so they never reach gateway-routed sessions. - Plan for
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC. It turns off auto-updates and the fast-mode check, so ship updates through your package manager. The WebFetch safety check still callsapi.anthropic.comunless you also setskipWebFetchPreflight: true. - Test each Claude Code release against the gateway first. New releases send new
anthropic-betavalues and body fields, and a gateway that allowlists them returns400. Hold the fleet on a tested version withrequiredMaximumVersionuntil the canary passes.
Two surfaces need their own delivery. The VS Code extension checks the credential in claudeCode.environmentVariables before it launches, and the desktop app reads its third-party inference configuration instead of ANTHROPIC_BASE_URL, so push both through MDM alongside the managed file. For the policy that surrounds the route, deny rules, telemetry and a managed CLAUDE.md, follow enterprise integration.
For the Claude apps gateway, the managed file carries the sign-in instead of a credential: "forceLoginMethod": "gateway" and "forceLoginGatewayUrl": "https://claude-gateway.internal.example.com". The gateway runs from the same binary (claude gateway --config gateway.yaml, v2.1.195 or later), only on a hostname that resolves to private addresses.
How do you prove every session takes the route?
Section titled “How do you prove every session takes the route?”A route you cannot observe is a policy on paper. Four checks give the platform owner, who signs off on the rollout, evidence without reading anyone’s configuration by hand:
- Canary check. On one machine per OS image, run
claude, then/status: theSetting sourcesline must include managed settings,Anthropic base URLmust show the gateway, and the credential line must name the helper or variable. For a cloud provider, the provider line shows it, for exampleAmazon Bedrock (Mantle). - Egress test. On the canary, block
api.anthropic.comat the firewall and ask Claude Code a question. An answer proves model traffic does not go direct. An error means some request still does, and/statusshows which base URL the session used. Ignore fast-mode and WebFetch preflight errors (both callapi.anthropic.comby design unless disabled); only a failed model answer counts. - Routing check per model name. Run the one-token
curlrequest above for every model name the gateway routes. A name the gateway does not route returns an error to the first developer who selects it. - Gateway-side attribution. The gateway’s usage log must show one key per developer and no traffic under a shared key; the
x-claude-code-session-idrequest header groups each developer’s requests by session, so you can trace one session end to end. The Claude apps gateway exports OTLP metrics with user identity; for other gateways, compare spend per key with cost control and the agent cost-tracking tools.
Run checks 1 and 3 in CI against every new Claude Code version before it reaches developers.
Copy-paste prompts for gateway setup
Section titled “Copy-paste prompts for gateway setup”When gateway routing breaks
Section titled “When gateway routing breaks”| Symptom | Cause | Recovery |
|---|---|---|
| Usage still counts against personal subscriptions | Only ANTHROPIC_BASE_URL is set, so the claude.ai login stays the active credential | Add ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY or apiKeyHelper; run /logout to drop the saved login |
401 naming an invalid token | The credential is in a header the gateway does not read, or it was revoked | Switch between ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY; regenerate the key at the gateway |
Login screen appears although the curl test succeeds | The credential sits in a project settings file, which applies only after the first-run wizard and the folder trust prompt | Set it in a shell export, ~/.claude/settings.json or managed settings |
This machine's managed settings require a first-party login | Managed settings contain forceLoginMethod or forceLoginOrgUUID | Remove those keys, or drop the gateway credential; the two cannot coexist |
400 naming context_management or Extra inputs are not permitted | The upstream rejects fields Claude Code sends to Anthropic-format endpoints | Set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1, then fix the gateway to forward fields verbatim |
400 with the gateway’s own context-limit message | The gateway enforces a smaller window and rewrites the error, so Claude Code does not compact | Run /compact; set CLAUDE_CODE_AUTO_COMPACT_WINDOW to the gateway’s limit (minimum 100,000) |
403 with an HTML body and nothing in the gateway log | A web application firewall blocks prompts that contain XML-style tags and source code | Exempt /v1/messages from body inspection (on AWS WAF, the CrossSiteScripting_Body rule) |
Bedrock streaming response has content-type | The gateway rewrote Bedrock’s event-stream Content-Type | Forward the response body and Content-Type unmodified |
Bedrock: on-demand throughput isn't supported | A bare model ID was used where an inference profile is required | Use an inference-profile ID such as us.anthropic.claude-opus-5-5 |
Google Cloud: 404 model not found | The model is not enabled, or not served in CLOUD_ML_REGION | Enable it in Model Garden; set a VERTEX_REGION_CLAUDE_* override |
TLS errors while curl succeeds | A TLS-inspecting proxy’s CA is unknown to Claude Code | Set NODE_EXTRA_CA_CERTS; see proxy configuration |
| The provider bill jumps after an upgrade | An unpinned deployment moved to a new Opus default | Pin ANTHROPIC_MODEL or the ANTHROPIC_DEFAULT_*_MODEL variables, then review cost governance |
If Remote Control is unavailable, that is expected on every gateway and cloud route: claude doctor names what blocks it, and channels and Remote Control covers the alternatives.
Where to go next with gateway routing
Section titled “Where to go next with gateway routing”- Where the model runs: the CTO’s decision on residency, zero data retention and routes, which this page implements.
- Proxy and VPN configuration: the corporate proxy and certificates that sit in front of the gateway.
- Enterprise integration: the managed policy that ships alongside the route.
- One policy for every coding agent: the same controls for Codex and Cursor.
- Monitoring Claude Code: OpenTelemetry metrics that confirm usage per developer.