Teams often ask a prompt guardrail to stop an AI agent from doing something harmful, when the only control that can reliably stop an action is a deterministic policy decision made outside the model, at the point where the tool call executes. Guardrails classify what text means and estimate whether it is malicious or off-policy. Policy engines evaluate a structured request (who, which action, on which resource, in what context) against written rules and return allow or deny. Both belong on an agent's tool path, but they fail differently. This guide is limited to action authorisation at the tool boundary: where the policy engine must sit, what guardrails still add, how injection bypasses each, latency and placement, and decision logging. It is for agent platform engineers, security architects and IAM teams.
Key takeaways
- A guardrail estimates, a policy engine decides. Classifiers and LLM judges return a probability that content is bad; a policy engine returns the same answer for the same input every time and can show which rule produced it.
- Only the policy decision can be the security boundary for actions. OWASP states that input screening "is not a security boundary" and tells builders to enforce permissions and parameter validation at the tool boundary.
- Injection targets the guardrail, not the policy. An attacker who rephrases, encodes or hides instructions in retrieved content can slip past a classifier, but cannot change what a correctly written rule permits for that identity and resource.
- Guardrails still earn their place. They catch suspicious intent the policy cannot express, inspect free-text arguments, redact data in results and feed risk signals into the policy context.
- Log both decisions on one record. A tool call record should carry the guardrail verdict, the policy decision, the policy version and the approval ID, so investigators can see which layer acted.
The short answer
Put a deterministic policy engine on the only path to tool execution and make its decision binding: if it says deny, the call does not run, whatever the model, the guardrail or the user prompt says. Use guardrails before and around that decision to reduce how often bad requests reach it, to judge content that rules cannot parse, and to add a risk score the policy can use. Never invert the order by letting a guardrail "allow" verdict stand in for authorisation.
The AI Guardrails vs AI Gateways page compares content with traffic controls, and the Tool-Call Security for AI Agents guide covers what each per-call decision must evaluate. This page answers a narrower question: which control you can trust to stop an action, and how to wire the two together.
Guardrails and policy engines side by side
| Dimension | Prompt and action guardrails | Policy engine (PDP) at the tool boundary |
|---|---|---|
| Question answered | Does this prompt, retrieved content or proposed call look malicious, unsafe or off-policy? | Is this principal permitted to perform this action on this resource in this context? |
| Decision logic | Statistical classifier, LLM judge, or pattern rules | Rules written in a policy language (for example Rego for Open Policy Agent, or Cedar) |
| Determinism | Same input can score differently across model versions or sampling | Same input and same policy version give the same result |
| Explainability | A score or label; reasons from an LLM judge are themselves model output | The rules that determined the decision (Cedar reports "determining policies"; OPA returns the query result for the rule evaluated) |
| Main bypass | Paraphrase, other languages, encodings, indirect injection through tool results | Over-broad rules, wrong attributes supplied by the caller, calls that avoid the enforcement point |
| Testability | Attack and benign test sets; results are rates, not guarantees | Unit tests per rule with expected allow or deny |
| Correct role | Risk reduction and signal | Binding authorisation decision |
The examples use two open-source policy languages, listed alphabetically: Cedar and Open Policy Agent (OPA).
How each option fails: threat model
Guardrails
The attacker controls some text the agent reads and wants a tool call the agent should not make. Because the guardrail judges meaning, the attacker expresses the same intent in a form it does not recognise. The OWASP LLM Prompt Injection Prevention Cheat Sheet explains why this works: language models do not separate instructions from data within a prompt, so a deny list can be evaded by rephrasing, and screening misses paraphrases, other languages and encoded payloads. Indirect injection (MITRE ATLAS AML.T0051.001) arrives inside a tool result or document, often after the input guardrail has run.
The EchoLeak case shows the pattern. Researchers chained bypasses of a prompt injection classifier, link redaction and content security policy, so a crafted email made the assistant place internal data in a URL the browser fetched. The vendor fixed it server side and reported no evidence of exploitation. Each content filter was a probabilistic or pattern control, and each was stepped around.
Guardrails also fail through repetition. NIST's Center for AI Standards and Innovation reported that when it retried hijacking attacks 25 times per task against a strong model, the average attack success rate rose from 57% to 80%. A guardrail with the same per-attempt miss rate will eventually let an attempt through if the attacker can keep trying.
Policy engines
The threat model for a policy engine is different. The attacker cannot argue with a rule, so they look for one of four gaps:
- Rules that permit too much: a policy that allows the agent's identity to call
delete_recordon any table because it was written for a broad service account. - Attributes the caller controls: if the agent supplies
context.approved = trueor the target environment name in its own request, an injected instruction can set them. Attributes used for decisions must come from trusted sources such as the identity token, a resource inventory or the approval service. - Calls that never reach the enforcement point: an agent with a shell or raw network egress can reach an API directly. See the Agent Egress Control and Network Isolation Guide.
- Error handling: Cedar skips a policy whose evaluation returns an error rather than treating the error as a deny; because only permit policies grant access, a broken permit fails closed, but a broken forbid stops protecting. Test forbid rules as carefully as permits.
The policy engine has its own blind spot: it cannot tell that a permitted action is being taken for the wrong reason, such as an injected instruction making the agent email a customer list to an address that is also a customer. That gap is where guardrails and behavioural detection add value, covered in the sibling Agent Hijacking vs Account Takeover guide.
Architecture: where the policy engine must sit
The NIST zero trust model separates a policy decision point (PDP), which evaluates the request, from a policy enforcement point (PEP), which intercepts it and applies the result. For agents the PEP must sit where the model's proposed call is turned into a real operation, and it must be the only path to that operation. The OWASP AI Agent Security Cheat Sheet puts the same point in agent terms: enforce authorisation in the execution component, outside the agent's context, and fail closed for unknown tools or missing approval requirements.
The flow for a single tool call:
- Model proposes: the agent emits a tool name and arguments. Nothing has happened yet.
- Normalise: the PEP validates arguments against the tool's input schema (the MCP specification requires servers to validate all tool inputs) and resolves the target to an inventory identifier.
- Collect trusted attributes: agent identity, delegating user, resource tags, approval state and any guardrail risk score.
- Decide: the PEP sends the structured request to the PDP and receives allow, deny or require approval.
- Enforce and log: the PEP executes only on allow, writes one decision record, and returns a denial to the agent as an error it cannot override.
The tool-call guide compares PEP placements in detail. For this comparison one rule matters: a framework hook running in the same process as the agent is acceptable for guardrails, but the binding policy decision should also be enforced somewhere the agent cannot modify or route around, normally the gateway or the tool server, with least-privilege credentials at the downstream API as the backstop. See the MCP Gateway and MCP Server Governance Guide.
| Placement | Guardrail fit | Policy engine fit |
|---|---|---|
| Agent framework hook (pre-tool callback) | Good: full conversation and task context for intent checks | Weak as the only PEP: same process as the agent, bypassed if the agent can act outside the framework |
| Tool or MCP gateway | Good for argument and result screening across many agents | Strong: one enforcement path, client and server identity visible, one decision log |
| Inside the tool or MCP server | Useful for result redaction before data returns to the model | Strong: closest to the resource, can check resource attributes such as environment and owner |
| Downstream API and identity layer | None: no view of the model's content | Coarse but unbypassable: token scopes and API permissions cap the worst case |
What guardrails can still add at the tool boundary
Once the policy engine owns the decision, guardrails become inputs rather than gatekeepers. Four uses hold up in practice:
- Intent mismatch detection: compare the proposed call with the user's original request. A call to export all contacts during a "summarise this ticket" task is suspicious even if the policy permits exports. The guardrail raises a risk score; the policy can require approval above a threshold.
- Free-text argument inspection: email bodies and chat posts are strings a policy cannot interpret; a guardrail can check them for secrets, personal data or embedded instructions.
- Result screening: tool outputs carry indirect injection, so screen them before they return to the model; the MCP tools specification tells clients to validate tool results first.
- Data redaction: strip or mask sensitive fields in results the agent does not need, so a later hijack has less to exfiltrate (ATLAS AML.T0086 Exfiltration via AI Agent Tool Invocation).
Detection techniques and tuning are in the AI Guardrails and AI Firewalls Guide.
Controls per option
| Control area | Guardrail controls | Policy engine controls |
|---|---|---|
| Default behaviour | Decide in advance whether a guardrail timeout or error blocks or passes the call; record the choice | Default deny: Cedar authorises nothing without a satisfied permit; unknown tools are denied |
| Input integrity | Mark retrieved and tool-returned content as untrusted before screening | Take decision attributes only from trusted sources, never from model-supplied arguments |
| Hard limits | None: guardrails do not cap volume or blast radius | Forbid rules for irreversible operations on production, spending caps, rate limits per identity |
| Human approval | Can trigger review on a high risk score | Returns require approval; the PEP verifies an approval bound to actor, tool, target, parameters and expiry, consumed once |
| Logging | Verdict, score, model version, rule or category hit | Decision ID, input (masked), result, policy bundle revision |
The approval row follows the OWASP AI Agent Security Cheat Sheet: a simple confirmed flag is not enough, and the approval must be checked and consumed atomically just before execution. See the Human-in-the-Loop for AI Agents Guide and the AI Agent Action Approvals and Spending Limits Guide.
Latency and operational trade-offs
- Policy evaluation: OPA is designed to be co-located as a sidecar, host daemon or library, with policies and data cached in memory. The expensive part is usually gathering attributes, not evaluating rules, so cache resource attributes briefly and take identity claims from the token.
- Guardrails: a classifier or LLM-judge call adds a model inference per check, doubled if both arguments and results are checked. Reserve LLM judges for high-risk tools.
- Availability: read-only tools may tolerate a guardrail outage; write, delete, payment and permission-change tools should fail closed when the policy engine or decision log is unavailable, as the OWASP agent cheat sheet recommends.
Decision logging for the layered design
After an incident the first question is which layer saw the call and what it decided. OPA decision logs already carry a decision ID, the input, the result and the bundle revision, and can mask sensitive input fields before upload. Cedar returns the determining policies and any policy errors with each decision. Combine these with the guardrail verdict in one schema:
| Field | Source | Why it matters |
|---|---|---|
| Correlation ID and trace ID | PEP | Joins the call to the agent session, the user request and the downstream API log |
| Agent identity, delegating user, agent version | Identity token, registry | Attribution and comparison across versions |
| Tool, normalised arguments (masked), resolved resource ID | PEP after schema validation | What was actually requested, not what the model wrote |
| Guardrail verdicts and scores, guardrail model version | Guardrail service | Shows whether content checks flagged the call |
| Policy decision, determining rules, policy revision | PDP | Shows which rule allowed or denied and under which policy version |
| Approval ID, approver, approval expiry | Approval service | Proves a human approved this exact action |
Send these records to storage the agent's identity cannot write to or delete (NIST SP 800-53 AU-9). The AI Agent Audit Log Schema Template gives a full field list.
When to rely on each
- The action is irreversible or high impact (delete, pay, grant access, deploy to production): the policy engine decides, with forbid rules and approval binding. Guardrails only add signal.
- The risk is in free text the agent writes (a message to a customer, a public post): the policy decides whether the agent may post at all; a guardrail judges the content.
- Read-only agents over low-sensitivity data: least-privilege credentials plus result guardrails may be enough at first.
- Many agents and many tools: a central PDP with a gateway PEP gives one policy set and one log.
- Small organisations: start with deny-by-default tool allowlists per agent and approval for destructive tools, then adopt a policy language when allowlists become hard to read. See the Policy-as-Code for Authorisation Guide.
Worked scenario: a support agent with refund and email tools
A customer support agent can read tickets, look up orders, issue refunds and email customers. A customer submits a ticket containing hidden text telling the agent to refund five unrelated orders and email the order list to an outside address.
- Guardrail only: the instruction is phrased as a polite policy note in another language and passes the classifier. The agent issues the refunds and sends the email.
- Policy engine only: the Cedar or Rego policy permits
issue_refundonly where the order's customer ID matches the ticket's customer ID, caps the amount, and forbids email to domains outside the customer record. Four of the five refunds are denied because the orders belong to other customers; the email is denied by the domain rule. One refund on the customer's own order is permitted and executes, which is within the agent's mandate. - Layered: the same policy applies, and a result-screening guardrail flags the ticket text as containing instructions. The flag raises the risk score above the threshold, so the policy returns require approval for the permitted refund too. A human sees the ticket and declines. The decision log shows the guardrail flag, five denials with their determining rules, one approval request and its rejection.
The policy stops the out-of-scope actions whether or not the guardrail notices; the guardrail improves handling of the in-scope action the policy cannot judge.
Implementation roadmap
- Inventory tools and tier them by impact: read, write, destructive, financial, permission-changing. Unknown or unmapped tools default to the highest tier.
- Write deny-by-default policies for the top tier first, keyed on agent identity, delegating user, resource attributes and approval state. Keep rules in version control with unit tests; the Agent Authorisation Policy Testing Guide covers test cases for injected calls.
- Deploy the PEP in audit mode at the gateway or tool server: evaluate and log every decision but do not block. Compare would-deny decisions with real traffic for two to four weeks.
- Turn on enforcement per tier, starting with destructive and financial tools, with a feature flag per tool so you can roll back a single rule without disabling the PEP.
- Add guardrails as signal: result screening and intent mismatch feed a risk attribute; tune thresholds against your own benign traffic.
- Close bypass routes: remove shell and raw network access from agents that do not need it, and narrow downstream credentials so the API layer caps the worst case.
Detection and measurement
- Policy coverage: percentage of tool calls by volume and by tool that pass through a binding PDP decision. Target 100% for write and destructive tiers.
- Bypass attempts: downstream API calls made with agent credentials that have no matching PEP decision record. Any non-zero value is an incident or a gap.
- Deny rate by rule: sudden rises suggest injection campaigns or regressions; steady high rates suggest rules that are too tight.
- Guardrail miss rate in red team tests: share of adversarial calls the guardrail passed that the policy then denied. This shows how much the policy layer is carrying.
- Approval quality: approval rate and time to approve for require-approval decisions; near-100% approval suggests rubber-stamping.
Framework mapping
| Framework | Reference | How it applies |
|---|---|---|
| NIST SP 800-53 Rev. 5 | AC-3 Access Enforcement; AC-6 Least Privilege; AC-24 Access Control Decisions | Policy engine decisions enforced at the PEP for each tool call |
| NIST SP 800-53 Rev. 5 | SI-10 Information Input Validation; SI-15 Information Output Filtering | Schema validation of arguments and guardrail screening of inputs and results |
| NIST SP 800-53 Rev. 5 | AU-2 Event Logging; AU-9 Protection of Audit Information; AU-12 Audit Record Generation | Combined decision record per call, stored outside the agent's control |
| NIST CSF 2.0 | PR.AA-05; DE.CM-09 | Permissions defined in policy and enforced; runtime monitoring of agent activity |
| OWASP Top 10 for LLM Applications 2025 | LLM01 Prompt Injection; LLM06 Excessive Agency | Guardrails reduce LLM01; policy engine and least privilege limit LLM06 |
| MITRE ATLAS | AML.T0051 LLM Prompt Injection; AML.T0053 AI Agent Tool Invocation; AML.T0086 Exfiltration via AI Agent Tool Invocation | The techniques the combined design is meant to contain |
Common failure patterns
- Instructions used as controls: telling the agent "do not change production" in its prompt is a guardrail at best. In the Replit AI agent database deletion, a code freeze existed only as a chat instruction while the agent still had write access to production, and destructive commands ran. A forbid rule on destructive operations against production would have held.
- Guardrail verdict treated as permission: code that runs the tool whenever the classifier returns "safe". OWASP notes that a risk classification does not grant permission.
- Model-supplied attributes in the policy input: environment, owner or approval flags taken from tool arguments, so injected text can satisfy the rule.
- PEP in the framework only: the agent gains a code execution tool and calls the API directly, skipping both layers.
- Untested forbid rules: a forbid policy that errors on a missing attribute is skipped, and the permit it was meant to constrain applies.
Practitioner checklist
- Every write, destructive, financial and permission-changing tool call passes through a binding PDP decision before execution.
- Unknown tools and missing policy decisions fail closed.
- Policy attributes come from identity tokens, inventories and the approval service, never from model output.
- Forbid rules exist for irreversible actions on production and are covered by tests, including missing-attribute cases.
- Guardrail outputs feed the policy as a risk attribute and never authorise a call on their own.
- Agents have no shell or raw egress unless the task needs it, and downstream credentials are least privilege.
- One decision record per call carries guardrail verdict, policy decision, policy revision, approval ID and result, stored where the agent cannot alter it.
Standards and references
- OWASP: AI Agent Security Cheat Sheet
- OWASP: LLM Prompt Injection Prevention Cheat Sheet
- OWASP: Top 10 for LLM Applications 2025
- Model Context Protocol: Specification, Tools
- Cedar: Authorization
- Open Policy Agent: Philosophy
- Open Policy Agent: Decision Logs
- NIST: Technical Blog, Strengthening AI Agent Hijacking Evaluations
Related NHI Mgmt Group resources: AI Agent Authorisation Guide · Tool-Call Security for AI Agents · AI Guardrails vs AI Gateways · Confused Deputy in AI Agents Guide · Policy-as-Code for Authorisation Guide