Skip to main content

Bedrock

The gateway speaks Bedrock natively and does the SigV4 signing itself.

PropertyValue
Provider idbedrock
Gateway speaksBedrock Runtime (Converse API; InvokeModel for Claude on /v1/messages when enabled)
CredentialAn AWS workload role, or a static access key and secret, plus a region
SigningThe gateway signs SigV4 itself
Client base URLOPENAI_BASE_URL, or ANTHROPIC_BASE_URL for Claude, pointed at :8787

Set it up

1
Enable model access in AWS

AWS console → Bedrock → Model access, in the region you will use. Anthropic models need a one-time use-case form. Nothing below works until that is granted.

2
Grant the gateway access to Bedrock

Attach this policy to the role your gateway workload already runs as. There is no credential to store or rotate.

bedrock-invoke.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BedrockInvoke",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream",
"bedrock:Converse",
"bedrock:ConverseStream",
"bedrock:ListFoundationModels",
"bedrock:ListInferenceProfiles"
],
"Resource": "*"
},
{
"Sid": "BedrockUseCaseAttestation",
"Effect": "Allow",
"Action": [
"bedrock:GetUseCaseForModelAccess",
"bedrock:PutUseCaseForModelAccess",
"aws-marketplace:ViewSubscriptions",
"aws-marketplace:Subscribe"
],
"Resource": "*"
}
]
}

The two List actions let the gateway resolve a model id its built-in table does not hold, which includes every undated id such as claude-opus-5.

IAM evaluates at call time, so a running gateway can invoke Bedrock seconds after the attach. No redeploy.

3
Configure the provider

Console → Providers → add bedrock. Set the region you enabled model access in, and either both key fields or neither.

Blank key fields are the configuration, not a missing step: they select the workload role. An explicit pair takes precedence over the role, and one field without the other is rejected. Session token is optional, for temporary keys you set by hand.

4
Point your clients at the gateway
export OPENAI_BASE_URL=http://<gateway>:8787/v1
# Claude on Bedrock through Anthropic SDKs:
export ANTHROPIC_BASE_URL=http://<gateway>:8787
# requests carry: x-anyray-provider: bedrock

To make Bedrock the default for every request that pins no provider, set Console → Routing to mode single, target bedrock.

5
Send one request and find it in Traces
curl http://<gateway>:8787/v1/chat/completions \
-H "Authorization: Bearer <your-anyray-key>" \
-H "x-anyray-provider: bedrock" \
-H "Content-Type: application/json" \
-d '{"model":"claude-sonnet-4-5-20250929","messages":[{"role":"user","content":"reply with the word ok"}]}'

Console → Traces shows the call with provider bedrock, the model id, token counts, and a cost. A success with no row means the client is not going through the gateway.

Model ids

Clients send canonical Anthropic ids and the gateway converts them, so claude-sonnet-4-5-20250929 becomes us.anthropic.claude-sonnet-4-5-20250929-v1:0. It tries a built-in table of dated ids, then live discovery through the List actions, and otherwise forwards the id exactly as written. A native Bedrock id always works.

claude-opus-5, claude-sonnet-5, and claude-fable-5 are in no built-in table. They resolve only through discovery, so for them the List actions are required, not optional.

From v1.10.269 an undated id for a dated-only family resolves to the newest published snapshot. On earlier releases, send the dated id or set a model alias, which pins an exact id ahead of all resolution.

Resolution order, region-prefix rules, and per-region Claude 5 availability: Bedrock reference.

How developers enrol

Bedrock is an org-account lane. The credential lives on the gateway, and developers reach it with their personal gateway key, so there is no per-developer AWS credential to distribute.

curl -fsSL https://app.anyray.ai/i/tnt_… | sh -s -- --org

Pass --org explicitly even though the org account is the fallback. With no flag, a developer signed into a personal Claude plan bills that plan instead of your AWS account, silently. --subscription is the wrong flag here: it forwards a Claude or ChatGPT seat token, which never reaches Bedrock.

To assign the lane per user and team, or when only some developers should route to Bedrock: mixing both lanes.

Network access

The gateway reaches two AWS hostnames on port 443:

HostUsed for
bedrock-runtime.<region>.amazonaws.comEvery inference call. Required
bedrock.<region>.amazonaws.comModel-id discovery, the List actions. Optional

An egress allowlist naming only bedrock-runtime leaves inference working while discovery quietly fails, so include both. The CloudFormation stack needs no networking change. Private subnets and VPC endpoints: Bedrock reference.

Claude Code: CLAUDE_CODE_USE_BEDROCK bypasses the gateway

With CLAUDE_CODE_USE_BEDROCK (or CLAUDE_CODE_USE_VERTEX) set, Claude Code signs requests straight to the cloud provider and ignores ANTHROPIC_BASE_URL. Everything looks healthy and no request reaches Anyray, so there is no attribution, no spend data, and no savings. Connect disables the switch at apply time by pinning it empty in the user settings env block, which outranks a shell export. Restart Claude Code afterwards and the gateway serves Bedrock.

The exception is an IT-managed managed-settings.json, which outranks user scope. There Connect warns instead, and the admin who deploys that file must remove the switch.

Scoping the policy Resource

Name both the foundation-model and inference-profile ARNs, because Claude 4 and newer are profile-only in most regions:

Scoped resource
"Resource": [
"arn:aws:bedrock:*::foundation-model/anthropic.*",
"arn:aws:bedrock:*:<account-id>:inference-profile/*anthropic*"
]
Where the credential comes from

With no explicit key pair configured, the gateway uses the standard AWS credential chain: an ECS or Fargate task role (not the task execution role), an EC2 instance profile, an EKS service-account role (IRSA), or standard AWS environment and shared-config credentials. Role credentials are short-lived and Anyray never stores them.

On the CloudFormation deployment, attach the policy to the stack's TaskRole as a managed policy, never inline. The template reconciles inline policies on every stack update and can remove one you added by hand (role mechanics).

A gateway with no AWS workload identity, or a Bedrock account different from the gateway's, uses a static key pair instead: static keys and cross-account access.

Troubleshooting

What you seeCause and fix
AWS credentials were not found (500)No key pair configured and no role reachable from the workload. Attach the policy to the role the gateway runs as (on ECS, the task role, not the execution role), or fill in the access-key pair.
AWS access key ID and secret access key must be configured together (400)Only one of the two fields is set. Set both, or clear both to fall back to the role.
AccessDeniedExceptionModel access is not granted for that model in that region, or the policy omits the inference-profile ARN.
ValidationException on the model idAn id that needed discovery without the List actions granted, an undated id for a dated-only family on a gateway older than v1.10.269, or a region with no profile for that model. Grant the List actions, or pin the exact Bedrock id with a model alias.
ResourceNotFoundException asking for the use-case formBedrock evaluates the attestation per principal. Submit the form as the IAM user or role that is calling (how).
Requests succeed, nothing in the consoleThe client is signing to AWS directly. Unset CLAUDE_CODE_USE_BEDROCK and restart it.
Bedrock worked, then stopped after a stack updateAn inline policy on a CloudFormation-managed role was reconciled away. Re-add it as a managed-policy attachment.