Skip to content

Amazon Bedrock

Run Claude Code against Claude models in your own AWS account: the setup wizard, credentials, model pinning, IAM, inference profiles, Mantle and troubleshooting.

If your organisation already runs on AWS, Bedrock lets Claude Code use Claude models billed through your AWS account and governed by IAM and CloudTrail. You lose the claude.ai-only features (see feature availability), but everything in the local CLI works.

There are two ways in. Individuals with AWS credentials can use the login wizard. Teams rolling Claude Code out at scale, or CI pipelines, should use the manual setup with environment variables and pinned models.

Before you start

  • An AWS account with Bedrock enabled and access to the Claude models you want.
  • IAM permissions (see IAM).
  • Some way of getting AWS credentials. The AWS CLI is the usual one, but an instance profile, ECS task role or Bedrock API key works too.

The quick route: the login wizard

  1. Enable Anthropic models once per AWS account. In the Bedrock console, open the Model catalogue, pick an Anthropic model and submit the use case form. Access is granted straight away.
  2. Start the wizard. Run claude, choose 3rd-party platform, then Amazon Bedrock. If you are already signed in, type /setup-bedrock in full; it is hidden from the command menu until CLAUDE_CODE_USE_BEDROCK=1 is set.
  3. Answer the prompts. Pick how you authenticate (an AWS profile it found in ~/.aws, a Bedrock API key, an access key and secret, or credentials already in the environment), choose a region, and let it check which models you can call and pin them.

The wizard saves everything to the env block of ~/.claude/settings.json (or $CLAUDE_CONFIG_DIR/settings.json), so you never need to export variables yourself. Rerun /setup-bedrock whenever you want to change credentials, region or model pins.

The manual route

1. Submit the use case form

Do this once per AWS account before the first call, through the Bedrock console Model catalogue. With AWS Organizations you can do it once from the management account through the PutUseCaseForModelAccess API (needs bedrock:PutUseCaseForModelAccess), and child accounts inherit approval.

2. Provide AWS credentials

Claude Code uses the standard AWS SDK credential chain. If the machine already has credentials in that chain (EC2 instance profile, ECS task role), skip ahead. Otherwise pick one:

MethodHowNotes
Shared profileaws configureStores an IAM user's key in ~/.aws/credentials. AWS discourages long-lived user keys for real work.
EnvironmentAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, plus AWS_SESSION_TOKEN for temporary credentialsCurrent shell only
IAM Identity Centeraws configure sso, then aws sso login --profile <name> and export AWS_PROFILE=<name>Role credentials come from the profile's sso_region, which can differ from your Bedrock region
Console sign-inaws login (AWS CLI 2.32.0+)Browser sign-in, valid up to 12 hours
Bedrock API keyexport AWS_BEARER_TOKEN_BEDROCK=...Bypasses the credential chain entirely. Short-term keys last up to 12 hours; long-term keys are for experimentation.

Caching. From v2.1.207, Claude Code resolves the chain once and keeps the result until five minutes before expiry (or an hour if there is no expiry). A credential error from the API clears the cache. Set CLAUDE_CODE_SKIP_AWS_CRED_CACHE=1 to resolve on every request. Resolution times out after 60 seconds with AWS default-chain credential resolve timed out; if your chain legitimately needs longer (say aws-vault with browser MFA), raise CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS. The wizard applies the same limit and reports Timed out after 60s waiting for AWS.

Refreshing credentials automatically

Two settings plug Claude Code into your SSO or credential tooling:

SettingWhen it runsUse it for
awsAuthRefreshOnly when credentials look expired (by timestamp or an API credential error), after an STS GetCallerIdentity check confirms they really areCommands that update ~/.aws, such as an SSO login. Output is shown; no interactive input.
awsCredentialExportAt session start and each credential reload, even if the chain has valid credentialsReturning credentials directly when you cannot touch ~/.aws, or need cross-account credentials. Output is silent.
{
  "awsAuthRefresh": "aws sso login --profile platform-dev",
  "env": { "AWS_PROFILE": "platform-dev" }
}

awsCredentialExport must print JSON with a Credentials object holding AccessKeyId, SecretAccessKey, SessionToken and optionally Expiration (ISO 8601). The flat output of aws configure export-credentials --format process is accepted too. With an expiry, credentials are cached until five minutes before it; without, for an hour. From v2.1.206, using awsCredentialExport without awsAuthRefresh means the default chain is not consulted at startup. Since v2.1.239 the STS check honours HTTPS_PROXY and NO_PROXY.

3. Point Claude Code at Bedrock

export CLAUDE_CODE_USE_BEDROCK=1
export AWS_REGION=eu-west-2          # only if your profile lacks a region or you want to override it

# optional
export ANTHROPIC_SMALL_FAST_MODEL_AWS_REGION=eu-west-1   # needs ANTHROPIC_DEFAULT_HAIKU_MODEL to have an effect
export ANTHROPIC_BEDROCK_BASE_URL=https://bedrock-gw.example.internal

Region resolution order: AWS_REGION, then AWS_DEFAULT_REGION, then the active profile's region (credentials file first, then config file), then us-east-1. Values that do not look like a region (containing a slash, dot or space) are skipped. The active profile is AWS_PROFILE or default; AWS_SHARED_CREDENTIALS_FILE and AWS_CONFIG_FILE move the files. /status shows the resolved region and where it came from.

Also worth knowing: /logout does nothing on Bedrock, web search is unavailable, and putting AWS_PROFILE in a settings file keeps it out of other processes' environments.

4. Pin your models

Warning: Pin model versions before rolling out to a team. Unpinned aliases resolve to Claude Code's built-in Bedrock defaults, which can trail the newest release or point at models your account has not enabled. Claude Code will fall back at startup, but pinning lets you decide when people move.

Unpinned, opus resolves to Opus 5.5 and sonnet to Sonnet 4.5. A pinned setup looks like this:

export ANTHROPIC_DEFAULT_OPUS_MODEL='eu.anthropic.claude-opus-4-8'
export ANTHROPIC_DEFAULT_SONNET_MODEL='eu.anthropic.claude-sonnet-4-6'
export ANTHROPIC_DEFAULT_HAIKU_MODEL='eu.anthropic.claude-haiku-4-5-20251001-v1:0'

Those use the eu. cross-region inference profile prefix; use whichever prefix (or application inference profile) fits your account, and us-gov. in GovCloud. If you only want to change the prefix of the built-in defaults, set ANTHROPIC_BEDROCK_REGION_PREFIX instead of pinning (see below).

Default when nothing is pinnedExample in a us-* region
Primary model: Opus 5.5us.anthropic.claude-opus-5-5
Small/fast model: Sonnet 4.5us.anthropic.claude-sonnet-4-5-20250929-v1:0

Background jobs like session titles normally use a Haiku-class model, but on Bedrock they use Sonnet because Haiku is not enabled everywhere. If you choose a primary model (via --model, ANTHROPIC_MODEL, the model setting or ANTHROPIC_DEFAULT_MODEL), background jobs use it. Pinning Opus without pinning Sonnet also counts as a choice. Set ANTHROPIC_DEFAULT_HAIKU_MODEL to an enabled model if you want Haiku for background work.

Warning: Opus costs more per token than Sonnet. A deployment that never pinned a primary model has been billed at Opus rates since v2.1.207. To stay on Sonnet 4.5, set ANTHROPIC_MODEL to its full ID. If you steer with ANTHROPIC_DEFAULT_SONNET_MODEL and do not set the Opus variable, your Sonnet stays the default.

History, for anyone debugging an older fleet: before v2.1.280 the default and opus were Opus 5 (from v2.1.219); v2.1.207 to v2.1.218 used Opus 4.8; before v2.1.207 the default was Sonnet 4.5, opus meant Opus 4.6, and background tasks used the primary model.

Other model options:

export ANTHROPIC_MODEL='arn:aws:bedrock:eu-west-2:111122223333:application-inference-profile/claude-dev'
export DISABLE_PROMPT_CACHING=1      # if you need it off
export ENABLE_PROMPT_CACHING_1H=1    # one-hour cache TTL, billed at a higher rate

Prompt caching is not available in every Bedrock region; if cache token counts stay at zero, check AWS's list of supported models and regions.

Several versions, several inference profiles

The ANTHROPIC_DEFAULT_*_MODEL variables give you one profile per family. To offer several versions of a family in /model, each routed through its own application inference profile, use modelOverrides:

{
  "modelOverrides": {
    "claude-opus-4-8": "arn:aws:bedrock:eu-west-2:111122223333:application-inference-profile/opus48-eng",
    "claude-opus-4-7": "arn:aws:bedrock:eu-west-2:111122223333:application-inference-profile/opus47-eng",
    "claude-sonnet-4-6": "arn:aws:bedrock:eu-west-2:111122223333:application-inference-profile/sonnet46-eng"
  }
}

Choosing a mapped version in /model, or passing its Anthropic ID through --model or ANTHROPIC_MODEL (from v2.1.200), calls Bedrock with the ARN. Unmapped versions use the built-in ID or a discovered inference profile. See model configuration.

Startup model checks

At startup Claude Code checks that the models it plans to use are callable:

  • Outdated pin, newer version available: it offers to update the pin. Accepting writes the new ID to user settings and restarts; declining is remembered until the next default change. ARN pins are never touched.
  • No pin, default unavailable: it falls back for this session (earlier versions of the same model first, then from Opus to the default Sonnet) and shows a notice. Nothing is saved.
  • Specific version chosen at launch (--model, ANTHROPIC_MODEL, model): treated as the pin for that tier, with no availability check of the default it replaces. Aliases and unrecognised IDs such as ARNs do not count as pins.

Refusals are remembered on the machine for up to a day; a refused current default is rechecked after ten minutes so re-enabled models come back. CLAUDE_CODE_SKIP_MODEL_ACCESS_MEMORY=1 turns the memory off.

With an enforced allowlist (enforceAvailableModels, v2.1.287+, Invoke API), these checks only consider models in availableModels, compared against the full inference profile ID including prefix:

{
  "availableModels": ["eu.anthropic.claude-opus-4-8", "eu.anthropic.claude-sonnet-4-6"],
  "enforceAvailableModels": true
}

If a model is disabled mid-session, Claude Code switches to another (Switched to <fallback> because <model> is not available) using the same fallback order, but only for unpinned tiers. Pinned versions and ARNs fail instead. In auto mode it only switches to models auto mode supports on Bedrock, otherwise failing with "AWS authentication failed". A configured fallback model chain takes priority over the tier switch. CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK=1 makes refused requests fail rather than switch (remove any fallback chain too if you want every refusal to fail).

Cross-region prefixes

On the Invoke API, built-in defaults resolve to cross-region inference profile IDs. The preferred prefix follows your region:

RegionPrefix
us-gov-*us-gov.
us-*us.
eu-*eu.
ap-*apac.
Anything elseglobal.

From v2.1.224, ANTHROPIC_BEDROCK_REGION_PREFIX sets the preferred prefix: us, eu, apac, jp, au or global. For example, global when your account has global profiles but your region would otherwise choose a geographic one. Invalid values fall back to the region-derived prefix, and GovCloud always uses us-gov..

It is a preference. If Claude Code can list your inference profiles, it picks the profile with your prefix, then any matching profile, then the built-in ID with your prefix (unchecked at that step, though startup checks still cover the session defaults). If it cannot list profiles, it applies the prefix blindly, and requests fail with a 400 if those profiles are not enabled. IDs, ARNs and modelOverrides values you configure are never rewritten.

IAM permissions

Claude Code needs to invoke models, stream responses and look up inference profiles. Here is a policy scoped to one region and account; widen or narrow the resources to suit:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ClaudeCodeBedrock",
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream",
        "bedrock:ListInferenceProfiles",
        "bedrock:GetInferenceProfile"
      ],
      "Resource": [
        "arn:aws:bedrock:eu-*:111122223333:inference-profile/*",
        "arn:aws:bedrock:eu-*:111122223333:application-inference-profile/*",
        "arn:aws:bedrock:eu-*::foundation-model/*"
      ]
    },
    {
      "Sid": "MarketplaceViaBedrockOnly",
      "Effect": "Allow",
      "Action": ["aws-marketplace:ViewSubscriptions", "aws-marketplace:Subscribe"],
      "Resource": "*",
      "Condition": { "StringEquals": { "aws:CalledViaLast": "bedrock.amazonaws.com" } }
    }
  ]
}

bedrock:GetInferenceProfile lets Claude Code map an application inference profile ARN to its underlying model so it sends the right request shape. Without it, Claude Code retries once with the other shape, which works but costs an extra round-trip per new model. This bites most often with narrowly scoped AWS_BEARER_TOKEN_BEDROCK keys.

Tip: A dedicated AWS account for Claude Code makes cost tracking and access control much simpler.

1M context, service tiers and guardrails

1M context. Sonnet 5, Opus 4.6 and later, and Sonnet 4.6 support a 1M-token window on Bedrock. Sonnet 5 always uses it (Invoke and Mantle), with no [1m] variant. For the others on the Invoke API, pick a 1M variant in the wizard or append [1m] to a pinned ID.

Service tiers. Set ANTHROPIC_BEDROCK_SERVICE_TIER to default, flex or priority; it is sent as X-Amzn-Bedrock-Service-Tier. Availability varies by model and region. For reserved capacity, use a provisioned throughput ARN as the model ID instead.

Guardrails. Create and publish a Bedrock Guardrail (enable cross-region inference on it if you use cross-region profiles), then send its headers:

{
  "env": {
    "ANTHROPIC_CUSTOM_HEADERS": "X-Amzn-Bedrock-GuardrailIdentifier: gr-7h2k9q\nX-Amzn-Bedrock-GuardrailVersion: 3"
  }
}

If a guardrail blocks a response mid-stream, the text so far remains and the reply ends with the guardrail's blocked-response message. Guardrail headers delivered through a Claude apps gateway policy need user approval.

The Mantle endpoint

Mantle is a Bedrock endpoint that serves Claude using the native Anthropic API shape instead of Invoke. It uses the same AWS credentials and awsAuthRefresh, but its own IAM namespace: grant bedrock-mantle:CreateInference and bedrock-mantle:CountTokens.

export CLAUDE_CODE_USE_MANTLE=1
export AWS_REGION=us-east-1
claude --model anthropic.claude-sonnet-5

The endpoint URL is built from the region (resolved as above); override it with ANTHROPIC_BEDROCK_MANTLE_BASE_URL. /status shows Amazon Bedrock (Mantle). Mantle model IDs start with anthropic. and have no version suffix (anthropic.claude-haiku-4-5, for example); which ones you can use depends on what AWS has granted your account.

Running both. Set CLAUDE_CODE_USE_BEDROCK and CLAUDE_CODE_USE_MANTLE together and Claude Code routes Mantle-format IDs to Mantle and everything else to Invoke; /status shows Amazon Bedrock + Amazon Bedrock (Mantle). To put a Mantle model in /model, list it in availableModels. That list also restricts the picker, and a Mantle Haiku ID displaces the bare haiku alias, so list the versions you want to keep:

{ "availableModels": ["opus", "sonnet", "claude-haiku-4-5", "anthropic.claude-haiku-4-5"] }

Through a gateway that adds AWS credentials server-side, stop the client signing requests:

export CLAUDE_CODE_USE_MANTLE=1
export CLAUDE_CODE_SKIP_MANTLE_AUTH=1
export ANTHROPIC_BEDROCK_MANTLE_BASE_URL=https://llm-gw.example.internal/mantle
VariablePurpose
CLAUDE_CODE_USE_MANTLETurn Mantle on (1 or true)
ANTHROPIC_BEDROCK_MANTLE_BASE_URLCustom Mantle URL
CLAUDE_CODE_SKIP_MANTLE_AUTHDo not sign requests (gateway does it)
ANTHROPIC_SMALL_FAST_MODEL_AWS_REGIONRegion for the Haiku-class model, shared with Invoke

Troubleshooting

Endless SSO browser tabs. VPNs and TLS-inspecting proxies can break the SSO flow, which looks like an auth failure, which reruns awsAuthRefresh. Remove awsAuthRefresh and run aws sso login yourself before starting Claude Code.

Certificate errors. Since v2.1.260 your CA configuration (OS trust store or NODE_EXTRA_CA_CERTS) applies to model discovery, token counting, STS and SSO calls and the wizard's checks, proxy or not. If the wizard shows models as unreachable or you see unable to get local issuer certificate while inference works, update to v2.1.261 or later. See network configuration.

Region problems. Run aws bedrock list-inference-profiles --region <region> to see what is available, try a supported region, or use cross-region profiles. "On-demand throughput isn't supported" means you should use an inference profile ID rather than a bare model ID. Claude Code uses the Invoke API, not Converse.

Streaming errors through a gateway. Bedrock streams with Content-Type: application/vnd.amazon.eventstream. A gateway that rewrites that header (typically to text/event-stream) triggers an error starting Bedrock streaming response has content-type. A gateway that drops the header is tolerated if it passes the body through untouched; if it also converts to server-sent events, responses arrive only when complete unless you set CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_DEFAULT=1. The real fix is to forward the body and header unchanged. If the gateway really speaks the Anthropic Messages API, connect to it with ANTHROPIC_BASE_URL as an LLM gateway instead.

Zero tokens per tool group in /context. Fixed in v2.1.196; update.

Mantle not active. If /status lacks Amazon Bedrock (Mantle), the variable is not reaching the process; export it in the launching shell or put it in settings env. A 403 naming a bedrock-mantle: action needs that IAM permission; a 403 without one means your account lacks access to that model. A 400 naming the model means it is not on Mantle: Invoke-style IDs like us.anthropic.claude-sonnet-4-6 will not work there.