Bedrock agents running with no guardrail attached
What does ZopNight detect here?
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.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1630 |
| Category | security |
| Severity | high |
| Metric | none — pure configuration read |
| Source | bedrock_agent_no_guardrail.go |
Where it applies
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, 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
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.