> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS Bedrock

> Access the entire AWS Bedrock catalog — Claude, OpenAI GPT-OSS, Llama, Nova, Mistral, Cohere, AI21, DeepSeek, Moonshot Kimi, MiniMax, Qwen, Z.AI/GLM, Gemma, Nemotron, TwelveLabs — with authentication via IAM, AWS_PROFILE, or ~/.aws/credentials. Includes embeddings (Titan v1/v2 + Cohere v3).

ChatCLI supports **AWS Bedrock** as a native provider (`BEDROCK`) with **three dispatch paths** that cover the entire AWS-hosted catalog:

* **Anthropic Messages** — `anthropic.*` and inference profiles (`global./us./eu./apac.anthropic.*`). Preserves cache markers and extended-thinking budget.
* **OpenAI Chat Completions** — `openai.gpt-oss-*` (OpenAI's open-weights on Bedrock).
* **Converse API (default)** — AWS's unified schema covering everything else: Llama, Amazon Nova, Mistral, Cohere, AI21 Jamba, DeepSeek, Stability, Writer Palmyra, Moonshot Kimi, MiniMax, Qwen, Z.AI/GLM, Google Gemma, NVIDIA Nemotron, TwelveLabs Pegasus, and any provider AWS onboards next.

The `/switch --model` listing trusts AWS-side responses from `ListFoundationModels` + `ListInferenceProfiles` 100% — there is no hardcoded allowlist. A new model on AWS shows up on the next `/switch --model` without a ChatCLI release.

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?

<CardGroup cols={2}>
  <Card title="No per-provider API key" icon="key">
    Uses existing AWS credentials (IAM role, `~/.aws/credentials`, `AWS_PROFILE`). Single identity across every model.
  </Card>

  <Card title="AWS billing and compliance" icon="receipt">
    Costs appear on your AWS bill. CloudTrail logs, native Bedrock guardrails.
  </Card>

  <Card title="Full catalog" icon="layer-group">
    Anthropic, OpenAI, Llama, Nova, Mistral, Cohere, AI21, DeepSeek, Moonshot Kimi, MiniMax, Qwen, Z.AI/GLM, Gemma, Nemotron, TwelveLabs — all under one account.
  </Card>

  <Card title="VPC endpoints" icon="network-wired">
    Works in private environments via `BEDROCK_BASE_URL` (or the AWS-native `AWS_ENDPOINT_URL_BEDROCK_RUNTIME`).
  </Card>

  <Card title="Auto-detected family" icon="route">
    Anthropic and OpenAI use dedicated paths (cache, thinking); the rest goes through Converse — one call covers all.
  </Card>

  <Card title="Native embeddings" icon="vector-square">
    Embeddings provider reuses the same AWS credential chain. Titan v1/v2 + Cohere v3. See [RAG + HyDE](/features/quality/rag-hyde).
  </Card>
</CardGroup>

***

## 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`

<Warning>
  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.
</Warning>

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

If you already use AWS CLI, just have a profile configured:

```bash theme={"system"}
# ~/.aws/credentials
[default]
aws_access_key_id = AKIA...
aws_secret_access_key = ...

[corp-prod]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
```

```bash theme={"system"}
export AWS_PROFILE=corp-prod
export BEDROCK_REGION=us-east-1     # optional, defaults to us-east-1
export BEDROCK_MODEL=claude-opus-4-8  # optional default model (catalog aliases work)
chatcli
```

Inside ChatCLI:

```bash theme={"system"}
/switch BEDROCK
```

<Tip>
  You can also set `AWS_PROFILE` in your `.env` file instead of exporting in the shell:

  ```env theme={"system"}
  AWS_PROFILE=corp-prod
  BEDROCK_REGION=us-east-1
  BEDROCK_MODEL=claude-opus-4-8
  LLM_PROVIDER=BEDROCK
  ```

  ChatCLI reads the `.env` via godotenv and resolves the profile correctly.
</Tip>

### Option 2: AWS SSO (IAM Identity Center)

If your company uses AWS SSO, configure the profile in `~/.aws/config`:

```ini theme={"system"}
[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
```

```bash theme={"system"}
# 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
```

<Info>
  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`.
</Info>

### Option 3: Environment variables (static credentials)

```bash theme={"system"}
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.

<Info>
  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)
</Info>

***

## IAM Permissions

Minimum permissions to invoke and list models. The `bedrock:InvokeModel` action covers both `InvokeModel` (Anthropic/OpenAI) and `Converse` (everything else):

```json theme={"system"}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream"
      ],
      "Resource": [
        "arn:aws:bedrock:*::foundation-model/*",
        "arn:aws:bedrock:*:*:inference-profile/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "bedrock:ListFoundationModels",
        "bedrock:ListInferenceProfiles"
      ],
      "Resource": "*"
    }
  ]
}
```

<Tip>
  To restrict to specific providers, swap the `Resource` ARNs for a list (e.g. `arn:aws:bedrock:*::foundation-model/anthropic.*`, `arn:aws:bedrock:*::foundation-model/moonshotai.*`). Remember to include the matching inference profile ARNs (`*:inference-profile/*anthropic.*` etc.) — otherwise Claude 3.7+ and equivalents from other providers stop working.
</Tip>

<Tip>
  `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).
</Tip>

Also, in the **Bedrock console** you must **enable model access** for each provider you want to use (one-time per account + region): `Bedrock Console → Model access → Request access`.

***

## Model families and schema selection

Bedrock uses **different schemas** depending on the model. ChatCLI has three dispatch paths and auto-detects which one to use from the model-id prefix:

| Model id prefix                                                                                                                                  | Family                      | Schema                                                           | Why                                                                                                                                                                                                                             |
| :----------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------- | :--------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `anthropic.*`, `global./us./eu./apac.anthropic.*` and any id containing `claude`/`fable`                                                         | **Anthropic Messages**      | `anthropic_version`, `messages`, `system` (with `cache_control`) | Preserves cache breakpoints, extended-thinking budget, every Claude knob. Bare ids (e.g. `claude-fable-5`) are normalized to the invokable catalog ID — previously they fell through to Converse, which **drops cache markers** |
| `openai.*`, `us.openai.*`, etc.                                                                                                                  | **OpenAI Chat Completions** | `messages`, `max_completion_tokens`                              | Stable schema with broad coverage for GPT-OSS                                                                                                                                                                                   |
| Anything else (Llama, Nova, Mistral, Cohere, AI21, DeepSeek, Stability, Writer, Moonshot, MiniMax, Qwen, Z.AI, Gemma, Nemotron, TwelveLabs, ...) | **Converse API** (default)  | `messages`, `system`, `inferenceConfig`                          | AWS-unified schema — one implementation covers every provider that doesn't need special features                                                                                                                                |

### Manual override

To force a family regardless of the prefix (e.g. test Converse on an Anthropic model), use the env var:

```bash theme={"system"}
export BEDROCK_PROVIDER=anthropic   # or "claude"
export BEDROCK_PROVIDER=openai      # or "gpt"
export BEDROCK_PROVIDER=converse    # or "auto"
```

Accepted values: `anthropic` / `claude`, `openai` / `gpt`, `converse` / `auto` (case-insensitive). The env var takes precedence over prefix detection.

<Tip>
  **Why do Anthropic and OpenAI stay out of Converse?** Anthropic's cache\_control breakpoints and extended-thinking knobs map onto Converse with a different shape — we deliberately don't disturb the production-proven cache planner. OpenAI gpt-oss runs stable on direct `InvokeModel` and Converse coverage for those IDs varies by region. Set `BEDROCK_PROVIDER=converse` if you want to experiment with everything on Converse.
</Tip>

<Info>
  **No hardcoded allowlist.** `/switch --model` lists every text-output model with on-demand inference your account has access to — Kimi K2.6, GLM 4.7, Qwen3 Coder Next, Nemotron Nano 3, anything new AWS adds — without a release on our side. If a rare ID doesn't fit Converse, ChatCLI returns a friendly error pointing the way.
</Info>

***

## New-generation Claude and the Messages endpoint (bedrock-mantle)

The newest Claude generation on Bedrock (**Fable 5, Opus 5, Sonnet 5, Opus 4.8, Opus 4.7**) uses **dateless IDs** — `anthropic.claude-fable-5`, `anthropic.claude-opus-5`, `anthropic.claude-sonnet-5`, `anthropic.claude-opus-4-8`, `anthropic.claude-opus-4-7` — with **no** ARN-versioned IDs (`...-v1:0`). On the `InvokeModel` path (Opus 4.8/4.7) the bare dateless ID is **not on-demand invokable** — AWS answers "retry with the ID or ARN of an inference profile" — so ChatCLI invokes them through the **`global.` inference profile** (`global.anthropic.claude-opus-4-8`); the Messages-endpoint models (Opus 5, Sonnet 5, Fable 5) use the bare dateless ID.

**Claude Opus 5**, **Claude Sonnet 5** and **Claude Fable 5** have one particularity: they are served **exclusively** by the *Claude in Amazon Bedrock* endpoint — the Messages API at `https://bedrock-mantle.{region}.api.aws/anthropic/v1/messages`. Opus 5 and Sonnet 5 do not exist on legacy `InvokeModel`, and Fable 5 rejects it with `400 ValidationException: data retention mode 'default' is not available for this model` (it requires 30-day data retention, available only under the *Claude in Amazon Bedrock* agreement). ChatCLI handles this on its own:

* The catalog flags these models with the `bedrock_mantle_only` capability and the client routes the request through the Messages endpoint automatically — `/switch --model claude-opus-5` (or `claude-sonnet-5` / `claude-fable-5`) just works.
* **Inference-profile IDs are canonicalized on the wire**: the Messages endpoint only knows the dateless `anthropic.*` IDs — sending `us.anthropic.claude-sonnet-5` or `global.anthropic.claude-fable-5` verbatim returns `404 not_found_error` ("model does not exist"). If you pick one of those profiles in `/switch` (that's what your account's `ListInferenceProfiles` lists), ChatCLI converts it to the canonical ID (`anthropic.claude-sonnet-5`) before building the request.
* **Auth**: SigV4 with the `bedrock-mantle` service name over the same credentials chain (IAM, profile, SSO), or a short-lived bearer token via `AWS_BEARER_TOKEN_BEDROCK` (`x-api-key` header) for corporate environments without IAM.
* **Body**: same shape as the first-party Messages API — the version travels in the `anthropic-version` header (the `anthropic_version` body field is InvokeModel-only). `cache_control` markers reach the wire unchanged, exactly as on the InvokeModel path.
* **Operational overrides**: `BEDROCK_ANTHROPIC_ENDPOINT=mantle|invoke` forces every Claude model onto either wire (gradual migration/rollback) and `BEDROCK_MANTLE_BASE_URL` points at VPC endpoints or proxies. Corporate TLS (`CHATCLI_BEDROCK_CA_BUNDLE` etc.) is honored.

<Note>
  Opus 4.8 and Opus 4.7 stay on `InvokeModel` by default (served by the same infrastructure as the Messages endpoint); set `BEDROCK_ANTHROPIC_ENDPOINT=mantle` to move them to the new endpoint too. Prerequisite for Opus 5/Sonnet 5/Fable 5: enable the model under **Model access** in the Bedrock console with a data retention mode selected.
</Note>

***

## Inference Profiles vs. Model IDs

This is **the most important detail** when using Claude on Bedrock.

Anthropic models from the 3.7–4.6 era (3.7, 4.x, 4.5, 4.6) **do NOT accept direct on-demand invocation by base model ID** (the dateless new generation — Fable 5, Opus 5, Sonnet 5, Opus 4.8/4.7 — needs no profile; see the section above). Attempting this with an older-era model 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:

| Prefix     | Meaning                                                    |
| :--------- | :--------------------------------------------------------- |
| `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:**

```text theme={"system"}
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
```

<Info>
  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.
</Info>

***

## Model Listing

`/switch --model` queries **two live sources** and merges them with the static catalog:

1. **`bedrock:ListFoundationModels`** with `ByOutputModality: TEXT` — text-output models available in the region.
2. **`bedrock:ListInferenceProfiles`** — regional/global profiles (paginated).

Two AWS-side filters guarantee that only **invokable** IDs appear:

* **Modality TEXT** (server-side) — drops embedding-only and image-only models.
* **`InferenceTypesSupported` contains `ON_DEMAND`** — drops base IDs that are only invokable via inference profile (Claude 3.7+/4.x and cross-region-only IDs from other providers). Those models still appear via `ListInferenceProfiles` with `global./us./eu./apac.` prefix.

```bash theme={"system"}
/switch BEDROCK
/switch --model
```

Example output (depends on your account's permissions):

```
Available models for BEDROCK (API: 47 + catalog: 14):
  1. anthropic.claude-fable-5 ... [catalog]
  2. anthropic.claude-sonnet-5 ... [catalog]
  3. global.anthropic.claude-sonnet-4-5-20250929-v1:0 ... [api]
  4. moonshotai.kimi-k2.5 ... [api]
  5. moonshotai.kimi-k2-thinking ... [api]
  6. zai.glm-4-7 ... [api]
  7. minimax.m-2-5 ... [api]
  8. qwen.qwen3-coder-480b ... [api]
  9. us.deepseek.r1-v1:0 ... [api]
  10. anthropic.claude-3-5-sonnet-20241022-v2:0 ... [api]
  11. openai.gpt-oss-120b-1: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.

<Warning>
  You still need to **enable Model Access** in the Bedrock console for each provider you intend to use. AWS gates this per account + region. If a model appears in `ListFoundationModels` but throws `AccessDeniedException` on invoke, model access is missing — usually a one-click fix in the console.
</Warning>

***

## 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:

| Variable                               | Description                                                                                                                                        |
| :------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CHATCLI_BEDROCK_CA_BUNDLE`            | Path 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_VERIFY` | `true` disables TLS verification entirely (equivalent to Node's `NODE_TLS_REJECT_UNAUTHORIZED=0`). **Insecure** — use only to confirm a TLS issue. |

```bash theme={"system"}
# 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
```

<Info>
  If the proxy intercepts TLS for **all** providers (not just Bedrock), prefer the **global** variables `CHATCLI_CA_BUNDLE` / `CHATCLI_TLS_INSECURE_SKIP_VERIFY` — they apply to every outbound connection (LLM providers, web tools, gateway, MCP), and Bedrock inherits them as fallback. The Bedrock-specific ones take precedence when both are set. See [Global TLS Trust](/reference/environment-variables#global-tls-trust-corporate-proxy).
</Info>

<Warning>
  `CHATCLI_BEDROCK_INSECURE_SKIP_VERIFY=true` logs a warning and accepts any certificate. Use only for troubleshooting — never in production.
</Warning>

HTTP(S) proxy is honored automatically through Go's standard env vars:

```bash theme={"system"}
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 / custom DNS

If your company routes Bedrock through a VPC interface endpoint, an API gateway or custom DNS, point the runtime (data plane) at it with `BEDROCK_BASE_URL` — the same role `ANTHROPIC_BEDROCK_BASE_URL` plays in Claude Code:

```bash theme={"system"}
export BEDROCK_BASE_URL=https://bedrock.internal.example.com
```

One variable covers the whole Bedrock surface — chat (`InvokeModel`/Converse), embeddings, image generation **and** model listing in `/switch`. If your control plane genuinely lives on another host — AWS VPC interface endpoints are created per service (`bedrock` vs `bedrock-runtime`), each with its own DNS name — the optional `BEDROCK_CONTROL_BASE_URL` overrides just the control plane (`ListFoundationModels`/`ListInferenceProfiles`). URLs must be absolute `http(s)` (validated at startup, fail-fast). The AWS-standard variables also work, read natively by SDK v2:

```bash theme={"system"}
export AWS_ENDPOINT_URL_BEDROCK_RUNTIME=https://bedrock-runtime.vpc.internal
export AWS_ENDPOINT_URL_BEDROCK=https://bedrock.vpc.internal   # control plane (model listing)
```

Precedence — data plane: `BEDROCK_BASE_URL` > `AWS_ENDPOINT_URL_BEDROCK_RUNTIME` > `AWS_ENDPOINT_URL` > regional default; control plane: `BEDROCK_CONTROL_BASE_URL` > `BEDROCK_BASE_URL` > `AWS_ENDPOINT_URL_BEDROCK`. `AWS_IGNORE_CONFIGURED_ENDPOINT_URLS=true` disables the AWS-standard ones but never the `BEDROCK_*_BASE_URL` pair. For the new-generation Claude Messages endpoint (bedrock-mantle), use `BEDROCK_MANTLE_BASE_URL` — it is a different host and service.

***

## Environment Variables

| Variable                                                            | Description                                                                                                                                                                                      | Default                     |
| :------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------- |
| `BEDROCK_MODEL`                                                     | Default model when none is selected — same role as `COPILOT_MODEL`/`MOONSHOT_MODEL` on other providers; catalog aliases work (`claude-opus-4-8`)                                                 | Sonnet 4.5 global           |
| `BEDROCK_PROVIDER`                                                  | Manual schema override: `anthropic` / `claude`, `openai` / `gpt`, `converse` / `auto`                                                                                                            | auto-detect                 |
| `BEDROCK_TEMPERATURE`                                               | Temperature (used by OpenAI and Converse paths)                                                                                                                                                  | —                           |
| `BEDROCK_TOP_P`                                                     | Top-p sampling (used by the Converse path)                                                                                                                                                       | —                           |
| `BEDROCK_REGION`                                                    | AWS region (takes precedence over `AWS_REGION`)                                                                                                                                                  | —                           |
| `AWS_REGION`                                                        | AWS region (fallback)                                                                                                                                                                            | —                           |
| `AWS_PROFILE`                                                       | Profile in `~/.aws/credentials` or `~/.aws/config` (SSO, assume-role). Can be set in `.env`.                                                                                                     | —                           |
| `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_SESSION_TOKEN` | Static credentials                                                                                                                                                                               | —                           |
| `AWS_CA_BUNDLE`                                                     | PEM bundle read natively by SDK v2                                                                                                                                                               | —                           |
| `BEDROCK_BASE_URL`                                                  | Custom base URL for the whole Bedrock surface — runtime and model listing (VPC endpoints, corporate DNS) — parity with Claude Code's `ANTHROPIC_BEDROCK_BASE_URL`; wins over `AWS_ENDPOINT_URL*` | —                           |
| `AWS_ENDPOINT_URL_BEDROCK_RUNTIME`                                  | Override for Bedrock Runtime endpoint                                                                                                                                                            | —                           |
| `BEDROCK_CONTROL_BASE_URL`                                          | Optional control-plane override (model listing) when it lives on a different host than `BEDROCK_BASE_URL` — VPC endpoints are per service; wins over `AWS_ENDPOINT_URL_BEDROCK`                  | inherits `BEDROCK_BASE_URL` |
| `AWS_ENDPOINT_URL_BEDROCK`                                          | Override for Bedrock (control plane) endpoint                                                                                                                                                    | —                           |
| `AWS_EC2_METADATA_DISABLED`                                         | `true` explicitly disables IMDS (169.254.169.254)                                                                                                                                                | —                           |
| `CHATCLI_BEDROCK_ENABLE_IMDS`                                       | `1`/`true` forces IMDS probe on non-EC2 machines                                                                                                                                                 | `false`                     |
| `BEDROCK_MAX_TOKENS`                                                | Output token limit                                                                                                                                                                               | From catalog                |
| `BEDROCK_ANTHROPIC_ENDPOINT`                                        | Forces the Claude wire: `mantle` (Messages endpoint) or `invoke` (legacy InvokeModel)                                                                                                            | per catalog                 |
| `BEDROCK_MANTLE_BASE_URL`                                           | Messages endpoint override (`bedrock-mantle.{region}.api.aws`) for VPC endpoints/proxies                                                                                                         | —                           |
| `AWS_BEARER_TOKEN_BEDROCK`                                          | Short-lived bearer token (`aws-bedrock-token-generator`) — sent in the Messages endpoint's `x-api-key` header, no SigV4                                                                          | —                           |
| `ANTHROPIC_MAX_TOKENS`                                              | Alternative shared with direct Anthropic provider                                                                                                                                                | —                           |
| `CHATCLI_BEDROCK_CA_BUNDLE`                                         | Bedrock-specific PEM bundle (overrides `AWS_CA_BUNDLE`)                                                                                                                                          | —                           |
| `CHATCLI_BEDROCK_INSECURE_SKIP_VERIFY`                              | `true` disables TLS verification (insecure)                                                                                                                                                      | `false`                     |
| `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY`                           | Standard Go/SDK HTTP proxy                                                                                                                                                                       | —                           |

**Default model:** `global.anthropic.claude-sonnet-4-5-20250929-v1:0`
**Default region:** `us-east-1`

All these vars surface in `/config providers` (chat) and `/config quality` (embeddings). See [Environment Variables](/reference/environment-variables) for the full reference.

***

## Observability — endpoint URL in logs

Bedrock now logs its endpoint URL on every request — parity with Anthropic, OpenAI, and Copilot. Useful for debugging credential / region / VPC endpoint / proxy issues.

**On init (once per session):**

```text theme={"system"}
INFO  llm.info.configuring_provider: Bedrock
      region=us-east-1
      endpoint=https://bedrock-runtime.us-east-1.amazonaws.com
      model=global.anthropic.claude-sonnet-4-5-20250929-v1:0
```

**On each request (chat):**

```text theme={"system"}
INFO  llm: request start  provider=BEDROCK
      family=anthropic
      region=us-east-1
      endpoint=https://bedrock-runtime.us-east-1.amazonaws.com
      payload_bytes=12453  history_len=8  max_tokens=4096
      cache_markers=3
```

**On embeddings init:**

```text theme={"system"}
INFO  bedrock embeddings: configured
      region=us-east-1
      endpoint=https://bedrock-runtime.us-east-1.amazonaws.com
      model=amazon.titan-embed-text-v2:0
      family=titan
      dim=1024
```

The URL is derived from the SDK-resolved region (`https://bedrock-runtime.<region>.amazonaws.com`). If you set `AWS_ENDPOINT_URL_BEDROCK_RUNTIME` (VPC endpoint), the SDK uses your override — the log shows the canonical URL but the actual request goes to your custom endpoint.

***

## Architecture

```mermaid theme={"system"}
sequenceDiagram
    actor User
    participant CLI as ChatCLI
    participant SDK as AWS SDK v2
    participant Chain as Credentials Chain
    participant Bedrock as Bedrock Runtime

    User->>CLI: /switch BEDROCK
    CLI->>SDK: LoadBedrockRuntime(region, profile)
    SDK->>Chain: Env → ~/.aws → IAM Role
    Chain-->>SDK: Credentials + Region (resolved)
    Note over CLI: log: region + endpoint URL + model

    User->>CLI: Sends prompt
    CLI->>CLI: resolveFamily(modelId)
    alt Anthropic prefix
        CLI->>SDK: InvokeModel + Anthropic Messages body
        Note over CLI,SDK: cache_control + thinking budget preserved
    else OpenAI prefix
        CLI->>SDK: InvokeModel + OpenAI Chat Completions body
    else Default (Llama, Nova, Mistral, Cohere, …)
        CLI->>SDK: Converse + unified messages body
    end
    SDK->>Bedrock: POST (SigV4 signed)
    Bedrock-->>SDK: Response
    SDK-->>CLI: Parsed text
    CLI-->>User: Renders reply
```

The `bedrockruntime.Client` construction lives in an exported helper (`bedrock.LoadBedrockRuntime`) shared between the chat client and the embeddings provider — single source of truth for AWS config. 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

| Aspect               | BEDROCK                                                                                                                                         | CLAUDEAI (direct Anthropic)               |
| :------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------- |
| **Auth**             | AWS credentials chain (IAM, profile)                                                                                                            | API key (`sk-ant-...`) or OAuth           |
| **Endpoint**         | `bedrock-runtime.<region>.amazonaws.com`                                                                                                        | `api.anthropic.com`                       |
| **Billing**          | AWS account (Billing console + CloudTrail)                                                                                                      | Anthropic account (console.anthropic.com) |
| **Models**           | Full Bedrock catalog (Claude, OpenAI, Llama, Nova, Mistral, Cohere, AI21, DeepSeek, Moonshot, MiniMax, Qwen, Z.AI, Gemma, Nemotron, TwelveLabs) | All Claude, latest versions first         |
| **Streaming**        | Not implemented in this version (uses `InvokeModel` / `Converse`)                                                                               | Supported                                 |
| **OAuth/1M context** | N/A                                                                                                                                             | Supported (`ANTHROPIC_1MTOKENS_SONNET`)   |
| **Private VPC**      | Yes (via `AWS_ENDPOINT_URL_*`)                                                                                                                  | No                                        |
| **Compliance**       | Inherits from AWS (SOC2, HIPAA, etc.)                                                                                                           | Inherits from Anthropic                   |
| **Embeddings**       | Yes — Titan v1/v2 + Cohere v3 (same AWS chain)                                                                                                  | Not available                             |

<Tip>
  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.
</Tip>

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="bedrock: model X requires an inference profile">
    ChatCLI message when you select a base ID that requires an inference profile (Claude 3.7+/4.x/4.5/4.6/4.7 and equivalents from other providers). The message **already suggests the fix**:

    ```text theme={"system"}
    bedrock: model "anthropic.claude-3-7-sonnet-20250219-v1:0" requires an
    inference profile (the bare foundation ID is not invokable on-demand).
    Try selecting "global.anthropic.claude-3-7-sonnet-20250219-v1:0",
    "us.anthropic.claude-3-7-sonnet-20250219-v1:0",
    "eu.anthropic.claude-3-7-sonnet-20250219-v1:0", or
    "apac.anthropic.claude-3-7-sonnet-20250219-v1:0" instead, or run
    `/switch --model` to see profiles your account has access to.
    ```

    `/switch --model` **automatically filters** out base IDs that require profiles, so this only shows up if you typed an ID manually. The filter uses the `InferenceTypesSupported` field of `ListFoundationModels`: a model without `ON_DEMAND` is suppressed from the listing.
  </Accordion>

  <Accordion title="AccessDeniedException: You don't have access to the model">
    Go to the Bedrock console for that region and enable Model Access for the provider. Takes a few minutes. Also check the IAM role has `bedrock:InvokeModel` on the model ARN + the inference profile ARN.
  </Accordion>

  <Accordion title="NoCredentialProviders / unable to load SDK config">
    The SDK didn't find credentials. Check:

    ```bash theme={"system"}
    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.
  </Accordion>

  <Accordion title="no EC2 IMDS role found / dial tcp 169.254.169.254:80: connect: host is down">
    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:

    ```bash theme={"system"}
    # 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:

    ```bash theme={"system"}
    export CHATCLI_BEDROCK_ENABLE_IMDS=1
    ```
  </Accordion>

  <Accordion title="SSOTokenProviderError / expired token (SSO)">
    Your SSO token has expired (default validity \~8h). Log in again:

    ```bash theme={"system"}
    aws sso login --profile your-profile
    ```

    Remember to have `AWS_PROFILE` set (env, `.env`, or name your profile `default`).
  </Accordion>

  <Accordion title="x509: certificate signed by unknown authority">
    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).
  </Accordion>

  <Accordion title="ThrottlingException / ServiceQuotaExceededException">
    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
  </Accordion>
</AccordionGroup>

***

## Embeddings via Bedrock

ChatCLI also uses Bedrock as an embeddings provider (HyDE phase 3b, vector retrieval). Activation:

```bash theme={"system"}
export CHATCLI_EMBED_PROVIDER=bedrock
export CHATCLI_QUALITY_HYDE_ENABLED=true
export CHATCLI_QUALITY_HYDE_USE_VECTORS=true

# Optional — defaults: Titan v2 1024-dim, same region as chat
export CHATCLI_EMBED_MODEL=amazon.titan-embed-text-v2:0
export CHATCLI_EMBED_DIMENSIONS=1024     # Titan v2: 256/512/1024
```

Supported families:

| Model ID prefix                                            | Family    | Dimensions                                                     |
| :--------------------------------------------------------- | :-------- | :------------------------------------------------------------- |
| `amazon.titan-embed-text-v2*`                              | Titan v2  | 256 / 512 / 1024 (configurable via `CHATCLI_EMBED_DIMENSIONS`) |
| `amazon.titan-embed-text-v1`                               | Titan v1  | 1536 (fixed)                                                   |
| `cohere.embed-english-v3` / `cohere.embed-multilingual-v3` | Cohere v3 | 1024 (fixed)                                                   |

Reuses **the same credentials chain** as the chat client — `BEDROCK_REGION` / `AWS_REGION` / `AWS_PROFILE` / `~/.aws/credentials` etc. See [RAG + HyDE](/features/quality/rag-hyde) for the retrieval architecture.

<Tip>
  Titan and Cohere use different schemas but ChatCLI auto-detects from the model id prefix. If you need a large batch with Titan (which only accepts 1 text per call), the provider parallelizes with an 8-worker pool transparently.
</Tip>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Provider Fallback" icon="arrows-rotate" href="/features/provider-fallback">
    Configure automatic failover between Bedrock and other providers
  </Card>

  <Card title="RAG + HyDE" icon="database" href="/features/quality/rag-hyde">
    Embeddings via Bedrock Titan/Cohere for semantic retrieval
  </Card>

  <Card title="Supported Models" icon="list" href="/reference/supported-models">
    Full list of models per provider
  </Card>

  <Card title="Environment Variables" icon="sliders" href="/reference/environment-variables">
    Complete configuration reference
  </Card>
</CardGroup>
