,

Amazon Bedrock Guardrails, Content Filters, and Grounding Checks (AWS Gen AI Series, Part 14)

Amazon Bedrock Guardrails inspects text into and out of a model across six policies. Where each fits, how to call it inline and standalone, what it costs, and where it trips you in production.

AWS Gen AI Series · Part 14 of 30

A model in production will eventually produce a sentence you cannot defend. A made-up policy. A competitor named in a recommendation. A caller’s phone number read back in the clear. The model has no idea it did anything wrong, because to the model it was all just the next likely token.

Key takeaways: Amazon Bedrock Guardrails is a policy layer that inspects text going into a model and coming out of it, and blocks or rewrites what breaks your rules. It carries six independent policies: content filters, denied topics, word filters, sensitive information filters, contextual grounding checks, and Automated Reasoning checks. You wire it in two ways. Pass a guardrail id on a Converse or InvokeModel call and it runs inline, or call ApplyGuardrail on its own to screen any text, including output from a model that has nothing to do with Bedrock. Pricing is per text unit, one unit per 1,000 characters, at 0.15 dollars per 1,000 units for content filters and for denied topics, with sensitive information filters free and blocked requests not charged. The catch most teams meet is latency and over-blocking, not cost.

The agent you built in Part 13 can now take actions in the world, which is exactly when you want a fence around what it says and does. This part is that fence. I define every policy the first time it appears, show both ways to call the service, work the real cost, and spend the back half on where it trips people, because the failures here are quiet ones.

Prerequisites: You have called a Bedrock model with the Converse API from Part 11 and you know what an input prompt and a model response are. No safety or moderation background assumed. I define text units, denied topics, contextual grounding, and Automated Reasoning as they come up. If you have never made a Bedrock call, start at Part 1 first.

What Guardrails checks, and where it sits

A guardrail is a set of rules Bedrock applies to text before it reaches the model and again before the model’s reply reaches the user. It sits in the request path on both sides. On the way in, it reads the user prompt and can block it, so a prompt that tries to jailbreak the model or asks for something off-limits never gets generated against. On the way out, it reads the model’s response and can block or mask it, so an answer that names a banned topic or leaks a Social Security number never lands in front of the user. Same rules, two checkpoints.

The important design point is that a guardrail is its own resource, not a setting on a model. You create it once, give it a version, and then attach it to as many model calls as you like. That separation is what lets one moderation policy cover every application in an account, and it is why the same guardrail can screen a Bedrock model on one call and a model running somewhere else on the next. The model does the reasoning. The guardrail decides what is allowed to pass in either direction.

A guardrail checks both directionsInput is screened before generation, output before it reaches the userUser promptthe requestInput checkblock or passModelgeneratesOutput checkblock or maskUserblocked messageblocked messageA block on either side returns your configured message instead of model text.
One guardrail, two checkpoints. Either side can stop the call before the user sees anything.

The six policies you turn on

A guardrail is built from six policy types, and each one is optional and configured on its own. You enable the ones your application needs and leave the rest off. Understanding what each catches, and what it does not, is the whole job of setting one up well.

PolicyWhat it catchesYou configure
Content filtersHate, Insults, Sexual, Violence, Misconduct, Prompt AttackA strength per category, on input and output
Denied topicsSubjects you declare off-limits for this appA short name and a plain description each
Word filtersSpecific words, profanity, custom block listsYour word list plus the managed profanity set
Sensitive informationPII such as names, emails, card and account numbersBlock or mask, per PII type or regex
Contextual groundingAnswers not grounded in a supplied source, or off topicA grounding and a relevance threshold
Automated ReasoningClaims that break a set of encoded logical rulesA policy built from your source documents

Content filters and denied topics are the two most teams start with. Sensitive information is free and worth enabling almost everywhere.

A few of these deserve a plain-language definition. A denied topic is a subject you describe in a sentence or two, such as investment advice for a bank’s support bot, and the guardrail keeps the conversation off it without you listing every phrasing. Sensitive information filters detect personally identifiable information, the fields that identify a real person, and either block the response or mask the value so an email or card number comes back as a placeholder. Contextual grounding is the hallucination check: give it the source passages and the user question, and it scores whether the answer actually followed from the source, so a confident invention gets caught. Automated Reasoning is the newest and most specialized, turning a body of policy documents into formal logical rules and checking model claims against them, which is how you catch an answer that is fluent but logically wrong.

Classic tier or Standard tier?

Content filters and denied topics come in two tiers, and the choice changes how well they hold up against real inputs. The Classic tier is the original detection. The Standard tier, added in mid 2025, detects the same categories but with better resistance to the tricks that get past a naive filter: typos, spacing, and rephrasings, along with support for up to 60 languages and detection of harmful content hidden inside code, such as comments and string literals. The price is the same for both tiers, so the tradeoff is not money.

The tradeoff is the routing. Standard tier requires you to opt in to cross-region inference, which means a request can be served from a model in another Region inside the same geography to find capacity. For a lot of workloads that is fine and already how they run. For a workload with strict data residency rules, it is a real constraint you have to clear before you turn Standard on. My default is Standard for its stronger detection and its language coverage, and I only fall back to Classic when residency rules forbid the cross-region hop. Decide this deliberately, because it touches where your data is processed. [VERIFY current tier language count and cross-region requirement]

Gotcha: The blocked message a guardrail returns is your text, not the model’s. If you leave it at the default, users hit a generic refusal that tells them nothing, and support tickets follow. Write a blocked message that explains what happened and what to do next, and write a different one for input blocks than for output blocks, because the two situations mean different things to the person on the other side.

Two ways to call a guardrail

The first way is inline. Pass a guardrailIdentifier and a guardrailVersion on your Converse or InvokeModel call, and Bedrock runs the guardrail on the input and the output as part of the same request. This is the path you want when the model is a Bedrock model and you are already calling it, because there is one call and the guardrail is part of it. The response tells you whether the guardrail intervened, so your code can branch on a block.

resp = bedrock.converse(
    modelId='amazon.nova-pro-v1:0',
    guardrailConfig={'guardrailIdentifier': 'gr-abc123',
                     'guardrailVersion': 'DRAFT'},
    messages=[{'role': 'user', 'content': [{'text': user_input}]}],
)
print(resp['stopReason'])   # guardrail_intervened when a policy fires

The second way is standalone, and it is the one that surprises people. The ApplyGuardrail API runs a guardrail against any text you hand it, with no model call at all. That means you can screen the output of a self-hosted model, a model on another provider, or text from anywhere in your pipeline, and get a consistent policy decision across all of them. It is also how you check a retrieved passage before it ever reaches the model. Here is a full call that screens a model answer on the output side.

import boto3
bedrock = boto3.client('bedrock-runtime', region_name='us-east-1')

resp = bedrock.apply_guardrail(
    guardrailIdentifier='gr-abc123',
    guardrailVersion='DRAFT',
    source='OUTPUT',                         # or INPUT
    content=[{'text': {'text': model_answer}}],
)

print(resp['action'])                        # NONE or GUARDRAIL_INTERVENED
if resp['action'] == 'GUARDRAIL_INTERVENED':
    print(resp['outputs'][0]['text'])        # your blocked or masked text
    for a in resp['assessments']:
        print(list(a.keys()))                # which policy fired
Expected output: action prints NONE for clean text, or GUARDRAIL_INTERVENED with the replacement text and the name of the policy that fired, such as a content filter or a sensitive information rule. Failure mode: a ValidationException on source means it must be exactly INPUT or OUTPUT. A ThrottlingException means you passed the ApplyGuardrail request rate, so batch your checks or ask for a quota increase before you fan out. Field names in the assessment payload are precise; confirm them against the current API reference before you ship. [VERIFY]

Before you change production

Attaching a guardrail to a live endpoint changes what real users receive on the next request, and a strict setting can start blocking valid traffic immediately. Test against the DRAFT version, cut a numbered version, point production at that version deliberately, and keep the previous version so you can roll back in one call. Watch the block rate for the first hour. This is general guidance, not a substitute for your own change review.

How grounding and Automated Reasoning catch a hallucination

These two policies target the failure the content filters cannot see: an answer that is polite, on topic, and wrong. Contextual grounding needs three things on the call, the source passages, the user question, and the model answer, and it returns two scores between 0 and 1. The grounding score measures how well the answer is supported by the source. The relevance score measures how well it addresses the question. You set a threshold on each, and an answer that falls below either gets blocked. Pair this with the knowledge base from Part 12 and the source passages are already in hand, which makes grounding the natural output check for a retrieval application.

Automated Reasoning goes further and is more work to set up. You feed it your policy documents, and it builds a formal logical model of the rules in them. At check time it tests the model’s claims against that logic and can tell you a statement is valid, invalid, or unsupported by the rules, rather than just scoring a similarity. That precision is worth it for regulated answers where a wrong statement has consequences, and it is overkill for a general chatbot. Start with grounding, which covers most retrieval hallucinations for a fraction of the effort, and reach for Automated Reasoning only where the cost of a confident-but-wrong answer is high. [VERIFY Automated Reasoning current availability and status]

What Guardrails costs

Guardrails bills per text unit, where one text unit is up to 1,000 characters of the text it evaluates. Content filters cost 0.15 dollars per 1,000 text units, and denied topics cost the same, each charged for whichever text you screen through it. Sensitive information filters are free. And a request the guardrail blocks is not billed, so the money follows the text that actually passes through a paid policy. Contextual grounding and Automated Reasoning are priced on their own meters, which you should confirm before you lean on them. [VERIFY grounding and Automated Reasoning rates]

Worked example

A support chatbot handles 100,000 requests a month. Each request screens about 2,000 characters total, the input prompt plus the model answer, which rounds to 2 text units per request. Turn on content filters and denied topics on both sides, and each request passes 2 units through each of the two paid policies. Content filters cost 100,000 times 2 units at 0.15 dollars per 1,000 units, about 30 dollars. Denied topics cost the same, about 30 dollars. Sensitive information filtering runs on every request for free.

Total guardrail spend is roughly 60 dollars a month at 100,000 requests, on top of the model tokens. That is small next to the model bill, and it stays a straight line as volume grows because there is no fixed floor here. The real cost of Guardrails is rarely the invoice. It is the latency each check adds and the valid traffic a strict setting blocks.

PolicyRateUnits per requestMonthly at 100k
Content filters0.15 per 1,000 units230 dollars
Denied topics0.15 per 1,000 units230 dollars
Sensitive informationFree20 dollars
Total, paid policies60 dollars

Grounding and Automated Reasoning sit on separate meters and are left out of this total; verify their rates before enabling.

Monthly guardrail cost by policy100,000 requests, 2 text units each, US dollars010203030content filters30denied topics0sensitive info
Two paid policies at 30 dollars each. Sensitive information filtering adds nothing to the bill.

Plot the paid total against request volume and the line is flat and cheap. Ten thousand requests is about 6 dollars, a hundred thousand about 60, a million about 600, all on paid content filters and denied topics. There is no capacity floor to amortize and no step change, so cost is never the reason to skip Guardrails. Latency is the number to design around, since each check adds time to the request, and a strict configuration blocking real users is the risk that actually costs you.

Paid guardrail cost as requests growContent filters plus denied topics, US dollars per month020040060010k100k1M660600
A straight line with no floor. Cost never argues against turning Guardrails on.

Where Guardrails trips you in production

The first trap is over-blocking. Set every content filter to its highest strength on day one and you will block valid questions along with the bad ones, because a high filter reads borderline language as a violation. A medical support bot set too strict refuses to discuss symptoms. Start each filter at a middle strength, watch the block rate against real traffic, and tighten only the categories that actually let bad content through. The right setting is the one your traffic proves, not the strictest one available.

The second is latency. Every guardrail check is work in the request path, and on a streaming response the output check has to buffer enough text to evaluate before it releases tokens, which users feel as a pause. It is usually worth it, but you have to measure it and decide, not assume it is free. The third is scope confusion: an inline guardrail on a Converse call screens that call, and nothing else. If your application also pulls context from a knowledge base or calls a tool, that text is not screened unless you screen it, which is exactly what ApplyGuardrail is for. A guardrail covers the text you route through it and not one character more.

My take

I treat Guardrails as required on anything user-facing, and I turn on sensitive information filtering everywhere because it is free and catches the leak that embarrasses you most. But I do not trust a guardrail as the only line. It is a strong second layer over a well-written system prompt and a model chosen for the job, not a substitute for either. The mistake I see is teams cranking every filter to maximum, watching valid traffic get blocked, and then turning the whole thing off in frustration. Middle settings, measured against real traffic, tuned per category, beat both extremes. Contextual grounding is the policy I would add second, right after content filters, on any retrieval app. The failure I see most is a hate or violence filter set to maximum on a support bot that legitimately discusses account security, so valid tickets get blocked, users complain, and the team switches the guardrail off instead of dialing one category down. Tune per category against real traffic and you keep the protection without the collateral damage.

Start with denied topics and grounding, tune the filters against real traffic

Here is the posture I ship. Create one guardrail as its own resource and attach it across your applications rather than rebuilding a policy per app. Turn on sensitive information filtering everywhere, since it is free and stops the worst leaks. Add content filters at a middle strength and denied topics described in plain sentences, then watch the block rate on real traffic and tune per category instead of guessing. On any retrieval application add contextual grounding as the output check, because it catches the confident hallucination the content filters never see. Save Automated Reasoning for regulated answers where a wrong claim has a real cost. Prefer the DRAFT version while you tune, cut a numbered version before production, and keep the last one so a rollback is one call.

Use the inline guardrailIdentifier when you own the Bedrock call, and ApplyGuardrail when the text comes from a self-hosted model, another provider, a retrieved passage, or a tool result, so one policy covers your whole pipeline. If you also build on Azure, its equivalent is Azure AI Content Safety, covered in the Azure Gen AI guide. Next in this series I move from safety to control of the prompt itself, with Prompt Management, Flows, and caching, where the guardrail you just built becomes one stage in a managed pipeline. Before you read on, run one ApplyGuardrail call against your ugliest test prompt and read which policy fires. That is the fastest way to feel where your fence actually stands.

AWS Gen AI Series · Part 14 of 30
« Previous: Part 13  |  Guide  |  Next: Part 15 »

Related reading: the vendor-neutral guide to guardrails and responsible AI explains what these checks catch and miss at the concept level, without the Bedrock specifics.

References

Detect and filter harmful content with Amazon Bedrock Guardrails
Use contextual grounding check to filter hallucinations
Use the ApplyGuardrail API in your application
Amazon Bedrock pricing

About The Author


Discover more from Journal of Intelligent Infrastructure – By Dr Pranay Jha

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure - By Dr Pranay Jha

Subscribe now to keep reading and get access to the full archive.

Continue reading