Lab 02 — Put a Guardrail in front of a Bedrock model
Scaffold: 5/5 (almost complete). Lab 01 is finished and the guardrail is built. You connect them.
The scenario
The invoke-a-model function from Lab 01 works, and now it needs a safety layer. Compliance will not sign off while the app can be talked into giving financial advice, and support tickets pasted into prompts sometimes contain customer emails and phone numbers that should never reach the model or the logs. An Amazon Bedrock Guardrail can screen both the input and the output in one place.
The requirement
Every request and response goes through the guardrail:
- A financial-advice question (“should I buy this stock?”) is blocked and returns the configured refusal, not a model answer.
- Emails and phone numbers in the input are redacted before the model sees them.
- A normal question still answers normally, and the response says whether the
guardrail stepped in (
"guarded": true|false).
What’s provided
template.yaml— the Lab 01 function, plus anAWS::Bedrock::Guardrail(a denied FinancialAdvice topic, HATE/VIOLENCE/PROMPT_ATTACK content filters, and EMAIL/PHONE PII anonymisation), a publishedGuardrailVersion, and an IAM policy that addsbedrock:ApplyGuardrailscoped to that guardrail. The guardrail id and version are passed to the function as environment variables.src/handler.py— the working model call. The gap is applying the guardrail.solution/handler.py— the reference answer.scripts/— deploy, test (benign, blocked, and PII prompts), teardown.
Your task
In src/handler.py:
- Add
guardrailConfig(identifier, version,"trace": "enabled") to theconverse()call so the guardrail screens input and output. - Read
response["stopReason"]and returnguarded: truewhen it equalsguardrail_intervened.
Two small edits. The docstring has the exact shapes.
Run it
# Prerequisite: Model access enabled for your model, as in Lab 01.
./scripts/deploy.sh
./scripts/test.sh # benign answers; the stock question is blocked;
# the third prompt comes back with its PII masked
./scripts/teardown.sh
What success looks like
Before you wire it, all three prompts answer and guarded is always false.
After, the benign prompt still answers, and the financial-advice prompt comes
back with the blocked message and guarded: true.
The third prompt is the redaction test. It asks the model to repeat a line
containing a fake email address and phone number back word for word, so the
answer shows you what the model was given: {EMAIL} and {PHONE} instead of
the real values, because the guardrail masked them on the way in. That echo is
the observation to make. The masking itself happens between your function and
the model, where you cannot see it directly unless you return the guardrail
trace as well.
If it fails
AccessDeniedExceptionon ApplyGuardrail — the policy grants that action only against this guardrail’s ARN, so a stale id from an earlier stack is refused. A fresh deploy rewires the environment variables and fixes it.AccessDeniedExceptionnaming the model — that is Lab 01’s console gate, not the guardrail: Model access is not enabled for that model in that region. Turn it on in the Bedrock console.- Nothing gets blocked — check you passed
guardrailConfigon theconverse()call and are readingstopReason, not inventing your own check. ValidationExceptionabout the guardrail version — the version comes from theGuardrailVersionresource output; the deploy script wires it for you, so a fresh deploy fixes a stale value.
Reveal the solution
SRC=solution ./scripts/deploy.sh && ./scripts/test.sh
What you just learned
- A guardrail is a separate control from the model: one guardrail can sit in
front of any model, and applying it is its own IAM action
(
bedrock:ApplyGuardrail). - It screens both directions — denied topics and prompt-attack filters on the way in, content and grounding checks on the way out, PII either way.
- The runtime tells you it acted through
stopReason, so your app can log the intervention and show the safe message instead of the raw output. - Publishing a version and applying that version (not
DRAFT) is the habit that keeps a guardrail change from silently altering production.
Next
Lab 03 — Answer questions from a Knowledge Base. You move from a bare model call to retrieval: a Knowledge Base is provided, and you write the retrieve-and-generate call that grounds answers in your documents.