# Bedrock Agent Without Guardrail

> ZopNight stamps every discovered Bedrock agent with a hasGuardrail flag and files a high-severity security finding when the flag reads exactly "false". An unguarded agent answers with no content filtering, denied-topic blocking or PII redaction. The finding claims $0 savings, because safety rather than spend is the driver, and a missing flag stays silent.

Source: https://zop.dev/integrations/aws/recommendations/bedrock-agent-without-guardrail
Updated: 2026-08-19

---

## What an unguarded agent will happily say

A guardrail is the only layer in Bedrock that filters an agent's traffic for harmful
content, denied topics, profanity and personal data, on the way in and on the way out.
An agent without one forwards user prompts to the model and returns whatever comes back,
verbatim. For an internal prototype that may be acceptable; for anything customer-facing it
means the workload can be steered off-policy or coaxed into repeating sensitive data, with
nothing in the path to stop it. That is why the finding ships at high severity even though
the dollar figure attached to it is zero: a guardrail [costs per text unit evaluated](https://aws.amazon.com/bedrock/pricing/), and the
absence of one is a safety gap, not a savings opportunity.

## How the hasGuardrail flag gets stamped

During discovery, every agent is probed and given a `hasGuardrail` metadata value of
`"true"` or `"false"`. The rule fires on exactly one condition: the flag exists and says
`"false"`. Anything else keeps the rule silent: the flag missing because the probe failed, or any
other value. The fail-safe direction is deliberate. A discovery hiccup should
never accuse a protected agent of running bare; only a positive confirmation of "no
guardrail configured" produces the finding.

## Reading guardrailConfiguration from the CLI

```bash
aws bedrock-agent get-agent --agent-id abc1234567 \
  --query 'agent.guardrailConfiguration'
```

A response of `null` means the agent has no guardrail association. That is the exact state this
rule reports. A populated block names the guardrail identifier and version the agent runs
behind.

## Attaching a guardrail without breaking the agent

Create or pick a guardrail first: content filters at strengths suited to the workload,
denied topics for anything the agent must refuse, and word or PII policies where personal
data could surface. Then associate it with the agent by updating the agent's
`guardrailConfiguration`, re-prepare the agent so the new configuration is baked into the
prepared version, and run a test invocation that deliberately trips a filter. The
re-prepare step is the one most often skipped. Until it runs, live traffic continues on
the old, unguarded prepared version even though the console shows a guardrail attached.
