Route Enterprise AI Traffic to AWS Bedrock
Proxy Amazon Bedrock requests through API7 Gateway with SigV4-signed IAM credentials, regional endpoints, and inference profiles.
Amazon Bedrock provides access to foundation models from Anthropic, Meta, Mistral, Amazon and others behind a single AWS-native API, with IAM authentication and regional endpoints. This guide shows how to route traffic to Bedrock through API7 Gateway using the ai-proxy (opens in Plugin Hub docs) plugin.
The gateway talks to Bedrock's Converse API, so clients keep sending OpenAI-style chat completion requests and the gateway performs the translation and the SigV4 signing.
Prerequisites
-
Install cURL to send requests to the services for validation.
-
Have a running API7 Gateway instance.
-
Have an AWS account with model access granted for the models you intend to use, in the region you intend to use them.
-
Create a token from the Dashboard and save it to an environment variable:
export API_KEY=your-dashboard-token # replace with your Dashboard token -
Replace
{gateway_group_id}with your gateway group ID. Usedefaultif you are following the quickstart. -
If you are following the Admin API examples, create or reuse a service in API7 Gateway. If you do not have one yet, follow Create or Reuse a Service, then save its ID to an environment variable:
export SERVICE_ID=your-service-id # replace with your service ID
Configure AWS Credentials
Create an IAM identity whose policy allows bedrock:InvokeModel and bedrock:InvokeModelWithResponseStream on the models you will call, then save its access key to environment variables:
export AWS_ACCESS_KEY_ID=your-access-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-access-keyThe gateway signs every request with SigV4 using these credentials.
The gateway needs a static access key. It does not assume an IAM role or read the instance metadata service, so an instance profile on the gateway host is not used. Scope the key's policy to the specific model ARNs it needs, and rotate it on your usual schedule.
If you issue temporary credentials with STS, pass the third field as well and re-apply the configuration before they expire:
"auth": { "aws": { "access_key_id": "...", "secret_access_key": "...", "session_token": "..." } }Configure the AI Proxy for Bedrock
Create a route with the ai-proxy (opens in Plugin Hub docs) plugin:
curl -k "https://localhost:7443/apisix/admin/routes?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
--data-binary @- <<REQ
{
"id": "bedrock-route",
"service_id": "$SERVICE_ID",
"paths": ["/bedrock"],
"plugins": {
"ai-proxy": {
"provider": "bedrock",
"provider_conf": {
"region": "us-east-1"
},
"auth": {
"aws": {
"access_key_id": "$AWS_ACCESS_KEY_ID",
"secret_access_key": "$AWS_SECRET_ACCESS_KEY"
}
},
"options": {
"model": "anthropic.claude-3-5-sonnet-20240620-v1:0"
}
}
}
}
REQ❶ Set the provider to bedrock and the AWS region. provider_conf.region is required: it selects the bedrock-runtime.<region>.amazonaws.com endpoint and is part of the SigV4 signature, so a configuration without it is rejected.
❷ Supply the IAM credentials. auth.aws is required for this provider, and access_key_id and secret_access_key are both mandatory within it.
❸ Set the model. This is optional — see Choosing the model.
services:
- name: Bedrock Service
routes:
- uris:
- /bedrock
name: bedrock-route
plugins:
ai-proxy:
provider: bedrock
provider_conf:
region: us-east-1
auth:
aws:
access_key_id: ${AWS_ACCESS_KEY_ID}
secret_access_key: ${AWS_SECRET_ACCESS_KEY}
options:
model: anthropic.claude-3-5-sonnet-20240620-v1:0❶ Set the provider to bedrock and the AWS region. provider_conf.region is required: it selects the bedrock-runtime.<region>.amazonaws.com endpoint and is part of the SigV4 signature, so a configuration without it is rejected.
❷ Supply the IAM credentials. auth.aws is required for this provider, and access_key_id and secret_access_key are both mandatory within it.
❸ Set the model. This is optional — see Choosing the model.
Synchronize the configuration to API7 Gateway:
adc sync -f adc.yamlChoosing the model
options.model accepts either form Bedrock recognizes:
| Form | Example |
|---|---|
| Model ID | anthropic.claude-3-5-sonnet-20240620-v1:0 |
| Inference profile ARN | arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/abc123 |
Unlike most providers, options.model is not required. If you leave it out, the model comes from each request's model field, which lets one route serve several models. When options.model is set it wins, and the client's model is ignored. If neither is present at request time, the gateway answers HTTP 400.
A colon in a model ID is not a problem: the gateway URL-encodes the model into a single path segment before signing.
Validate the Configuration
Send a chat completion request:
curl "http://127.0.0.1:9080/bedrock" -X POST \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "You are a mathematician." },
{ "role": "user", "content": "What is 1+1?" }
]
}'You should receive a response similar to the following:
{
"object": "chat.completion",
"model": "anthropic.claude-3-5-sonnet-20240620-v1:0",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "1 + 1 = 2"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 16,
"completion_tokens": 9,
"total_tokens": 25
}
}To enable streaming responses, set "stream": true in the request body. The gateway switches to Bedrock's converse-stream endpoint and converts its response for you.
Bedrock streams with the AWS event stream framing rather than server-sent events, and the gateway translates it into the SSE format clients expect. This is invisible to a client, but it means a proxy between the gateway and Bedrock that assumes SSE will corrupt the stream.
As with other providers, use the proxy-buffering (opens in Plugin Hub docs) plugin to disable NGINX proxy_buffering so events are not held back.
Troubleshooting
| Symptom | Likely cause | Resolution |
|---|---|---|
The configuration is rejected with bedrock requires provider_conf.region | The region is missing. | Add provider_conf.region. It is required even when you set override.endpoint. |
The configuration is rejected with bedrock requires auth.aws | Credentials are missing, or were put under auth.header. | Move them to auth.aws. Bedrock is signed, not bearer-authenticated. |
HTTP 400 with no model named | Neither options.model nor a model field in the request body was present. | Set one of the two. |
HTTP 403 from Bedrock | The IAM policy does not allow the action, or model access was never granted for that model in that region. | Check both: the policy, and the model access page in the Bedrock console for the region in provider_conf.region. |
HTTP 403 with a signature error | The signing region does not match the endpoint, or the credentials expired. | Confirm provider_conf.region, and refresh session_token if you are using temporary credentials. |
Next Steps
You have learned how to route traffic to AWS Bedrock through API7 Gateway. See the Bedrock documentation and the supported models for more details.
- Multi-LLM Routing and Fallback — Route across regions or failover to other providers.
- Anthropic — Reach the same Claude models through Anthropic's own API instead.
- AI Observability and Cost Tracking — Track token usage per model.