Every practical safeguard for agents rests on one fact from tools and function calling: the model can only request actions, and the surrounding program decides whether to perform them. Safety lives in that program. It cannot live in the prompt, because a prompt is a request and the model is not obliged to honor it.
Least privilege
Start from nothing and add only what the task requires.
Scope access to the specific folder, repository, mailbox label, or database table involved. Prefer read-only credentials; grant write access to the narrowest possible target. Use a separate account for the agent rather than your own, so its reach is bounded by configuration and you can see in the logs which actions were its.
The test is simple: if this agent behaved as badly as possible within its permissions, what is the worst outcome? If the answer is unacceptable, the permissions are too broad. This holds regardless of how carefully you worded the instructions.
Approval gates
Not every action needs review. Sort them by reversibility.
Freely allowed: reading, searching, drafting, anything that produces output you will look at before it matters.
Approval required: sending messages, deleting, publishing, paying, changing settings, anything that touches another person.
Never delegated: actions that are legally binding, that spend beyond a small limit, or that you could not undo or explain afterwards.
A gate is only a gate if it actually blocks. An agent that announces what it is about to do and proceeds regardless is a narration feature, not a control.
Make it plan first
Asking for a plan before execution is the single highest-value habit. You see the intended approach while it is still cheap to change, you catch misunderstood goals immediately, and you find out what it thinks it needs access to. Our plan before you act prompt does this, and the safe delegation briefing sets the boundaries up front.
Dry runs
Where the tooling allows it, run in a mode that reports what would happen without doing it. The gap between the described plan and the actual proposed operations is often where a misunderstanding shows up.
Limits enforced outside the model
Set a maximum number of steps, a spending cap, and a wall-clock timeout, all enforced by the harness. These are the backstop against the retry spiral, and they must be external — an instruction to stop after twenty steps is advisory, while a harness that refuses the twenty-first call is not.
Logs you can actually read
Keep a record of every tool call, its inputs, and its result. When something goes wrong, the summary the agent wrote will not tell you where — the log will. This is also the only honest way to answer whether an action was taken, since the agent's own account of its work is another prediction.
Sandboxes
For anything experimental, give the agent a copy: a test account, a duplicated folder, a branch rather than the main line. Most learning about how an agent behaves is best done where mistakes cost nothing.
Human-in-the-loop is not a failure
There is a persistent idea that needing approval means the technology is immature and full autonomy is the goal. For consequential work that is backwards. We require review for consequential human decisions too, and for the same reason: the cost of a bad action exceeds the cost of a glance.
The right question is not how to remove the human. It is where a human adds the most value per second of attention — and that is almost always at the irreversible steps and at the initial plan, not in the middle of a mechanical sequence.
Key takeaway: guardrails work because they live in the software around the model, not in what you asked the model to do. Least privilege, approval at irreversible steps, hard limits, and a readable log cover most of the real risk.