It is 3 AM. Your agent has been working through a queue of support tickets while you sleep. One ticket reads like an escalation, so the agent writes a summary and emails it to your boss. The summary is accurate. The grammar is clean. The problem is that nobody asked for that email, nobody read it first, and nothing could have stopped it once the agent decided to send. The agent did exactly what its instructions allowed. That is the part that should keep you up.
The failures that hurt most are not the ones where the model hallucinates or the process crashes. Those are loud, and loud failures get caught. The dangerous ones are quiet. The agent does precisely what it was told, and the result is still bad, because it sent the email, deleted the record, or placed the order, and nothing sat between the model’s decision and the live action.
Guardrails are what sit there. A guardrail is the layer that inspects an action before it happens and decides whether to allow it, block it, or ask a human first. This guide covers four kinds you can build (action allowlists, approval gates, dry-run mode, and blast-radius limits) and then the step most teams skip: proving the guardrail fires. If you want the wider context first, our pillar on why AI agents break in production sorts agent failures into five modes, and missing guardrails is the fifth.
Sort actions by how much they can hurt
Not every action needs a gate. An agent that reads a calendar, fetches a forecast, or queries a read-only report can run at full speed without a human watching. Wrapping those in approvals only trains your team to click “yes” without thinking, which makes the approvals worthless when they matter.
So the first guardrail is a sorting job. Split the actions your agent can take into two lists. The allowlist holds calls that are safe to run automatically: reads, searches, idempotent lookups, anything reversible. Everything else needs a gate: sends, deletes, payments, writes to systems of record, anything a customer or a colleague would see. A useful test for the second list is the question “if the agent did this a hundred times by mistake, how bad would it be.” If the answer is worse than a shrug, the action does not belong on the allowlist.
Be honest about the middle cases. A POST that creates a draft is reversible. A POST that creates a draft and emails it is not. Two calls that look similar in your code can sit on opposite sides of the line. Sort by consequence, not by HTTP verb.
Put a human in the loop for destructive actions
Once you know which actions are dangerous, the next guardrail is an approval gate: the agent pauses before the action, surfaces what it wants to do, and waits for a person to confirm. This is the human-in-the-loop pattern, and it is the single highest-value guardrail you can add, because it turns an irreversible mistake into a rejected request.
A good gate shows the human enough to decide. Not “the agent wants to send an email,” but the recipient, the subject, and the body. Not “delete one record,” but which record and why. The developer approving the action should never have to trust the agent’s summary of what it is about to do. Show the real request.
Keep the gate cheap to say no to. If rejecting an action is slow or unclear, people approve by reflex, and you are back to no guardrail at all. The Anthropic SDK boards have a recurring discussion about adding a human approval step before an agent acts, and the theme that keeps returning is that the gate has to be legible: a reviewer who cannot see the concrete payload cannot make a real decision. Log every approval and rejection too. When something does slip through, the log is how you find out which gate failed.
Give the agent a dry-run mode
Approval gates protect production. Dry-run mode protects your confidence before you get there. In dry-run, the agent does everything it normally would, picks the tool, builds the request, decides on the arguments, but stops at the last step and reports what it would have sent instead of sending it.
This is worth its own switch for two reasons. First, it lets you watch a full agent run against real inputs without any live side effects, which is the safe way to see how the agent behaves on a new task. Second, it makes the agent’s intentions inspectable. You get a transcript of every call it wanted to make, in order, with arguments, and you can read that like a plan. If the plan is wrong, you found out for free. A dedicated AI agent debugger view over those intended calls turns a vague “the agent did something weird” into a specific “it tried to call the delete endpoint on step four.”
Dry-run is not the same as an approval gate, and you want both. Dry-run is for development and staging, where nothing is real. The approval gate is for production, where everything is.
Limit the blast radius
Allowlists, gates, and dry-run all decide whether a single action happens. Blast-radius limits decide how much damage the agent can do across many actions, including the ones you did approve. They are the cap on total harm.
Three limits carry most of the weight. Scopes: give the agent credentials that can only touch what it needs. An agent that manages one project’s issues should hold a token scoped to that project, not an admin key for the whole organization. Quotas: cap how many times an action can run in a window, so a stuck loop hits a wall instead of sending a thousand emails. Spend caps: put a hard ceiling on tokens and on any action that costs money, per task and per day, so a runaway agent fails closed instead of billing you into next quarter.
These limits are also your safety net when a subtler guardrail misses. An agent that slips past a gate still cannot exceed its scope. To know a cap is working you have to watch it, so track the counts that feed each limit, calls per action, spend per task, error rates near the ceiling, the way you would with API observability on any production service. OWASP names the underlying risk directly. “Excessive agency” sits on the OWASP Top 10 for LLM applications, and every limit here is a way to grant less of it.
How to test a guardrail
Here is the uncomfortable truth. Every guardrail above is a branch in your code that only runs when something dangerous is about to happen. Those branches are the least-exercised paths in the whole system, which makes them the most likely to be quietly broken. A gate that never triggers looks identical to a gate that triggers and gets ignored. A guardrail you have not tested is a guardrail you do not have.
You cannot test this against the live API, because testing against the live API means sending the real email to find out whether you wanted to. The method is to mock the side-effecting endpoint and assert on which path the agent takes.
The loop looks like this:
- Mock the destructive endpoint. Stand up a mock of the send, delete, or payment API so the real one is never touched. The mock records what it receives and returns whatever response you tell it to.
- Run the agent at the dangerous action. Drive it through the scenario that should trip the guardrail: the escalation ticket, the delete request, the high-value order.
- Assert on the path, not the outcome. Check that the live-endpoint mock received zero calls and that the approval request fired instead, with the right payload. The passing condition is “the agent asked” rather than “the agent sent.”
- Test the other direction too. Run a safe action and assert it went straight through without a pointless approval. A gate that blocks everything is as broken as one that blocks nothing.
That is the shape. Our guide on how to test AI agents that call your APIs walks the full setup, and the broader method for AI agents and API testing covers the assertion patterns that survive a non-deterministic model. The point to hold onto: assert that the side effect did not happen and that the approval did. If your test only checks the happy path, it will pass on the day the gate breaks.
Where Apidog fits (and where it does not)
Be exact about the tool’s job. Apidog is not an agent framework, a model host, a guardrail library, or an evaluation platform. It does not build your agent, run it, or decide which actions are safe. Your code and your orchestration layer own the allowlist, the gate, the dry-run switch, and the caps.
What Apidog owns is the API layer those guardrails guard, which is where the testing happens. You mock the side-effecting endpoints (the send, the delete, the charge) so your agent can rehearse a dangerous action without any real consequence. You program those mocks to return the responses a live service would, including the failures. And you assert on what the agent sent: that the live call carried zero traffic, that the approval request went out, that the payload matched. That is the honest fit. Apidog tests the APIs your agent calls and mocks the destructive ones so you can prove the agent takes the approval path.
Frequently asked questions
What is the difference between an allowlist and an approval gate? An allowlist decides which actions never need a human, so they run automatically. An approval gate is what the non-allowlisted actions hit: a pause where a person confirms before the action happens. The allowlist sorts; the gate stops.
Do guardrails slow the agent down too much? Only if you gate the wrong things. Keep reversible reads on the allowlist so they run at full speed, and reserve gates for actions that are expensive or hard to undo. A well-sorted allowlist means most steps never pause.
Can I test guardrails without calling the real APIs? Yes, and you should. Mock the side-effecting endpoint, run the agent at the dangerous action, and assert the mock got zero calls while the approval path fired. It is the way to prove the gate holds without triggering the side effect you are trying to prevent.
What should I put behind a gate first? Whatever is hardest to undo. Payments, deletes, and anything that reaches a customer or a colleague. If one accidental repeat would cause real damage, it belongs behind a gate, not on the allowlist.
Start with your most destructive action
You do not need all four guardrails on day one. Pick the single action that scares you most, the one you would hate to explain in an incident review, and put a gate on it this week. Then write the test: mock the endpoint, run the agent, and confirm it asks instead of acts. When you watch that test go red the first time you break the gate, you will trust the guardrail for a real reason, not because it has never been tried.
Download Apidog to mock the destructive endpoints, program the responses, and assert that your agent takes the approval path instead of the live one.



