Security Engineering

Gating Irreversible Actions: Controls That Don't Depend on the Model

David Guzenburg/ / 8 min read

An instruction in a context file is a suggestion to the same model an attacker is influencing. A missing credential is not.

access controlleast privilegeirreversible actionsdesign

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.

ReversibleIrreversible
VisibleLet it run
edit a file, open a PR
Gate it
publish a package, send email
InvisibleLog 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.

ActionEnforced by
Push to a protected branchBranch protection, required review
Force-push, delete a branchBranch protection
Publish a packagePublish token not available to the agent
Deploy to productionDeploy pipeline requires human approval
Send external email or messagesNo credential for the send path
Delete cloud resourcesIAM denies delete for the agent principal
Change IAM or permissionsIAM denies; separate break-glass path
Any payment or transferNo 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 strongest control is absence

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.

LocationStrengthFails when
Context file instructionWeakestThe model is steered — i.e. exactly when you need it
Client-side confirmationWeakThe human approves without reading
Tool wrapper refusesStrongThe agent finds another path to the same effect
Credential absent / IAM deniesStrongestSomeone 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.

AssumeThen
A session will be steered by injected contentTainted sessions cannot act irreversibly
A connected server will turn out to be maliciousContainment must hold without trusting it
A credential will leak into a transcriptShort-lived, narrow scope, monitored
A confirmation will be approved unreadDo 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.

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

  1. List every irreversible action reachable from an agent session.
  2. For each, identify what enforces the gate — and confirm it is not the model.
  3. Where the answer is "we tell it not to", either grant no credential, or add a real control.
  4. Split sessions so that anything reading untrusted content holds no authority.
  5. 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.

Takeaway

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.

Keep reading
Codex vs Claude

What the Agent Inherits: Sessions You Are Already Logged Into

Credential discussions focus on secrets in files. On a developer machine most access is an authenticated session an agent can simply use: cloud CLIs, the current kubectl context, a forwarded SSH agent. An inventory script and what to make absent by default.

Security Engineering

Credential Boundaries: What an Agent Should Never Be Able to See

The difference between an agent seeing a secret and using one, why wrapper scripts beat environment variables, and how to scope agent credentials so a steered session stays contained.

Codex vs Claude

Below the Prompt: What a Kernel Sandbox Actually Constrains

Seatbelt, bwrap and seccomp enforce policy that injected text cannot argue with. What a profile can express, why a workspace-write policy still permits everything inside your repository including .git/hooks, and a self-test that proves the policy is on.

Codex vs Claude

Default-Deny Egress: The Control You Turn Off in the First Hour

Outbound network access is the highest-value restriction on an agent and the one that breaks npm install. Pre-seeding dependencies, hostname filtering at a proxy, why a credential fits in a query string, and verifying the denial by IP.

← Capability Attestation and Tool Poisoning: Trusting What a Server Claims  ·  Multi-Tenant Codebases: Make the Unsafe Query Impossible to Write →

All security engineering articles  ·  Every article