Amazon Bedrock Guardrails for Agents
Guardrails are a configurable, model-independent policy layer that evaluates prompts and responses against content, topic, word, sensitive-information and grounding policies.
Amazon Bedrock Guardrails is a safety layer that sits around a model invocation rather than inside the model. You create a guardrail as a standalone resource, version it, and attach it to an InvokeModel or Converse call, to a Bedrock agent, or to a knowledge-base query. Because it is separate from the model, the same policy applies whether you switch from one foundation model to another, and it can be applied to text your own code produces via the ApplyGuardrail API — including models running outside Bedrock.
The policy types
- Content filters. Configurable strengths (none, low, medium, high) across harmful categories such as hate, insults, sexual, violence and misconduct, set independently for input and output. A separate prompt attack filter targets jailbreak and injection phrasing and applies to input only.
- Denied topics. You describe a topic in natural language, with a name, a definition and a few sample phrasings, and the guardrail refuses it. This is how you keep a banking assistant out of investment advice without enumerating keywords.
- Word filters. A managed profanity list plus your own custom word or phrase list — competitor names, an internal project code name.
- Sensitive information filters. Built-in PII entity types (email, phone, name, card numbers, national identifiers and more) plus your own regular expressions. Each entity is set to block the request outright or to mask it, replacing the value with a placeholder — the usual choice when the model legitimately needs the surrounding text.
- Contextual grounding checks. Two scores with thresholds you set: grounding, whether the response is supported by the source material you supplied, and relevance, whether it actually answers the query. This is the RAG hallucination control, and it applies to output.
Guardrails also offer automated reasoning checks, which validate output against a formal policy built from your own documents, for domains where a factual rule must hold.
Input and output are separate decisions
Every guardrail evaluates two directions and you configure them separately. Input evaluation blocks the request before it reaches the model, which is where the prompt-attack filter and PII blocking earn their keep. Output evaluation inspects the model's response, which is where grounding checks and PII masking apply. Filtering only the input is a common mistake: the model can emit sensitive data it read from a knowledge base even when the question was innocent.
When a guardrail intervenes, the response carries GUARDRAIL_INTERVENED, your configured blocked message, and an assessment showing which policy fired — log it. For contextual grounding you must tell the guardrail which part of the input is the grounding source and which is the query, using the guard-content qualifiers; for the prompt-attack filter, tag only the user-supplied portion of the input so your own system instructions are not scored as an attack.
What guardrails are not
They are not authorisation. A guardrail has no idea whether this user may see that record; it only sees text. They do not inspect or block tool calls, so a guardrail on an agent will not stop an injected instruction from reaching an action-group Lambda function with dangerous parameters — that is the tool's job. And they are probabilistic classifiers, so they belong in the mitigation column alongside good prompting, not in the control column with IAM. Attach one to every production agent, on both directions, and still assume it can be evaded.
Example
import boto3
bedrock = boto3.client("bedrock")
bedrock.create_guardrail(
name="support-agent-guardrail",
blockedInputMessaging="I can't help with that request.",
blockedOutputsMessaging="I can't share that.",
contentPolicyConfig={"filtersConfig": [
{"type": "SEXUAL", "inputStrength": "HIGH", "outputStrength": "HIGH"},
{"type": "VIOLENCE", "inputStrength": "HIGH", "outputStrength": "HIGH"},
{"type": "MISCONDUCT", "inputStrength": "MEDIUM", "outputStrength": "MEDIUM"},
# Prompt attack is input-only: output strength must be NONE.
{"type": "PROMPT_ATTACK", "inputStrength": "HIGH", "outputStrength": "NONE"},
]},
topicPolicyConfig={"topicsConfig": [{
"name": "InvestmentAdvice",
"type": "DENY",
"definition": "Recommendations to buy, sell or hold specific financial instruments.",
"examples": ["Should I put my savings into this fund?"],
}]},
wordPolicyConfig={"managedWordListsConfig": [{"type": "PROFANITY"}]},
sensitiveInformationPolicyConfig={
"piiEntitiesConfig": [
{"type": "CREDIT_DEBIT_CARD_NUMBER", "action": "BLOCK"},
{"type": "EMAIL", "action": "ANONYMIZE"},
],
"regexesConfig": [{
"name": "InternalTicketId", "pattern": "TCK-[0-9]{8}", "action": "ANONYMIZE",
}],
},
# Output-side RAG check: needs grounding-source and query qualifiers on input.
contextualGroundingPolicyConfig={"filtersConfig": [
{"type": "GROUNDING", "threshold": 0.75},
{"type": "RELEVANCE", "threshold": 0.60},
]},
)
# Attaching a published version to a Converse call:
boto3.client("bedrock-runtime").converse(
modelId="anthropic.claude-3-5-sonnet-20241022-v2:0",
guardrailConfig={"guardrailIdentifier": "gr-abc123",
"guardrailVersion": "3", "trace": "enabled"},
messages=[{"role": "user", "content": [
{"guardContent": {"text": {"text": user_text, "qualifiers": ["query"]}}}
]}],
)When to use it
- A healthcare assistant masks patient identifiers in every response with an ANONYMIZE PII action while still letting clinicians see the clinical text.
- A RAG support bot enables contextual grounding checks so answers unsupported by the retrieved passages are blocked rather than shipped to the customer.
- A public-facing agent turns the prompt-attack filter to high on input, and logs each GUARDRAIL_INTERVENED assessment to spot campaigns against it.
Discussion