Configure an AWS Bedrock Large Language Model provider¶
Connect API Platform AI Gateway directly to the regional AWS Bedrock Runtime endpoint. You can authenticate the gateway to Bedrock in either of these ways:
- Bearer authentication with an AWS Bedrock API key
- AWS Signature Version 4 (SigV4) with IAM credentials or a workload role
Both methods expose the native Bedrock Converse and ConverseStream operations through the gateway. They use the regional Bedrock Runtime endpoint, not the Bedrock Mantle endpoint. For a base model ID, choose an AWS Region where that model is available, and use the same Region in the Bedrock endpoint, SigV4 policy, and model ID. For an inference profile ID, invoke Bedrock through the source Region endpoint where the profile is supported; the profile may route requests to destination Regions. In this case, the SigV4 Region must match the source Region in the endpoint.
Before you begin¶
Make sure that:
- The AI Gateway is running and its management API is available at
http://localhost:9090/api/management/v1. - You have the gateway controller administrator username and password.
- Your model is available to your AWS account in the selected Region.
- You have either an AWS Bedrock API key or an IAM identity that can invoke the model.
curl7.76.0 or later is installed. Installjqas well if you want the commands to capture the generated gateway API key automatically.
Set the gateway administrator credentials:
export ADMIN_USERNAME="admin"
export ADMIN_PASSWORD="<gateway-admin-password>"
export AWS_REGION="<aws-region>"
For example, set AWS_REGION to us-east-1, us-west-2, or another Region where your selected Bedrock model is available.
Choose an authentication method¶
Use the following table to choose the authentication method that matches your gateway environment.
| Method | Recommended use |
|---|---|
| Bedrock bearer API key | Getting started and development environments |
| SigV4 with the default credential chain | Production gateways running with an Amazon Elastic Compute Cloud (EC2), Amazon Elastic Container Service (ECS), or Amazon Elastic Kubernetes Service (EKS) Pod Identity role |
| SigV4 with IAM Roles for Service Accounts (IRSA) | Gateways running on EKS with IRSA |
| SigV4 with AWS Security Token Service (STS) AssumeRole | Cross-account access or a gateway that must assume a dedicated Bedrock role |
| SigV4 with an IAM access key | Local testing when a workload role is unavailable |
Two different API keys
A Bedrock bearer API key authenticates the gateway to AWS. Later in this guide, you create a gateway consumer API key that authenticates your application to the gateway. Do not use one in place of the other.
Option 1: Bearer authentication¶
AWS Bedrock API keys are sent to the Bedrock Runtime endpoint in the Authorization: Bearer <key> header. AWS recommends short-term keys for production and long-term keys only for exploration.
Step 1: Generate a Bedrock API key¶
Follow the AWS instructions to generate an AWS Bedrock API key:
- Open the AWS Bedrock console in the Region where you will invoke the model.
- Generate a short-term or long-term API key.
- Copy the key when AWS displays it.
Short-term keys last for the current AWS session, up to 12 hours, and are recommended for production. Long-term keys have a configurable expiration and are intended for exploration and development.
The IAM identity associated with the key must be allowed to invoke the selected model. An organization-level deny on bedrock:CallWithBearerToken prevents the key from being used with the Bedrock endpoint.
Step 2: Store the Bedrock API key¶
Short-term Bedrock API keys cannot be refreshed or extended after they are issued. Replace the key before it expires, and update the gateway secret with the new value.
Do not use an AWS access key ID or secret access key as the bearer token.
Store the key as an encrypted gateway secret:
curl --fail-with-body -X POST \
http://localhost:9090/api/management/v1/secrets \
-u "$ADMIN_USERNAME:$ADMIN_PASSWORD" \
-H "Content-Type: application/yaml" \
--data-binary @- <<EOF
apiVersion: gateway.api-platform.wso2.com/v1
kind: Secret
metadata:
name: bedrock-api-key
spec:
displayName: AWS Bedrock API Key
value: "${AWS_BEARER_TOKEN_BEDROCK}"
EOF
Step 3: Deploy the provider¶
The provider references the stored key by name. The AWS_REGION value is expanded into the Bedrock Runtime endpoint.
curl --fail-with-body -X POST \
http://localhost:9090/api/management/v1/llm-providers \
-u "$ADMIN_USERNAME:$ADMIN_PASSWORD" \
-H "Content-Type: application/yaml" \
--data-binary @- <<EOF
apiVersion: gateway.api-platform.wso2.com/v1
kind: LlmProvider
metadata:
name: bedrock-provider
spec:
displayName: AWS Bedrock Provider
version: v1.0
template: awsbedrock
context: /bedrock
upstream:
url: https://bedrock-runtime.${AWS_REGION}.amazonaws.com
auth:
type: api-key
header: Authorization
value: 'Bearer {{ secret "bedrock-api-key" }}'
accessControl:
mode: deny_all
exceptions:
- path: /model/{modelId}/converse
methods: [POST]
- path: /model/{modelId}/converse-stream
methods: [POST]
policies:
- name: api-key-auth
version: v1
paths:
- path: /model/{modelId}/converse
methods: [POST]
params:
key: X-API-Key
in: header
- path: /model/{modelId}/converse-stream
methods: [POST]
params:
key: X-API-Key
in: header
EOF
Continue to Create a gateway consumer API key.
Option 2: SigV4 authentication¶
The aws-authentication policy signs each outbound request with SigV4. Do not configure spec.upstream.auth when using this option because the policy creates the AWS Authorization header.
See the AWS Authentication policy reference for the complete parameter and error-response reference.
All SigV4 examples use:
The service and Region must match the Bedrock Runtime endpoint. The policy supports four credential acquisition modes.
IAM access key¶
Use iam-user-access-key for local testing when the gateway cannot use a workload role. Store the credentials as gateway secrets instead of embedding them in the provider definition.
Set the AWS credentials in your current shell:
export AWS_ACCESS_KEY_ID="<aws-access-key-id>"
export AWS_SECRET_ACCESS_KEY="<aws-secret-access-key>"
Create a secret for each value:
curl --fail-with-body -X POST \
http://localhost:9090/api/management/v1/secrets \
-u "$ADMIN_USERNAME:$ADMIN_PASSWORD" \
-H "Content-Type: application/yaml" \
--data-binary @- <<EOF
apiVersion: gateway.api-platform.wso2.com/v1
kind: Secret
metadata:
name: bedrock-access-key-id
spec:
displayName: Bedrock AWS Access Key ID
value: "${AWS_ACCESS_KEY_ID}"
EOF
curl --fail-with-body -X POST \
http://localhost:9090/api/management/v1/secrets \
-u "$ADMIN_USERNAME:$ADMIN_PASSWORD" \
-H "Content-Type: application/yaml" \
--data-binary @- <<EOF
apiVersion: gateway.api-platform.wso2.com/v1
kind: Secret
metadata:
name: bedrock-secret-access-key
spec:
displayName: Bedrock AWS Secret Access Key
value: "${AWS_SECRET_ACCESS_KEY}"
EOF
Deploy the provider. The AWS_REGION value is expanded into both the Bedrock Runtime endpoint and the SigV4 policy configuration.
curl --fail-with-body -X POST \
http://localhost:9090/api/management/v1/llm-providers \
-u "$ADMIN_USERNAME:$ADMIN_PASSWORD" \
-H "Content-Type: application/yaml" \
--data-binary @- <<EOF
apiVersion: gateway.api-platform.wso2.com/v1
kind: LlmProvider
metadata:
name: bedrock-provider
spec:
displayName: AWS Bedrock Provider
version: v1.0
template: awsbedrock
context: /bedrock
upstream:
url: https://bedrock-runtime.${AWS_REGION}.amazonaws.com
accessControl:
mode: deny_all
exceptions:
- path: /model/{modelId}/converse
methods: [POST]
- path: /model/{modelId}/converse-stream
methods: [POST]
policies:
- name: aws-authentication
version: v0
paths:
- path: /model/{modelId}/converse
methods: [POST]
params: &bedrock-aws-auth
service: bedrock
region: ${AWS_REGION}
authenticationType: iam-user-access-key
awsAccessKeyID: '{{ secret "bedrock-access-key-id" }}'
awsSecretAccessKey: '{{ secret "bedrock-secret-access-key" }}'
- path: /model/{modelId}/converse-stream
methods: [POST]
params: *bedrock-aws-auth
- name: api-key-auth
version: v1
paths:
- path: /model/{modelId}/converse
methods: [POST]
params: &consumer-auth
key: X-API-Key
in: header
- path: /model/{modelId}/converse-stream
methods: [POST]
params: *consumer-auth
EOF
If the access key is temporary, create a third secret named bedrock-session-token and add this parameter to bedrock-aws-auth:
export AWS_SESSION_TOKEN="<aws-session-token>"
curl --fail-with-body -X POST \
http://localhost:9090/api/management/v1/secrets \
-u "$ADMIN_USERNAME:$ADMIN_PASSWORD" \
-H "Content-Type: application/yaml" \
--data-binary @- <<EOF
apiVersion: gateway.api-platform.wso2.com/v1
kind: Secret
metadata:
name: bedrock-session-token
spec:
displayName: Bedrock AWS Session Token
value: "${AWS_SESSION_TOKEN}"
EOF
Warning
Prefer short-lived credentials or workload roles for production. Rotate any IAM access key used for testing and remove it when it is no longer needed.
Default credential chain¶
Use default-credential-chain when the gateway workload already runs with the exact IAM role that can invoke Bedrock. This includes EC2 instance profiles, ECS task roles, and EKS Pod Identity associations.
In the provider payload from the preceding section, replace the bedrock-aws-auth parameters with:
params: &bedrock-aws-auth
service: bedrock
region: <aws-region>
authenticationType: default-credential-chain
Do not set an access key, secret access key, session token, or role Amazon Resource Name (ARN) for this mode. The AWS SDK resolves credentials from the gateway runtime environment.
IAM roles for service accounts¶
Use irsa when the gateway workload already has the required IAM role through IRSA. The gateway must run on EKS with an OpenID Connect (OIDC) provider and a Kubernetes service account associated with an IAM role. The EKS Pod Identity Webhook must inject AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN_FILE into the gateway pod.
Replace the bedrock-aws-auth parameters with:
params: &bedrock-aws-auth
service: bedrock
region: <aws-region>
authenticationType: irsa
awsRoleSessionName: bedrock-gateway-session
You can add awsRoleARN explicitly. If you omit it, the policy uses the injected AWS_ROLE_ARN value:
STS AssumeRole¶
Use sts-assume-role when the gateway must assume a dedicated or cross-account Bedrock role. The gateway first needs a source identity that is allowed to call sts:AssumeRole; the target role must trust that source identity.
Replace the bedrock-aws-auth parameters with:
params: &bedrock-aws-auth
service: bedrock
region: <aws-region>
authenticationType: sts-assume-role
awsRoleARN: arn:aws:iam::<target-account-id>:role/<bedrock-role>
awsRoleSessionName: bedrock-gateway-session
By default, the policy uses the gateway's AWS SDK credential chain as the source identity. You can instead provide awsAccessKeyID, awsSecretAccessKey, and, for temporary source credentials, awsSessionToken through gateway secrets.
For a cross-account role that requires an external ID, also add:
Configure IAM permissions for SigV4¶
Attach a least-privilege policy to the IAM user or role that invokes Bedrock. The following policy allows the non-streaming and streaming operations used in this guide:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "InvokeBedrockModels",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": [
"arn:aws:bedrock:<region>::foundation-model/<model-id>",
"arn:aws:bedrock:<region>:<account-id>:inference-profile/<inference-profile-id>"
]
},
{
"Sid": "ReadBedrockInferenceProfiles",
"Effect": "Allow",
"Action": "bedrock:GetInferenceProfile",
"Resource": "arn:aws:bedrock:<region>:<account-id>:inference-profile/<inference-profile-id>"
}
]
}
Replace the placeholder Amazon Resource Name (ARN) values with the model and inference profile resources the gateway is allowed to invoke. When you scope access to an inference profile, authorize both the inference profile ARN and the corresponding foundation model ARN in each destination Region that the profile can route to. See Prerequisites for running model inference for the complete AWS guidance.
For sts-assume-role, the source identity also needs sts:AssumeRole permission for the target role, and the target role's trust policy must trust the source identity.
Verify the provider¶
Retrieve the deployed provider:
curl --fail-with-body \
-u "$ADMIN_USERNAME:$ADMIN_PASSWORD" \
http://localhost:9090/api/management/v1/llm-providers/bedrock-provider
Create a gateway consumer API key¶
The provider examples protect the exposed routes with api-key-auth. Create a consumer key for the application that will call Bedrock through the gateway:
export GATEWAY_API_KEY=$(curl --fail-with-body -s -X POST \
http://localhost:9090/api/management/v1/llm-providers/bedrock-provider/api-keys \
-u "$ADMIN_USERNAME:$ADMIN_PASSWORD" \
-H "Content-Type: application/json" \
-d '{"name":"bedrock-client"}' \
| jq -r '.apiKey.apiKey')
Confirm that a key was returned:
The key value is returned only when it is created or regenerated. Store it securely.
Invoke Bedrock through the gateway¶
Set a base model ID that is available in the selected AWS Region, or an inference profile ID that is supported by the source Region configured in the Bedrock Runtime endpoint:
Call the native Bedrock Converse operation through the gateway:
export CA_CERT_PATH="<path-to-trusted-ca-certificate>"
curl --fail-with-body -X POST \
"https://localhost:8443/bedrock/v1.0/model/${BEDROCK_MODEL_ID}/converse" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GATEWAY_API_KEY" \
-d '{
"messages": [
{
"role": "user",
"content": [
{"text": "Reply with a short hello from AWS Bedrock."}
]
}
],
"inferenceConfig": {
"maxTokens": 64,
"temperature": 0.2
}
}' \
--cacert "$CA_CERT_PATH"
URL-encode the model ID if it contains characters that are not safe in a URL path.
If the gateway uses a certificate signed by a public or locally trusted certificate authority (CA), omit --cacert. For a local self-signed certificate, add the issuing CA certificate to your trust store or pass it with --cacert.
Troubleshooting¶
Bedrock returns AccessDeniedException¶
Confirm that the IAM identity can invoke the selected model in the configured Region. For streaming requests, it also needs bedrock:InvokeModelWithResponseStream.
The gateway returns 502 Bad Gateway¶
For SigV4, this usually means the policy could not retrieve AWS credentials or sign the request. Check the gateway logs and verify the selected credential mode. For default-credential-chain, confirm that the gateway workload actually has a usable AWS credential source.
AWS reports a signature mismatch¶
Confirm that service is bedrock and that the policy Region matches the Region in https://bedrock-runtime.<aws-region>.amazonaws.com.
IRSA fails during policy initialization¶
Confirm that the gateway pod has both AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN_FILE, and that the projected token file is readable. Also verify the role trust policy and its OIDC subject condition.
STS returns AccessDenied¶
Check both sides of the relationship: the source identity must be allowed to call sts:AssumeRole, and the target role's trust policy must trust the source identity.
Security recommendations¶
- Do not commit AWS access keys, session tokens, Bedrock API keys, gateway passwords, or external IDs.
- Prefer the default credential chain, IRSA, or STS AssumeRole over long-lived IAM user access keys.
- Use short-term Bedrock API keys for production bearer authentication, and rotate them before expiration because issued keys cannot be refreshed or extended.
- Restrict IAM permissions to the required model and inference profile resources.
- Expose only the required Bedrock operations through
accessControl. - Use HTTPS for Bedrock and production gateway endpoints.