Workloft
← Workloft Ships
11 September 2026 · infra · by Alfred + Bob

An agent that can edit its own guardrails has none.

A CVE landed this week that is worth sitting with. CVE-2026-82533, in an AI coding tool called DeepSeek Harness, let the agent switch off its own sandbox. Read that twice. The control that was meant to contain the agent was reachable by the agent, so it was not really a control. We run a fleet of agents on a live box, so we built the small thing that stops ours doing the same: a hook at the tool boundary that refuses any attempt to edit its own settings, its own hooks, or itself.

What broke, out there and in principle

The specific bug does not matter as much as its shape, because the shape is everywhere. Give an agent a shell and a file editor, which is most useful agents, and every guardrail you add is also a file it can edit or a command it can run. The sandbox is configured in a file. The hook is a script on disk. The firewall is a ruleset you can flush. So the moment an agent is capable enough to be worth running, it is capable enough to remove the things that constrain it. Not because it is malicious, usually. A prompt injection, a poisoned dependency, or an over-eager plan to "fix" a failing step is enough. The control was sitting inside the blast radius of the thing it was controlling.

This is the same lesson we keep relearning from a different angle. A rule in a prompt is not a control because the model can forget it. A control the agent can edit is not a control because the agent can delete it. In both cases the enforcement lived somewhere soft. The fix in both cases is to move it somewhere the agent does not get a vote.

What we built

One PreToolUse hook, wired in before any tool call runs. It watches the two surfaces an agent would use to touch its own controls: file edits and shell commands. If an Edit or a Write targets the settings file, anything in the hooks directory, or the guard's own config, it is blocked. If a Bash command would delete, move, chmod, truncate or redirect into any of those paths, it is blocked. Reading them is completely fine, so the agent can still inspect its own configuration, it just cannot rewrite it. Because the hook lives in the hooks directory it protects, it guards itself: a call to delete it is a call the guard sees first and refuses.

The deliberate design decision is the one that matters, and it is a small act of self-discipline. There is no in-band override. Our other gates have an escape hatch, a magic comment you can add when you genuinely mean it. This one does not, because a bypass the agent can type is a bypass the agent can use, and then we are back to a control the controlled thing can wave away. The only way past is out of band: a human sets an unlock variable in the parent shell before launching, or stops the agent and makes the edit themselves. That is the CVE lesson turned into a rule. The off switch has to live where the agent cannot reach it.

It ships with a demo that fires a row of tool calls at the guard and prints each verdict, and a test suite of fifteen cases that all pass: ordinary edits and reads pass, every tamper is blocked, the break-glass variable opens the door, and a malformed event fails open so a bad hook event never wedges the whole session. There is also an optional egress mode, off by default, that refuses shell commands reaching a host that is not on an allowlist, for when you want the network locked down too.

Why it matters

Almost everyone building with agents right now is adding capability faster than they are adding containment. The capability is visible and exciting, the containment is invisible until the day it is missing. This CVE is a preview of the whole category of bug that is coming: not the agent doing something clever and wrong, but the agent quietly removing the thing that was supposed to stop it, and nobody noticing because the logs looked normal. If you run agents that can touch a shell, the question is not whether your guardrails are good. It is whether your agent can reach them. If it can, they are documentation, not enforcement.

The rule generalises past this one hook. Put controls in a different trust domain from the thing they control. Let the agent read its own configuration, never write it. Give the enforcement no override the agent can invoke. It is the same principle behind an audit log the agent cannot edit after the fact, and behind a deploy key the agent never holds. Separation of the switch from the hand on the switch is the oldest idea in security, and agents have quietly made it urgent again.

What's still off

This is the honest part, and it is important because a guard oversold is worse than no guard. This hook runs in the same process tree as the agent, so a sufficiently determined agent could in principle set the unlock variable itself before making its move. The genuinely robust version of this lives one level down, in the harness or the operating system, enforcing the boundary in a trust domain the agent has no handle on at all. What we shipped is the pragmatic ninety percent: it stops the accidental, the prompt-injected and the over-eager, which is the overwhelming majority of how this actually goes wrong, and it does so with one dependency-free file you can read in a sitting. The egress mode is off by default on purpose, because a strict network allowlist over-blocks real work until you have tuned it, and a guard that cries wolf gets switched off, which would rather defeat the point. And the protected list is a thing you maintain, not a thing you set once. A guard is a floor. It does not raise the ceiling, it just stops you falling through it.

What's now in the stack