AWS Bedrock Guardrails
AWS Bedrock Guardrails keep content policy in AWS, and AISIX applies the guardrail decision to gateway traffic. Requests can be checked before they reach the upstream model, and responses can be checked before they reach callers.
In this guide, you will create an AISIX Bedrock guardrail, send one allowed request, and send one blocked request that AISIX rejects before it reaches the upstream model.
Prerequisites
Before starting, prepare the following:
- Review Guardrail Behavior for hook points, enforcement modes, and remote failure handling.
- One of these configuration paths:
- AISIX Cloud with an environment, an attached gateway, and a write-scoped admin token. For On-Premises, follow the AISIX Cloud Quickstart. To request Hybrid Cloud access, contact API7.
- An open-source AISIX gateway that loads a declarative
resources.yamlfile.
- A working model alias and caller API key that can send Chat Completions requests.
- An AWS Bedrock guardrail in a supported region, with a word filter that blocks a unique test token such as
confidential-codename. - AWS credentials allowed to call
bedrock:ApplyGuardrailfor that guardrail. curl. The AISIX Cloud path also usesjq.
Create a Bedrock Guardrail
The example below checks both requests and responses with a Bedrock guardrail. Choose one configuration path, then use the shared verification procedure.
Export the gateway values used by both paths:
# AISIX_PROXY has no trailing slash or endpoint path.
# The local quickstarts use http://127.0.0.1:3000.
export AISIX_PROXY="YOUR_AISIX_GATEWAY_URL"
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
export AISIX_MODEL="gpt-4o-mini"
export AWS_ACCESS_KEY_ID="YOUR_AWS_ACCESS_KEY_ID"
export AWS_SECRET_ACCESS_KEY="YOUR_AWS_SECRET_ACCESS_KEY"
AISIX Cloud
Export the control-plane connection details:
# AISIX_CP includes /api and has no trailing slash.
# The local On-Premises quickstart uses http://localhost:8080/api.
export AISIX_CP="YOUR_AISIX_CLOUD_ADMIN_API_BASE_URL"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
export ENV_ID="YOUR_ENVIRONMENT_ID"
Create a Bedrock guardrail in AISIX, and capture its ID for the attachment step:
export GUARDRAIL_ID=$(curl -sS -X POST "$AISIX_CP/environments/$ENV_ID/guardrails" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "bedrock-review",
"enabled": false,
"hook_point": "both",
"fail_open": false,
"enforcement_mode": "block",
"kind": "bedrock",
"config": {
"guardrail_id": "YOUR_BEDROCK_GUARDRAIL_ID",
"guardrail_version": "DRAFT",
"region": "us-east-1",
"aws_credentials": {
"kind": "static",
"access_key_id": "'"${AWS_ACCESS_KEY_ID}"'",
"secret_access_key": "'"${AWS_SECRET_ACCESS_KEY}"'"
},
"output_fail_open": false,
"latency_mode": {
"kind": "timed",
"timeout_ms": 2000
}
}
}' | jq -r '.guardrail.id')
❶ both checks caller requests and model responses. See Guardrail Hook Point.
❷ fail_open: false blocks the request if AWS Bedrock Guardrails fails or times out. The default is true.
❸ enforcement_mode: block rejects matching content. This is the default. See Enforcement Modes.
❹ output_fail_open: false blocks unscanned model output during a Bedrock outage. This is the default.
❺ latency_mode bounds how long AISIX waits for the guardrail decision. Set kind to serial to wait without a timeout.
A guardrail takes effect only after it is attached to a scope. Attach it to the whole environment:
curl -sS -X POST "$AISIX_CP/environments/$ENV_ID/guardrails/$GUARDRAIL_ID/attachments" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"scope_type": "env"
}'
The env scope applies the guardrail to all traffic in the environment and takes no scope_id. Use model, api_key, or team with a matching scope_id to narrow the attachment.
Enable the guardrail after its attachment exists:
curl -sS -X PATCH "$AISIX_CP/environments/$ENV_ID/guardrails/$GUARDRAIL_ID" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
The enabled configuration projects to attached gateways automatically.
Open-Source AISIX Gateway
Add the guardrail to the resources file that already defines the example model and caller API key. The example reads credentials from AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. A running quickstart container does not inherit these variables from later host exports.
guardrails:
- name: bedrock-review
enabled: true
hook_point: both
fail_open: false
enforcement_mode: block
kind: bedrock
guardrail_id: YOUR_BEDROCK_GUARDRAIL_ID
guardrail_version: DRAFT
region: us-east-1
aws_credentials:
kind: static
access_key_id: ${AWS_ACCESS_KEY_ID}
secret_access_key: ${AWS_SECRET_ACCESS_KEY}
output_fail_open: false
latency_mode:
kind: timed
timeout_ms: 2000
The provider fields sit directly on the guardrail entry rather than under config. Every enabled guardrail in the resources file applies to every request handled by that gateway.
Apply the change by validating the complete file before reloading or recreating the gateway. If you are extending the open-source quickstart, follow Reload a Resources File to recreate the container only after validation succeeds and pass the additional credential variables.
Verify the Guardrail
AISIX Cloud projection is asynchronous. If the first request does not reflect the guardrail, wait for the gateway to apply the latest revision and retry. See Resource Projection for convergence checks.
Send a benign request through AISIX:
curl -sSi -X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${AISIX_MODEL}"'",
"messages": [
{
"role": "user",
"content": "What is the capital of France?"
}
]
}'
A successful response starts with HTTP/1.1 200 OK and returns an OpenAI-compatible chat-completions body.
Then send a request containing the token blocked by your Bedrock guardrail:
curl -sSi -X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${AISIX_MODEL}"'",
"messages": [
{
"role": "user",
"content": "Please print the confidential-codename."
}
]
}'
A blocked response starts with HTTP/1.1 422 Unprocessable Entity and includes an OpenAI-compatible error:
{
"error": {
"message": "request blocked by content policy (guardrail 'bedrock-review')",
"type": "content_filter"
}
}
AISIX blocks the request before dispatching to the upstream model when the input guardrail returns a blocking verdict.
PII Anonymization (Masking)
Bedrock guardrails can be configured in AWS to anonymize sensitive information instead of blocking it. Matched values are replaced with placeholders such as {EMAIL} or {PHONE}. AISIX honors that disposition without extra AISIX configuration; the behavior follows the PII action set on the Bedrock guardrail itself:
- Block actions for topic, content, and word policies, contextual grounding, and PII entities or regexes set to Block reject the request or response with the
422envelope shown above. - Anonymize actions rewrite the matched values with Bedrock's masked text and let the traffic continue. On the request side, the upstream model receives the masked text. On the response side, the caller receives the masked reply. Streaming responses are held back, scanned once, masked, and then released, so a value split across chunks cannot leak.
For example, with a Bedrock guardrail whose Email PII entity is set to Anonymize:
curl -sS -X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${AISIX_MODEL}"'",
"messages": [
{
"role": "user",
"content": "Draft a reply to alice@example.com about the invoice."
}
]
}'
The request succeeds, and the upstream model receives Draft a reply to {EMAIL} about the invoice. The upstream model never receives the raw address. The request's usage event records masked entity type names only, never the matched values.
Masking applies on /v1/chat/completions, /v1/messages, /v1/responses, and /v1/completions, for both direct and cross-provider traffic. On endpoints that do not support masking, such as embeddings, rerank, images, and audio, AISIX blocks the request when the Bedrock guardrail anonymizes it. AISIX cannot rewrite those payloads, and forwarding them unmasked would defeat the policy.
If Bedrock returns masked output that cannot be attributed back to the request's individual text segments, AISIX does not apply the rewrite and forwards the content unmodified instead. This avoids writing masked text into the wrong message and corrupting the conversation. Hard-block policies are unaffected by this fallback.
Next Steps
You have now enforced an AWS Bedrock guardrail through AISIX. Use these guides to tune behavior or compare other providers:
- Guardrail Behavior: adjust hook points, enforcement mode, streaming output, or remote failure handling.
- Choosing a Guardrail Provider: compare AWS Bedrock Guardrails with other built-in and remote options.
- Azure AI Content Safety Guardrails: configure category moderation or prompt-shield checks in Azure.