"Guardrails for agentic workloads" appears verbatim in platform-engineer job postings because one layer is never enough: input filters miss novel injections, output filters miss bad actions, and a model that's been talked into something needs an action policy that doesn't care what the model thinks.
Tier: Advanced · Workflow area: Agent operations & guardrails
This playbook builds defense-in-depth for AI agents — gateway I/O filtering, action allowlists enforced outside the model, approval tiers by blast radius, and a kill switch — then proves each layer with attack requests.
Skip heavyweight layering for generate-only workloads with a human review before anything executes — there, pb-46's observability plus output filtering suffices.
Classify actions by blast radius first — the tiers drive everything else.
| Tier | Examples | Policy |
|---|---|---|
| Read | get logs, list deploys, query metrics | auto-allow, log |
| Reversible write | scale within bounds, restart, open PR, draft ticket | auto-allow + audit + rate limit |
| Hard-to-reverse | merge, deploy, delete resource, send external comms | human approval required |
| Forbidden | prod data deletion, IAM changes, spend commitments | not exposed as a tool at all |
Gateway layer: filter inputs and outputs. At the gateway, attach guardrails so every agent request/response passes PII redaction and prompt-injection screening regardless of which app forgot to. In LiteLLM, guardrails are declared in config and attached per-key/request mode (pre_call/post_call), e.g. a Presidio-based PII guard and an injection detector; Portkey ships equivalent gateway guardrails. Verify the exact config schema for your pinned version. Route by data class: keys serving client-restricted workloads get redaction mandatory-on (pb-45's allowlists already control which models they can reach).
Model-adjacent layer: content rails. For agents with free-text outputs to users, add a safety classifier (Llama Guard-class) or NeMo Guardrails flows for topical control. Treat this layer as advisory scoring, not your enforcement point — it lives too close to the thing being defended against.
Action layer: allowlists enforced outside the model. The agent's harness (not the model) validates every tool call against policy before execution. Express it as OPA so it's testable and reviewable:
package agent.actions
default allow := false
allow if {
input.tool == "scale_deployment"
input.args.namespace in {"staging", "dev"}
input.args.replicas <= 10
}
requires_approval if {
input.tool in {"merge_pr", "deploy_service"}
}
The model never sees credentials for actions outside its allowlist (scoped service accounts — pb-50/pb-51 build this out); a jailbroken model asking for a forbidden tool gets a policy denial, not a negotiation.
Approval tier: humans on the hard-to-reverse rung. Approval-required actions pause the agent and page a human with the exact proposed action and its arguments (Slack approval flow, PR review, or your incident tooling). Log the approval with the action. Design for approval fatigue: if a tier generates dozens of approvals a day, either the tier is wrong or the agent is — tune, don't rubber-stamp.
Kill switch, then red-team every layer. Kill switch = disable the agent's virtual key at the gateway (one API call, pb-45) plus a harness-level stop; rehearse it. Then attack each layer and file the evidence: PII in → redacted out; injection corpus ("ignore previous instructions...", data-exfil payloads, tool-smuggling in retrieved content) → blocked or downgraded; out-of-allowlist tool call → denied and alerting; approval-tier action → actually paused; kill switch → traffic stops in seconds. Re-run this suite on every guardrail config change — it's the pb-52 CI idea applied to safety.
The system prompt is a suggestion; the OPA policy is a control — never promote a guardrail to "control" status if the model can talk its way past it.
*.Guardrail logs are a honeypot — they concentrate exactly the PII and secrets they intercepted; encrypt, scope, and expire them more aggressively than application logs.