Gating Irreversible Actions: Controls That Don't Depend on the Model
An instruction in a context file is a suggestion to the same model an attacker is influencing. A missing credential is not.
Where the model must not be the last word
Everything in this pillar has circled one conclusion: controls that depend on a model choosing to comply are weaker than controls that do not. An instruction in a context file is a strong suggestion. A branch protection rule is a fact.
The design question, then, is which actions must never depend on the model's judgement — and how to enforce that outside it.
Two properties that decide it
Ask two questions about any action an agent can take.
| Reversible | Irreversible | |
|---|---|---|
| Visible | Let it run edit a file, open a PR |
Gate it publish a package, send email |
| Invisible | Log it, review after read a file, query an API |
Never automate delete backups, rotate keys, move money |
Reversibility is obvious. Visibility is the one people miss: an action you would notice within minutes is far safer than one that surfaces in three months, even at equal severity. A bad commit gets caught in review. A quietly loosened S3 bucket policy does not.
A working list of gated actions
Most teams' list looks roughly like this. It is worth writing yours down explicitly rather than assuming everyone shares the same intuition.
| Action | Enforced by |
|---|---|
| Push to a protected branch | Branch protection, required review |
| Force-push, delete a branch | Branch protection |
| Publish a package | Publish token not available to the agent |
| Deploy to production | Deploy pipeline requires human approval |
| Send external email or messages | No credential for the send path |
| Delete cloud resources | IAM denies delete for the agent principal |
| Change IAM or permissions | IAM denies; separate break-glass path |
| Any payment or transfer | No credential, ever |
Read the right column. Not one of these is enforced by telling the agent not to. Every one is enforced by a system that does not consult the model — usually by simply not granting the credential.
The most reliable way to prevent an action is for the capability not to exist in the session. No publish token means no publishing, regardless of how the session is steered, what it read, or how convincing the instruction was. Prefer this over every other mechanism.
Where the gate should sit
Given an action worth gating, there are four places to put the control, and they are not equally good.
| Location | Strength | Fails when |
|---|---|---|
| Context file instruction | Weakest | The model is steered — i.e. exactly when you need it |
| Client-side confirmation | Weak | The human approves without reading |
| Tool wrapper refuses | Strong | The agent finds another path to the same effect |
| Credential absent / IAM denies | Strongest | Someone grants the credential later |
Note the failure column. The top two fail under precisely the conditions that make you want the control. The bottom two fail through configuration drift, which is slower, visible in review, and something ordinary process can catch.
This is the argument for pushing gates as far down that table as you can tolerate. It is more work to arrange a separate principal with a denied IAM action than to write a sentence in a markdown file — and it is the difference between a control and a preference.
Confirmation prompts and their limits
Many clients offer a confirmation step before certain tools run. Useful, and worth understanding precisely.
What it prevents: mistakes. An agent about to do something unintended gets stopped by a human who reads the prompt.
What it does not prevent: a determined attack. The confirmation shows the action, not the reasoning behind it. An agent steered into requesting a plausible-looking action gets approval, because it looks plausible.
Two failure modes compound this. Prompt fatigue — the tenth
confirmation in an hour gets approved without reading. And insufficient
information — "Run: git push origin main. Approve?" tells
you the command but nothing about the diff being pushed.
Confirmations work best when rare and information-rich. If yours fire constantly, they have become a formality, and you have a false sense of a control you no longer have.
Designing for the failure you expect
The productive assumption is not that a session might be steered but that one eventually will be, and to design so that the outcome is tolerable.
| Assume | Then |
|---|---|
| A session will be steered by injected content | Tainted sessions cannot act irreversibly |
| A connected server will turn out to be malicious | Containment must hold without trusting it |
| A credential will leak into a transcript | Short-lived, narrow scope, monitored |
| A confirmation will be approved unread | Do not rely on it for the highest-severity actions |
This is ordinary defence in depth. What is specific to agents is where the layers have to sit: not around the model, which is the thing being influenced, but around what the model can reach.
Rollback beats prevention where you can have it
One category deserves separate treatment: actions that are technically reversible but only if you prepared in advance.
A force-push is recoverable if the reflog still holds the old commit, or if a mirror exists. A deleted branch is recoverable within the retention window. A dropped table is recoverable if backups are current and someone has actually tested restoring one.
These sit between the reversible and irreversible columns, and which side they land on is a decision you make before anything happens rather than after. That makes them unusually good value: improving recoverability protects against agent mistakes, human mistakes and ordinary bad luck simultaneously.
- Extend branch deletion retention on your git host.
- Keep a mirror that pulls, so a force-push cannot rewrite it.
- Actually test a database restore. Untested backups have a poor record.
- Enable object versioning on buckets an agent can write to.
None of this is agent-specific, which is rather the point. The best return often comes from ordinary operational hygiene that happens to convert an irreversible action into a recoverable one.
The one-page version
- List every irreversible action reachable from an agent session.
- For each, identify what enforces the gate — and confirm it is not the model.
- Where the answer is "we tell it not to", either grant no credential, or add a real control.
- Split sessions so that anything reading untrusted content holds no authority.
- Log every tool call somewhere the agent cannot write.
Five steps, an afternoon of work for most teams, and they address the majority of what the published threat modelling describes. The gap between teams that have done this and teams that have not is much larger than the effort involved.
Sort actions by reversibility and visibility, and gate the irreversible ones outside the model — ideally by not granting the credential at all. Confirmation prompts catch mistakes, not attacks, and stop working when they fire too often. Design for a session being steered, because eventually one will be.