Skip to main content
ChatCLI supports AWS Bedrock as a native provider (BEDROCK), with request/response schema auto-detected by model family:
  • Anthropic Claudeanthropic.* and inference profiles (global./us./eu./apac.anthropic.*)
  • OpenAI GPT-OSSopenai.gpt-oss-* (OpenAI’s open-weights on Bedrock)
Ideal for corporate environments that already manage billing, compliance, and access control through AWS — no need for API keys from the original providers.

Why AWS Bedrock?

No Anthropic API key

Uses existing AWS credentials (IAM role, ~/.aws/credentials, AWS_PROFILE).

AWS billing and compliance

Costs appear on your AWS bill. CloudTrail logs, native Bedrock guardrails.

Claude + GPT-OSS

Claude 3/3.5/3.7/4/4.5/4.6 (via inference profiles) and OpenAI GPT-OSS 20B/120B.

VPC endpoints

Works in private environments via AWS_ENDPOINT_URL_BEDROCK_RUNTIME.

Configuration

The provider is auto-detected when ChatCLI finds valid AWS credentials (not just file existence):
  • Static creds in env: AWS_ACCESS_KEY_ID
  • Profile selection: AWS_PROFILE (via env var or .env file)
  • ~/.aws/credentials file with at least one non-empty aws_access_key_id
  • AWS SSO: SSO profile in ~/.aws/config (detects sso_session, sso_start_url, sso_account_id)
  • Assume-role / credential_process: profiles with role_arn or credential_process in ~/.aws/config
  • SSO token cache: presence of files in ~/.aws/sso/cache/ (indicating a prior aws sso login)
  • Web Identity Token (EKS IRSA): AWS_WEB_IDENTITY_TOKEN_FILE
  • Container Credentials (ECS): AWS_CONTAINER_CREDENTIALS_RELATIVE_URI / _FULL_URI
The mere existence of ~/.aws/config with only region or output does not activate Bedrock. The file must contain credential configuration (SSO, assume-role, credential_process), or credentials must exist in another source.

Option 1: ~/.aws/credentials (static credentials)

If you already use AWS CLI, just have a profile configured:
# ~/.aws/credentials
[default]
aws_access_key_id = AKIA...
aws_secret_access_key = ...

[corp-prod]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
export AWS_PROFILE=corp-prod
export BEDROCK_REGION=us-east-1   # optional, defaults to us-east-1
chatcli
Inside ChatCLI:
/switch BEDROCK
You can also set AWS_PROFILE in your .env file instead of exporting in the shell:
AWS_PROFILE=corp-prod
BEDROCK_REGION=us-east-1
LLM_PROVIDER=BEDROCK
ChatCLI reads the .env via godotenv and resolves the profile correctly.

Option 2: AWS SSO (IAM Identity Center)

If your company uses AWS SSO, configure the profile in ~/.aws/config:
[profile my-sso]
sso_session = my-session
sso_account_id = 123456789012
sso_role_name = MyRole
region = us-east-1

[sso-session my-session]
sso_start_url = https://my-company.awsapps.com/start
sso_region = us-east-1
# Log in (opens browser)
aws sso login --profile my-sso

# Use with ChatCLI (any of these):
export AWS_PROFILE=my-sso && chatcli
AWS_PROFILE=my-sso chatcli

# Or in .env:
echo 'AWS_PROFILE=my-sso' >> .env
chatcli
ChatCLI automatically detects SSO profiles in ~/.aws/config (via sso_session, sso_start_url, sso_account_id keys). If the SSO token expires, the error will be clear (SSOTokenProviderError) — just run aws sso login again.Important: the AWS SDK does not know which profile is “logged in”. You must indicate the profile via AWS_PROFILE (env, .env, or flag). If your SSO profile is named default, it is used automatically without AWS_PROFILE.

Option 3: Environment variables (static credentials)

export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...      # if using STS
export AWS_REGION=us-east-1

Option 4: IAM Role (EC2/ECS/EKS)

On AWS-native environments, nothing to configure — the SDK picks up the role automatically through IMDSv2 / webidentity. Just make sure the role has the IAM permissions below.
ChatCLI disables the IMDS probe (169.254.169.254) by default on machines that are not EC2/ECS/EKS, to avoid unnecessary timeouts. IMDS is automatically enabled when container/EKS env vars are detected (AWS_CONTAINER_CREDENTIALS_*, AWS_WEB_IDENTITY_TOKEN_FILE, ECS_CONTAINER_METADATA_URI*).To force behavior, use:
  • AWS_EC2_METADATA_DISABLED=true — explicitly disable IMDS
  • CHATCLI_BEDROCK_ENABLE_IMDS=1 — force enable IMDS (useful on EC2 without standard env vars)

IAM Permissions

Minimum permissions to invoke and list models:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream"
      ],
      "Resource": [
        "arn:aws:bedrock:*::foundation-model/anthropic.*",
        "arn:aws:bedrock:*:*:inference-profile/*anthropic.*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "bedrock:ListFoundationModels",
        "bedrock:ListInferenceProfiles"
      ],
      "Resource": "*"
    }
  ]
}
ListFoundationModels and ListInferenceProfiles are used by /switch --model to dynamically discover what your account can invoke. Without them, ChatCLI falls back to the static catalog (still functional but can’t reflect account-specific access).
Also, in the Bedrock console you must enable model access for each Anthropic model you want to use (one-time per account + region): Bedrock Console → Model access → Request access.

Model families and schema selection

Bedrock uses different payloads for each model family. ChatCLI auto-detects the schema from the model-id prefix:
Model id prefixFamilySchema
anthropic.*, global.anthropic.*, us.anthropic.*, eu.anthropic.*, apac.anthropic.*Anthropic ClaudeAnthropic Messages (anthropic_version, messages, system)
openai.*, us.openai.*, …OpenAI GPT-OSSOpenAI Chat Completions (messages, max_completion_tokens)
OthersNot supported in this version

Manual override

If the model id doesn’t start with a known prefix (e.g. custom imports), force the schema via env var:
export BEDROCK_PROVIDER=anthropic   # or "openai" / "claude" / "gpt"
Accepted values: anthropic, claude, openai, gpt (case-insensitive). The env var takes precedence over prefix detection.
ChatCLI only lists and invokes models from supported families (anthropic and openai). Meta Llama, Amazon Nova, Mistral, and Cohere models returned by ListFoundationModels are filtered out automatically — support for them may be added later.

Inference Profiles vs. Model IDs

This is the most important detail when using Claude on Bedrock. Modern Anthropic models (3.7, 4.x, 4.5, 4.6) do NOT accept direct on-demand invocation by base model ID. Attempting this returns:
on-demand throughput isn't supported. Request with the id or arn of an
inference profile that contains this model.
The fix is to use an inference profile ID — a logical ARN that routes the call to a region with available capacity. It carries a geography prefix:
PrefixMeaning
global.*Global — newest tier, worldwide availability (recommended)
us.*Cross-region USA (us-east-1, us-east-2, us-west-2)
eu.*Cross-region Europe
apac.*Cross-region Asia-Pacific
Example:
anthropic.claude-sonnet-4-5-20250929-v1:0           ❌ on-demand error
global.anthropic.claude-sonnet-4-5-20250929-v1:0    ✅ works
us.anthropic.claude-sonnet-4-5-20250929-v1:0        ✅ works
ChatCLI already uses a global inference profile as the default model (global.anthropic.claude-sonnet-4-5-20250929-v1:0). Claude 3 and 3.5 models still accept direct base-ID invocation and are also in the catalog.

Model Listing

/switch --model queries two live sources and merges them with the static catalog:
  1. bedrock:ListFoundationModels — base models (on-demand capable)
  2. bedrock:ListInferenceProfiles — regional/global profiles (paginated)
/switch BEDROCK
/switch --model
Example output (depends on your account’s permissions):
Available models for BEDROCK (API: 18 + catalog: 14):
  1. global.anthropic.claude-sonnet-4-6-20260115-v1:0 ... [api]
  2. global.anthropic.claude-opus-4-6-20260115-v1:0 ... [api]
  3. global.anthropic.claude-sonnet-4-5-20250929-v1:0 ... [api]
  4. us.anthropic.claude-sonnet-4-20250514-v1:0 ... [api]
  5. eu.anthropic.claude-sonnet-4-20250514-v1:0 ... [api]
  6. anthropic.claude-3-5-sonnet-20241022-v2:0 ... [api]
  ...
Models with [api] are the ones your account actually can invoke in that region. [catalog] entries are static registrations that may or may not be enabled.

Corporate Proxy and Private TLS

In corporate environments with a proxy intercepting TLS using a private CA, you may see:
tls: failed to verify certificate: x509: certificate signed by unknown authority
ChatCLI provides two Bedrock-specific env vars:
VariableDescription
CHATCLI_BEDROCK_CA_BUNDLEPath to a PEM bundle with the corporate CA. Merged into the system pool and used as RootCAs. Takes precedence over AWS_CA_BUNDLE.
CHATCLI_BEDROCK_INSECURE_SKIP_VERIFYtrue disables TLS verification entirely (equivalent to Node’s NODE_TLS_REJECT_UNAUTHORIZED=0). Insecure — use only to confirm a TLS issue.
# Recommended: use a bundle with the corporate CA
export CHATCLI_BEDROCK_CA_BUNDLE=/etc/ssl/corp-ca-bundle.pem

# Last resort (insecure)
export CHATCLI_BEDROCK_INSECURE_SKIP_VERIFY=true
CHATCLI_BEDROCK_INSECURE_SKIP_VERIFY=true logs a warning and accepts any certificate. Use only for troubleshooting — never in production.
HTTP(S) proxy is honored automatically through Go’s standard env vars:
export HTTPS_PROXY=http://proxy.corp:3128
export HTTP_PROXY=http://proxy.corp:3128
export NO_PROXY=localhost,127.0.0.1,.corp.internal

VPC endpoints / private endpoints

If your company uses a VPC endpoint for Bedrock:
export AWS_ENDPOINT_URL_BEDROCK_RUNTIME=https://bedrock-runtime.vpc.internal
export AWS_ENDPOINT_URL_BEDROCK=https://bedrock.vpc.internal
The SDK v2 reads these natively — no ChatCLI changes needed.

Environment Variables

VariableDescriptionDefault
BEDROCK_PROVIDERManual schema override: anthropic (default) or openaiauto-detect
BEDROCK_TEMPERATURETemperature used for OpenAI family models
BEDROCK_REGIONAWS region (takes precedence over AWS_REGION)
AWS_REGIONAWS region (fallback)
AWS_PROFILEProfile in ~/.aws/credentials or ~/.aws/config (SSO, assume-role). Can be set in .env.
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKENStatic credentials
AWS_CA_BUNDLEPEM bundle read natively by SDK v2
AWS_ENDPOINT_URL_BEDROCK_RUNTIMEOverride for Bedrock Runtime endpoint
AWS_ENDPOINT_URL_BEDROCKOverride for Bedrock (control plane) endpoint
AWS_EC2_METADATA_DISABLEDtrue explicitly disables IMDS (169.254.169.254)
CHATCLI_BEDROCK_ENABLE_IMDS1/true forces IMDS probe on non-EC2 machinesfalse
BEDROCK_MAX_TOKENSOutput token limitFrom catalog
ANTHROPIC_MAX_TOKENSAlternative shared with direct Anthropic provider
CHATCLI_BEDROCK_CA_BUNDLEBedrock-specific PEM bundle (overrides AWS_CA_BUNDLE)
CHATCLI_BEDROCK_INSECURE_SKIP_VERIFYtrue disables TLS verification (insecure)false
HTTPS_PROXY / HTTP_PROXY / NO_PROXYStandard Go/SDK HTTP proxy
Default model: global.anthropic.claude-sonnet-4-5-20250929-v1:0 Default region: us-east-1

Architecture

ChatCLI uses bedrockruntime.InvokeModel with body in the Anthropic Messages schema (anthropic_version: "bedrock-2023-05-31"). Authentication is SigV4, handled transparently by the SDK. The HTTP client can be overridden by ChatCLI when CHATCLI_BEDROCK_CA_BUNDLE or CHATCLI_BEDROCK_INSECURE_SKIP_VERIFY is set (via awshttp.BuildableClient).

Bedrock vs. Direct Anthropic

AspectBEDROCKCLAUDEAI (direct Anthropic)
AuthAWS credentials chain (IAM, profile)API key (sk-ant-...) or OAuth
Endpointbedrock-runtime.<region>.amazonaws.comapi.anthropic.com
BillingAWS account (Billing console + CloudTrail)Anthropic account (console.anthropic.com)
ModelsClaude 3, 3.5, 3.7, 4, 4.1, 4.5, 4.6 (via profiles)All Claude, latest versions first
StreamingNot implemented in this version (uses InvokeModel)Supported
OAuth/1M contextN/ASupported (ANTHROPIC_1MTOKENS_SONNET)
Private VPCYes (via AWS_ENDPOINT_URL_*)No
ComplianceInherits from AWS (SOC2, HIPAA, etc.)Inherits from Anthropic
If your company already runs everything on AWS with managed compliance, BEDROCK is the way. If you’re an individual developer wanting the newest Claude features (1M context, OAuth via Claude Code plan), use CLAUDEAI direct.

Troubleshooting

You’re invoking a modern model (3.7+, 4.x+, 4.5+, 4.6) by its base ID. Use the inference profile: add prefix global., us., eu., or apac..
# ❌
/switch --model anthropic.claude-sonnet-4-5-20250929-v1:0
# ✅
/switch --model global.anthropic.claude-sonnet-4-5-20250929-v1:0
Go to the Bedrock console for that region and enable Model Access for the Anthropic model. Takes a few minutes. Also check the IAM role has bedrock:InvokeModel on the model ARN + the inference profile ARN.
The SDK didn’t find credentials. Check:
aws sts get-caller-identity   # should return your identity
env | grep -E 'AWS_|BEDROCK_'
ls -la ~/.aws/
If nothing returns credentials, set them up via aws configure, aws sso login, or export env vars.
This error occurs when the AWS SDK tries to reach the EC2 Instance Metadata Service (IMDS) on a machine that is not EC2 (e.g., your laptop). ChatCLI disables the IMDS probe by default on non-EC2, but if the error persists:
# Solution 1: Set valid credentials
export AWS_PROFILE=my-profile
# or
export AWS_ACCESS_KEY_ID=AKIA...

# Solution 2: Explicitly disable IMDS
export AWS_EC2_METADATA_DISABLED=true
If you are actually on EC2 and need IMDS:
export CHATCLI_BEDROCK_ENABLE_IMDS=1
Your SSO token has expired (default validity ~8h). Log in again:
aws sso login --profile your-profile
Remember to have AWS_PROFILE set (env, .env, or name your profile default).
Corporate proxy doing TLS interception. Configure CHATCLI_BEDROCK_CA_BUNDLE with the PEM of the corp CA. For quick troubleshooting, set CHATCLI_BEDROCK_INSECURE_SKIP_VERIFY=true (insecure, temporary only).
You’ve hit on-demand quota for that region. Options:
  • Use a global.* inference profile (routes to any available region)
  • Use Provisioned Throughput (configure in the Bedrock console)
  • Raise quotas via AWS Service Quotas

Next Steps

Provider Fallback

Configure automatic failover between Bedrock and other providers

OAuth Authentication

Authentication alternatives for other providers

Supported Models

Full list of Claude models per provider

Environment Variables

Complete configuration reference