Omniscio

OmniscioGuidesClaude Code on Bedrock or Vertex

Claude Code on Bedrock, Vertex or a gateway: how the provider is chosen

Claude Code has no provider setting you can flip in a session. It has environment variables, and the one that is set decides where every request goes: Amazon Bedrock, Google Cloud's Agent Platform, or an endpoint your organization runs. That sounds simple until a session on Bedrock starts answering from a different model, a corporate proxy rewrites a response, or a gateway quietly bills someone else. This page covers the setup itself, the numbers each provider resolves on its own, and the failures that only exist on a third-party provider.

Sources read October 27, 2026. By the Omniscio team. Updated .

Find the setup you are actually doing

Three of the routes reach a Claude model through something other than your own Claude subscription or Console key, and they are configured differently. Pick the one your organization chose: the three setup paths are separate, though a provider-format gateway borrows the provider's own switch. Anthropic also supports Microsoft Foundry and Claude Platform on AWS; they are outside this page's scope, and nothing below contradicts them.

If your request is not reaching a provider at all, this is the wrong page: a refused socket, a DNS failure or a certificate error is a network problem, and the connection errors guide covers that family with the fix for each code. This page starts at the point where the network works and the provider is the question.

Two other pages sit beside this one and own their own subject. A sign-in failure on a normal claude.ai account belongs to the login errors guide. Running several sessions at once is the multiple sessions guide. A model missing from the picker is a different question again, and this page only covers the provider half of it, below.

The variable that picks the provider

A session runs on whichever provider its environment selects: Bedrock is CLAUDE_CODE_USE_BEDROCK=1, Google Cloud's Agent Platform is CLAUDE_CODE_USE_VERTEX=1, and a generic gateway is ANTHROPIC_BASE_URL plus a credential. Anthropic's enterprise overview keeps the last one separate on purpose, because a gateway is a proxy in front of a provider rather than a provider itself.

Two of the three also want a location, and the location is not interchangeable. Bedrock resolves an AWS region, and Vertex resolves a Google Cloud location. On Vertex a model asked for in a location that does not serve it comes back as a model-not-found 404, so that is the error to read first if you have just changed region.

You are setting upRequiredAlso needs
Amazon BedrockCLAUDE_CODE_USE_BEDROCK=1AWS credentials from the default chain, and a region from AWS_REGION, your profile, or the default
Google Cloud's Agent PlatformCLAUDE_CODE_USE_VERTEX=1ANTHROPIC_VERTEX_PROJECT_ID and CLOUD_ML_REGION, plus Application Default Credentials
An LLM gateway, Anthropic formatANTHROPIC_BASE_URLA gateway credential in ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY
An LLM gateway, Bedrock or Vertex formatANTHROPIC_BEDROCK_BASE_URL or ANTHROPIC_VERTEX_BASE_URLThe matching CLAUDE_CODE_USE_* switch and the CLAUDE_CODE_SKIP_*_AUTH flag

Vertex AI is now Google Cloud's Agent Platform

Anthropic's documentation now calls it Google Cloud's Agent Platform, "formerly Vertex AI", while the login prompt still offers the old name, Google Vertex AI. The variable did not change and is still CLAUDE_CODE_USE_VERTEX, so a search result that says Agent Platform and a colleague who says Vertex are describing the same setup.

There is a wizard for the first two

Run claude, choose 3rd-party platform at the login prompt, then the provider. The wizard takes your credentials, asks for a region or project, checks which models the account can actually invoke, and writes its result into the env block of your user settings file, so nothing has to be exported by hand. Afterwards, /setup-bedrock or /setup-vertex reopens the same wizard to change credentials, region or model pins. On Bedrock that command is hidden from the command menu until CLAUDE_CODE_USE_BEDROCK=1 is set, so type it in full the first time.

Amazon Bedrock: region, credentials, and the model that actually answers

The manual setup is one switch, an optional region, and credentials. Enable the integration with CLAUDE_CODE_USE_BEDROCK=1, set AWS_REGION only if your profile has no region of its own, and let the SDK credential chain supply the rest. Also switch on the model in the Bedrock console first: the Model catalog holds a use case form, access is granted as soon as it is submitted, and until it is, requests for that model fail.

The region is resolved in a fixed order

Bedrock does not need a region variable in most setups, because Claude Code falls back through four sources and stops at the first usable one: AWS_REGION, then AWS_DEFAULT_REGION, then the region on your active AWS profile read from the shared credentials file and then the shared config file, then us-east-1. A value that is not shaped like a region, such as one containing a slash, a dot or a space, is treated as unset and the search continues. /status shows the region that won and, when it came from a config file or the default, says so.

How the credentials arrive, and the one way that skips the chain

Claude Code uses the default AWS SDK credential chain, so if the machine already supplies credentials to it — an EC2 instance profile, ECS task credentials, a role on the instance — there is nothing to configure here. Otherwise it is one of: aws configure writing a key to the default profile, access key environment variables (plus AWS_SESSION_TOKEN when they are temporary), an SSO profile after aws sso login, the browser sign-in from aws login on AWS CLI 2.32.0 or later, or an Amazon Bedrock API key. That last one is different: exported as AWS_BEARER_TOKEN_BEDROCK, it authenticates every request and stops Claude Code from resolving the chain at all, even when other AWS credentials are present. Short-term keys last up to 12 hours, long-term keys until an expiry you set.

The chain is resolved once and cached in memory, then reused until five minutes before the credentials expire, or for an hour when they carry no expiry. A credential error clears the cache and the next retry resolves fresh credentials, and CLAUDE_CODE_SKIP_AWS_CRED_CACHE=1 resolves the chain on every request instead.

The resolve itself has a 60-second ceiling, which is the number to raise if your chain legitimately needs a human: set CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS when an SSO or MFA wrapper such as aws-vault takes longer. The two settings also differ in when they run, and that difference decides which one you want. awsAuthRefresh runs only when Claude Code finds the credentials expired, and it checks with STS first so it does not run needlessly. awsCredentialExport runs at session start and on every reload, which is what you need when the right credentials differ from what the chain would resolve.

Pin the model, or you do not know which one you are paying for

Without a pin, the opus and sonnet aliases resolve to Claude Code's built-in default for Bedrock, which can trail the newest release and may not be enabled in your account. As Anthropic documents it today, that default is Opus 5.5 for the main model and Sonnet 4.5 for the small one, which matters more than it sounds: Opus carries the higher per-token price, so an unpinned deployment is billed at the Opus rate. Pin with ANTHROPIC_DEFAULT_OPUS_MODEL, ANTHROPIC_DEFAULT_SONNET_MODEL and ANTHROPIC_DEFAULT_HAIKU_MODEL. A Bedrock model ID is not the bare Anthropic name: it carries a prefix, so in a us-* region the Opus pin reads us.anthropic.claude-opus-5-5, and in AWS GovCloud the prefix is us-gov..

Two related settings are easy to confuse. ANTHROPIC_BEDROCK_REGION_PREFIX keeps the built-in default model and changes only the prefix it is called with, which is not the same as pinning a version; valid values are us, eu, apac, jp, au and global, and it needs v2.1.224 or later. If you need several versions of one family in the model picker, each pointed at its own application inference profile, that is modelOverrides in the settings file, not a second environment variable.

Background work such as naming a session is carried by the small/fast model, and on Bedrock that is the Sonnet default rather than a Haiku model, because Haiku may not be enabled in an account or region. Set ANTHROPIC_DEFAULT_HAIKU_MODEL to a model your account can invoke if you want those calls on Haiku; picking a main model with --model or ANTHROPIC_MODEL moves them onto that model instead.

The permissions and the one API it does not speak

The IAM policy Anthropic publishes grants bedrock:InvokeModel, bedrock:InvokeModelWithResponseStream, bedrock:ListInferenceProfiles and bedrock:GetInferenceProfile on inference profiles and foundation models, plus the two aws-marketplace actions that let the subscription happen through Bedrock. Claude Code calls the Bedrock Invoke API and does not support the Converse API, so an endpoint or library built around Converse is not a substitute. If a request fails with "on-demand throughput isn't supported", the model has to be named as an inference profile ID rather than a bare foundation model.

Guardrails and service tiers, briefly

A Bedrock Guardrail is attached with two headers in ANTHROPIC_CUSTOM_HEADERS, X-Amzn-Bedrock-GuardrailIdentifier and X-Amzn-Bedrock-GuardrailVersion, and it needs Cross-Region inference enabled if you use cross-region profiles. When a guardrail blocks partway through a reply, the text already streamed stays and the reply ends with the guardrail's own blocked message. Service tier is one variable, ANTHROPIC_BEDROCK_SERVICE_TIER, set to default, flex or priority, and availability varies by model and region.

Google Cloud's Agent Platform: project, location, and the rename

The Vertex side has one failure mode the Bedrock side does not, and it is a project mismatch. Claude Code addresses its requests to the project in ANTHROPIC_VERTEX_PROJECT_ID even when GCLOUD_PROJECT, GOOGLE_CLOUD_PROJECT or the credential file named by GOOGLE_APPLICATION_CREDENTIALS points somewhere else. So "my billing is on project B but the requests land in project A" is not a mystery: the variable wins, and the fix is to correct the variable.

Enable the API and request access once per project. gcloud services enable aiplatform.googleapis.com turns the API on, and the Model Garden is where you request access to individual Claude models; Anthropic notes the approval can take 24 to 48 hours, which is why a setup that looks correct can fail for a day. Assigning roles/aiplatform.user covers the permission that matters, aiplatform.endpoints.predict, and Anthropic suggests a dedicated project for cost tracking.

Then three variables: CLAUDE_CODE_USE_VERTEX=1, ANTHROPIC_VERTEX_PROJECT_ID, and CLOUD_ML_REGION. The region accepts a global endpoint, a multi-region location such as eu or us, or a specific region such as us-east5, and Claude Code picks the matching hostname for each form, including the aiplatform.eu.rep.googleapis.com hosts for multi-region. If a value is not shaped like a location it is treated as unset, and the fallbacks differ by variable: a VERTEX_REGION_CLAUDE_* value falls back to CLOUD_ML_REGION, and CLOUD_ML_REGION falls back to us-east5.

Model availability is not uniform across those three shapes. A model offered on a global endpoint and a model offered only in a region are different requests, which is what the per-model VERTEX_REGION_CLAUDE_* variables are for: with CLOUD_ML_REGION=global, you point the models that do not support global at a region of their own.

Authentication is Application Default Credentials, so gcloud auth application-default login or a service account key referenced by GOOGLE_APPLICATION_CREDENTIALS. For refresh, gcpAuthRefresh runs your command when the credentials are expired or cannot be loaded, checks first with a token request and skips the command when the check succeeds, and gives up after three minutes. It is worth knowing that a gcpAuthRefresh set in a project's .claude/settings.json runs under the same workspace-trust rule as hooks, including in -p runs in a folder you have never trusted.

Model pins work exactly as they do on Bedrock, with Vertex model IDs: ANTHROPIC_DEFAULT_OPUS_MODEL, ANTHROPIC_DEFAULT_SONNET_MODEL and ANTHROPIC_DEFAULT_HAIKU_MODEL, defaulting to claude-opus-5-5 and claude-sonnet-4-5@20250929 when unset. Prompt caching is on automatically, and /logout is unavailable on both cloud providers because the credential belongs to them.

Two errors carry most of the confusion here. A 404 that names the model is either a model not enabled in Model Garden or a location that does not serve it, since some models exist only on global or on a multi-region location. A 429 on a regional endpoint can mean the main or the small/fast model is not served there; check that, and your quota, or move to global for better availability.

A corporate gateway: the base URL, the credential, and the test

A gateway is a proxy your organization runs in front of a provider. Claude Code reaches one by base URL and authenticates with a credential the organization issues, and which variable holds that credential depends on what the gateway told you: ANTHROPIC_AUTH_TOKEN for a bearer token or an Authorization header, ANTHROPIC_API_KEY for an API key or x-api-key, and apiKeyHelper when the credential rotates or comes from a vault. Every gateway connection needs both the base URL and the credential, and the last paragraph of this section explains what happens when you have only one of them.

Where you put them decides who else sees them. A shell export lasts one terminal session and does not reach an editor launched from the dock or Start menu. The env block of a settings file persists, reaches background sessions, and wins when both are set. What you must not do is put a credential in a project's .claude/settings.json, because that file is committed and shared with everyone who clones the repository; the project-local file for secrets is .claude/settings.local.json, and even that ought to be in your gitignore before it holds a key.

Prove it before you open Claude Code

Send one cheap request straight at the gateway, so a failure points at the gateway rather than at your configuration. Run this with the values exported in your shell, even if you also put them in a settings file, because the command reads the shell variables.

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-sonnet-4-6", "max_tokens": 1, "messages": [{"role": "user", "content": "."}]}'

If that returned JSON, the gateway speaks the Anthropic Messages API and the rest of this paragraph does not apply to you. A gateway that serves a provider's own API format is configured differently: use the provider's base URL variable instead of ANTHROPIC_BASE_URL, keep the provider switch, and set the skip-auth flag. That is ANTHROPIC_BEDROCK_BASE_URL with CLAUDE_CODE_SKIP_BEDROCK_AUTH=1 and CLAUDE_CODE_USE_BEDROCK=1, or ANTHROPIC_VERTEX_BASE_URL with CLAUDE_CODE_SKIP_VERTEX_AUTH=1, the project, the region and CLAUDE_CODE_USE_VERTEX=1. The skip flag is what stops Claude Code signing requests with cloud credentials the gateway already holds, and leaving it out also removes an Authorization header you tried to add. A provider-format gateway is confirmed inside Claude Code rather than with the curl above: /status shows the provider, a Bedrock base URL or Vertex base URL row, and AWS auth skipped or GCP auth skipped.

One more variable earns its place in that shape: AWS_BEARER_TOKEN_BEDROCK. If it is set, Claude Code sends that Bedrock API key as the Authorization header instead of your gateway token, even with CLAUDE_CODE_SKIP_BEDROCK_AUTH=1. So on a Bedrock-format gateway, leave it unset.

A gateway credential displaces your claude.ai login while it is active. Requests carry the gateway's credential instead, the subscription's usage limits do not apply to them, and the tokens are billed to whoever owns the credential the gateway forwards. Setting ANTHROPIC_BASE_URL alone does not do this: the URL routes traffic, but a saved login stays the active credential, so its limits and billing still apply.

The errors that mean something else on a cloud provider

Four messages read like generic API errors and are not. Three of them are local to the machine or the proxy, so no request reached a model; the content-type one comes back from a model that did answer, in a shape Claude Code refused.

  • Could not load AWS credentials or Could not load Google Cloud credentials, followed by a detail after the middle dot. The chain produced nothing usable: an expired SSO session, missing application default credentials reported as Could not load the default credentials, or a revoked sign-in reported as invalid_grant. In a -p run or the Agent SDK the structured code is cloud_credential_error.
  • AWS default-chain credential resolve timed out, which on a current build arrives as the detail after the dot in the line above. The chain hung rather than failed, and the resolve is capped at 60 seconds. A credential_process helper waiting for input it cannot receive, or a container whose instance metadata service never answers, are the usual causes. Raise the ceiling with CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS only when the helper genuinely needs longer.
  • Bedrock streaming response has content-type "text/event-stream". A gateway is rewriting the response header. Bedrock streams in a binary event-stream format, so Claude Code refuses a body it cannot read and does not retry. Fix the gateway. CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD=1 hides the error while you do, but those requests then run on the slower non-streaming path. A gateway that only drops the header is a different case: Claude Code assumes the body is Bedrock's event stream and keeps streaming, unless that gateway also re-emits the stream as server-sent events, and then CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_DEFAULT=1 is the setting.
  • A 400 naming an unknown field, on every request. The gateway is validating a request body against something older than Claude Code sends. CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 suppresses most pre-release fields; a field it does not cover needs the provider-specific switch instead, so Claude Code sends only what that provider accepts.

Two more shapes are worth naming because they look the same and are not. A 400 that names a tool type is tied to a Claude Code version — an artifact schema on 2.1.265 through 2.1.267, an advisor entry on 2.1.275 — and the fix is to update, or to turn that feature off on the affected version. And a gateway that converts the stream to server-sent events is no longer serving the Bedrock API at all: if it also accepts Anthropic Messages requests, connect to it as an LLM gateway with ANTHROPIC_BASE_URL instead of the Bedrock switch.

One more belongs to a different page: the certificate failure. On Bedrock it is worth one extra sentence, because the configuration has to reach both paths: Claude Code applies your CA store to the requests it makes to AWS, including model discovery, token counting and the STS and SSO calls behind credential resolution, so a TLS-inspecting proxy needs the same fix there as everywhere else. The connection errors guide has the fix and the NODE_EXTRA_CA_CERTS detail. Two open reports are worth reading beside this: issue 103680, a certificate regression on 2.1.304 where custom CAs were loaded but not used, and issue 103218, a request for opt-in gzip request bodies on Bedrock, Vertex and custom base URLs.

What works on the Anthropic API and does not work here

A missing feature on a cloud provider looks like a bug or a slow model rather than a provider decision, which is why this section is worth reading before a rollout rather than after it. Anthropic publishes a per-provider availability table, and on both cloud providers the list starts with everything that requires a Claude subscription.

On Amazon Bedrock, Anthropic lists these as not available: web search, fast mode, the Advisor tool, Channels, the analytics dashboard, server-managed settings, and the /design-sync and /import commands. For a web lookup the documented alternative is the WebFetch tool with a specific URL; for scheduling it is /loop rather than /schedule; for cloud sessions it is GitHub Actions or GitLab CI/CD.

On Google Cloud's Agent Platform the list is the same except for web search, which works there on Claude Opus 4, Sonnet 4, Haiku 4.5 and later. Auto mode is partial on both: Anthropic supports it only on Sonnet 5 or later, Opus 4.7 or later, Haiku 5.5 and the Fable models. Cross-session messaging is limited to the machine you are on, and Zero Data Retention follows your cloud agreement rather than Anthropic's.

Two quieter differences are worth carrying into a rollout plan. Error reporting and telemetry to Anthropic are off by default on these providers, so the diagnostics you get are the provider's. And an alias can resolve to a version older than the newest release, which is why a team that reads about a new model does not see it in /model. Pinning, above, is the fix.

Four lines that prove the setup before you debug it

Start a session and run /status. One command reports which provider, base URL, project, region and model a session is actually using.

  • On Bedrock, the provider line names the provider and the region line shows the resolved region, noting when it came from your AWS config files or the default. If the provider line is missing, the variables are not reaching the process.
  • On Google Cloud's Agent Platform, the API provider line shows Google Vertex AI, and the project, default region and model lines show your resolved values.
  • Through a gateway, the Anthropic base URL line appears only when a gateway address is set, and an Auth token or API key line names the variable that is active. A line naming a claude.ai account instead means no gateway credential was found.
  • If the lines look right and the request still fails, the problem is past the configuration, and the error text from the section above is the next thing to read.

Omniscio and provider setup

Omniscio is the desktop app we make for running many Claude Code sessions at once. There is no Bedrock or Vertex setup in it: no wizard, no provider entry, no field for a project, a region or an AWS profile. This page is not selling one, and nothing in the app writes those two switches: it starts the same claude command, so an organization on Bedrock configures this where it configures every other Claude Code install.

There is one honest tie, and it is the gateway half of this page. The app has Custom Providers, where you add a name, a base URL, an API key and the model ids it serves, in either an OpenAI-compatible or an Anthropic-compatible format. An Anthropic-compatible entry is handed to the session as ANTHROPIC_BASE_URL plus ANTHROPIC_AUTH_TOKEN, which is the same pair a corporate gateway wants. So a gateway that speaks the Anthropic Messages API is something you can add there and then pick per session.

One warning if you set the gateway up the way the section above describes and then use it from this app. A session Omniscio starts does not inherit ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY from your shell: the app removes the ambient copies before it spawns the CLI, so an exported gateway credential never reaches the session. The session then runs on whatever provider it would have used anyway: the credential the app gives it for the account you chose, or your own claude login if you run the app on that setting, or a CLAUDE_CODE_USE_BEDROCK or CLAUDE_CODE_USE_VERTEX switch already set on the machine, which the app leaves in place. Put the gateway in Custom Providers, or in the env block of your settings file, which the CLI reads itself.

What that is not: Bedrock and Vertex themselves. Those two are reached by their own switches and their own cloud credentials, not by a base URL and a key, and the app has no entry for either. If your organization runs on Bedrock, the setup stays in the CLI's environment and settings, with one exception: on an SSH remote that borrows the desktop account pool, the launch clears both cloud-provider switches on that machine before it starts, because they would outrank the pooled credential.

If you are comparing ways to run several sessions at once, the features page lists what the app does and the download page has the installers.

Sources

Every variable, number and message on this page rests on one of these. The date beside each is the day we read it.

  • Claude Code on Amazon Bedrock, for the wizard, the manual variables, the region order, the credential chain and its cache, awsAuthRefresh and awsCredentialExport, model pins and prefixes, the IAM policy, Guardrails, service tiers, and the certificate and streaming notes. Read October 27, 2026.
  • Claude Code on Google Cloud's Agent Platform, for the rename, the project rule, the location forms and fallbacks, Model Garden access, gcpAuthRefresh, model pins, and the 404 and 429 guidance. Read October 27, 2026.
  • Enterprise deployment overview, for the provider comparison and for keeping a gateway separate from a provider. Read October 27, 2026.
  • Other LLM gateways, for what a gateway provides, the subscription and billing rule, and the provider-specific base URL variables. Read October 27, 2026.
  • Connect Claude Code to an LLM gateway, for the credential table, the settings-file rule, the curl test, the cloud-provider blocks, and the gateway troubleshooting table. Read October 27, 2026.
  • Feature availability, for what is unavailable or partial on each provider. Read October 27, 2026.
  • Errors, for the credential, resolve-timeout and content-type messages, quoted from the reference. Read October 27, 2026.
  • GitHub issue 103680, open, for the reported certificate regression on 2.1.304. Read October 27, 2026.
  • GitHub issue 103218, open, for the request for opt-in gzip request bodies on Bedrock, Vertex and custom base URLs. Read October 27, 2026.
  • One capture run on this machine on October 27, 2026: claude --version, which printed 2.1.311 (Claude Code).

This part of the product moves with every release: the provider pages carry version notes on the region prefix, the pinning defaults and the certificate handling, so a copy of this page from a few months back is worth re-reading against the live pages.

Common questions

Which variable switches Claude Code to Bedrock or Vertex?

CLAUDE_CODE_USE_BEDROCK=1 for Amazon Bedrock, and CLAUDE_CODE_USE_VERTEX=1 for Google Cloud's Agent Platform, which is the service still called Vertex AI in the login prompt. A gateway is a different switch: ANTHROPIC_BASE_URL points Claude Code at an endpoint that speaks the Anthropic Messages API, and a provider-format gateway uses ANTHROPIC_BEDROCK_BASE_URL or ANTHROPIC_VERTEX_BASE_URL together with the matching provider switch.

Why does Claude Code say it cannot load my AWS or Google credentials?

Because the credential chain produced nothing usable on that machine, so no request reached the provider. On AWS the usual cause is an expired SSO session. On Google Cloud it is usually missing application default credentials, fixed by running gcloud auth application-default login. If the detail after the dot reads AWS default-chain credential resolve timed out, the chain hung rather than failed, usually on a credential_process helper waiting for input it cannot receive, and it gave up at the 60-second resolve ceiling.

Why did WebSearch stop working after switching to Bedrock?

Because Anthropic lists web search as not available on Amazon Bedrock, along with fast mode, the Advisor tool, Channels, the analytics dashboard, server-managed settings, and the /design-sync and /import commands. On Google Cloud's Agent Platform web search works only on Claude Opus 4, Sonnet 4, Haiku 4.5 and later. WebFetch is the documented alternative for a specific URL.

Can I set the Bedrock or Vertex variables in a settings file instead of my shell?

Yes. Both setup wizards write what they collect to the env block of your user settings file, which is ~/.claude/settings.json or $CLAUDE_CONFIG_DIR/settings.json. When a shell export and a settings file set the same variable, the settings file wins, and a settings file is also what reaches background agents that a shell export does not. Keep a credential out of a project's .claude/settings.json, which is committed and shared.