
Amazon Bedrock Guardrails — Complete Setup Guide
Block harmful content, redact PII, and stop hallucinations in any Bedrock app. Step-by-step guide with code for content filters, denied topics, and grounding checks
How to Add Guardrails to Any Amazon Bedrock App — Block Harmful Content, Redact PII, and Stop Hallucinations
TL;DR: Amazon Bedrock Guardrails lets you apply content filtering, PII redaction, topic blocking, and grounding checks to any model — in under 30 lines of config. Here's how to set it up, test it, and deploy it in production.
Why Every Production AI App Needs This
Most Bedrock tutorials show you how to call a model. Almost none show you what happens when a user asks your AI something they shouldn't.
At STC, the first question every enterprise client asks before go-live is: "What stops the AI from saying something that gets us sued?"
The answer is Bedrock Guardrails. It's AWS's managed layer that sits between your app and the model — and it works on every model in the Bedrock catalogue.
Here's how to build it properly.
What Guardrails Can Do
Feature | What it blocks |
|---|---|
Content filters | Hate speech, violence, sexual content, self-harm, insults |
Denied topics | Any subject you define (e.g. "competitor products", "legal advice") |
Word filters | Specific words or phrases |
PII redaction | Names, emails, phone numbers, SSNs, credit card numbers, and more |
Grounding check | Detects hallucinations — flags responses not supported by your context |
Sensitive info filter | Custom regex patterns for your own data formats |
Step 1: Create a Guardrail
You can create a Guardrail via the console or programmatically. Here's the full config in Python:
Python
import boto3bedrock = boto3.client('bedrock', region_name='us-east-1')response = bedrock.create_guardrail(name='production-guardrail',description='Content safety and PII protection for customer-facing AI',# Block harmful content categoriescontentPolicyConfig={'filtersConfig': [{'type': 'SEXUAL', 'inputStrength': 'HIGH', 'outputStrength': 'HIGH'},{'type': 'VIOLENCE', 'inputStrength': 'MEDIUM', 'outputStrength': 'HIGH'},{'type': 'HATE', 'inputStrength': 'HIGH', 'outputStrength': 'HIGH'},{'type': 'INSULTS', 'inputStrength': 'MEDIUM', 'outputStrength': 'MEDIUM'},{'type': 'MISCONDUCT', 'inputStrength': 'HIGH', 'outputStrength': 'HIGH'},{'type': 'PROMPT_ATTACK', 'inputStrength': 'HIGH', 'outputStrength': 'NONE'}]},# Block specific topics your app should never discusstopicPolicyConfig={'topicsConfig': [{'name': 'Legal advice','definition': 'Providing specific legal advice, interpreting contracts, or recommending legal action','examples': ['Should I sue my employer?','Is this contract enforceable?','What are my legal rights here?'],'type': 'DENY'},{'name': 'Competitor products','definition': 'Discussion of specific competitor products or services in comparison to ours','examples': ['How does your product compare to Salesforce?','Why should I use you instead of ServiceNow?'],'type': 'DENY'}]},# Redact PII from both inputs and outputssensitiveInformationPolicyConfig={'piiEntitiesConfig': [{'type': 'NAME', 'action': 'ANONYMIZE'},{'type': 'EMAIL', 'action': 'ANONYMIZE'},{'type': 'PHONE', 'action': 'ANONYMIZE'},{'type': 'UK_NHS_NUMBER', 'action': 'BLOCK'},{'type': 'CREDIT_DEBIT_CARD_NUMBER', 'action': 'BLOCK'},{'type': 'AWS_ACCESS_KEY', 'action': 'BLOCK'},{'type': 'PASSWORD', 'action': 'BLOCK'}],# Block custom patterns — e.g. your internal employee IDs'regexesConfig': [{'name': 'EmployeeID','description': 'Internal employee ID format EMP-XXXXX','pattern': r'EMP-\d{5}','action': 'ANONYMIZE'}]},# What to say when guardrail blocks somethingblockedInputMessaging='I cannot process that request. Please rephrase or contact support.',blockedOutputsMessaging='I cannot provide that response. Please contact support for assistance.',)guardrail_id = response['guardrailId']guardrail_version = response['version']print(f"Guardrail created: {guardrail_id} (version {guardrail_version})")
Step 2: Apply the Guardrail to Model Calls
Adding a Guardrail to any Bedrock call is two extra parameters:
Python
import boto3import jsonbedrock_runtime = boto3.client('bedrock-runtime', region_name='us-east-1')GUARDRAIL_ID = 'your-guardrail-id'GUARDRAIL_VERSION = '1'def invoke_with_guardrail(prompt: str) -> dict:response = bedrock_runtime.invoke_model(modelId='anthropic.claude-3-haiku-20240307-v1:0',body=json.dumps({"anthropic_version": "bedrock-2023-05-31","max_tokens": 500,"messages": [{"role": "user", "content": prompt}]}),contentType='application/json',accept='application/json',# Add these two lines to any existing Bedrock callguardrailIdentifier=GUARDRAIL_ID,guardrailVersion=GUARDRAIL_VERSION,trace='ENABLED' # Returns details on what was filtered)result = json.loads(response['body'].read())# Check if guardrail intervenedheaders = response['ResponseMetadata']['HTTPHeaders']guardrail_action = headers.get('x-amzn-bedrock-guardrail-action', 'NONE')return {'text': result['content'][0]['text'],'guardrail_action': guardrail_action,'blocked': guardrail_action == 'GUARDRAIL_INTERVENED'}# Test itresult = invoke_with_guardrail("What is our refund policy?")print(result['text'])# Try a blocked topicresult = invoke_with_guardrail("Should I sue my employer for unfair dismissal?")print(result['blocked']) # Trueprint(result['text']) # "I cannot process that request..."
Step 3: Apply Guardrails to Knowledge Bases (RAG)
Guardrails work with
retrieve_and_generate too — same parameters:Python
import boto3bedrock_agent_runtime = boto3.client('bedrock-agent-runtime', region_name='us-east-1')KNOWLEDGE_BASE_ID = 'your-kb-id'GUARDRAIL_ID = 'your-guardrail-id'def rag_with_guardrail(question: str) -> str:response = bedrock_agent_runtime.retrieve_and_generate(input={"text": question},retrieveAndGenerateConfiguration={"type": "KNOWLEDGE_BASE","knowledgeBaseConfiguration": {"knowledgeBaseId": KNOWLEDGE_BASE_ID,"modelArn": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-haiku-20240307-v1:0","generationConfiguration": {"guardrailConfiguration": {"guardrailId": GUARDRAIL_ID,"guardrailVersion": "1"}}}})return response['output']['text']
Step 4: Add the Grounding Check (Stop Hallucinations)
The grounding check is the most powerful feature for RAG apps. It compares the model's response against the source documents and flags anything the documents don't support.
Python
import boto3bedrock = boto3.client('bedrock', region_name='us-east-1')# Add grounding check to your guardrailbedrock.update_guardrail(guardrailIdentifier='your-guardrail-id',name='production-guardrail',blockedInputMessaging='I cannot process that request.',blockedOutputsMessaging='I cannot provide that response.',groundingPolicyConfig={'filtersConfig': [{'type': 'GROUNDING','threshold': 0.75 # 0-1: higher = stricter},{'type': 'RELEVANCE','threshold': 0.75 # Block responses not relevant to the query}]})
To use grounding checks, pass your source documents in the API call:
Python
import boto3import jsonbedrock_runtime = boto3.client('bedrock-runtime', region_name='us-east-1')source_document = """Our standard refund policy: customers may return products within 30 daysof purchase for a full refund. Enterprise customers have a 60-day window.Digital products are non-refundable once downloaded."""response = bedrock_runtime.apply_guardrail(guardrailIdentifier='your-guardrail-id',guardrailVersion='1',source='OUTPUT', # Check model output, not inputcontent=[{"text": {"text": "Enterprise customers get a 90-day refund window.", # WRONG — will be flagged"qualifiers": ["grounding_source"]}},{"text": {"text": source_document,"qualifiers": ["grounding_source"]}}])print(response['action']) # GUARDRAIL_INTERVENED — response not groundedprint(response['assessments']) # Details on what failed
Step 5: Read the Trace to Understand What Fired
When
trace='ENABLED' , Bedrock returns a full breakdown of every check:Python
import boto3import jsonbedrock_runtime = boto3.client('bedrock-runtime', region_name='us-east-1')response = bedrock_runtime.invoke_model(modelId='anthropic.claude-3-haiku-20240307-v1:0',body=json.dumps({"anthropic_version": "bedrock-2023-05-31","max_tokens": 200,"messages": [{"role": "user", "content": "My email is test@company.com. What is the refund policy?"}]}),contentType='application/json',accept='application/json',guardrailIdentifier='your-guardrail-id',guardrailVersion='1',trace='ENABLED')result = json.loads(response['body'].read())# The trace is in the Amazon-Bedrock-Trace headerimport base64trace_header = response['ResponseMetadata']['HTTPHeaders'].get('amazon-bedrock-trace')if trace_header:trace = json.loads(base64.b64decode(trace_header))# See what PII was foundfor assessment in trace.get('guardrail', {}).get('inputAssessment', {}).values():pii_found = assessment.get('sensitiveInformationPolicy', {}).get('piiEntities', [])for pii in pii_found:print(f"PII detected: {pii['type']} — action: {pii['action']}")# Output: PII detected: EMAIL — action: ANONYMIZE
What Guardrails Cost
Guardrail pricing is per 1,000 text units processed:
Feature | Price |
|---|---|
Content filters | $0.75 per 1,000 text units |
Denied topics | $1.00 per 1,000 text units |
Word filters | $0.75 per 1,000 text units |
PII detection | $0.10 per 1,000 text units |
Grounding check | $0.10 per 1,000 text units |
At 10,000 queries/month with all features enabled: roughly $20–30/month. For the protection it provides, this is a no-brainer.
Guardrails Checklist for Production
Before you go live, tick these off:
- [ ] Content filters enabled for all harmful categories (at least MEDIUM strength)
- [ ] Denied topics defined for anything your app should never discuss
- [ ] PII redaction on both INPUT and OUTPUT
- [ ] Grounding check enabled if you're using RAG
- [ ] Trace enabled in staging — disabled in production (saves cost)
- [ ] Custom blocked messages that don't confuse users
- [ ] Guardrail ID stored in environment variables or Secrets Manager — not hardcoded
- [ ] CloudWatch alarm on guardrail intervention rate (spike = something's wrong)
Resources
I'm Meghana Rajagopal, lead Cloud & AI Delivery at STC (AWS Premier Partner) and AWS ML Engineer Associate. I write about practical AWS AI/ML solutions and architecture. Connect with me on LinkedIn .Follow for weekly AWS AI content.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article