Design for the steered prompt: how Sudo's sandbox and approval hold up
Leon
Say you are the security architect asked to sign off on an AI assistant that changes your production configuration. Endpoints, AI tools, agents, scheduled tasks, index settings, schemas. The vendor tells you the model is careful. That answers the wrong question. The question you have to answer is what the assistant can reach on the day someone else is steering it.
Sudo is the admin assistant in Curiosity Studio, and that question is the one we wrote our new technical paper around: Inside Sudo: a sandbox, a diff, a person. It is written for platform admins and security architects. It walks through the sandbox mount by mount, lists what is missing from it by construction, and spells out what an approval binds. Its thesis fits on two lines: no route to the host, and no route in except a diff a person approved.
This post covers why we think that is the right shape, and where it still leaves work for you.
Start from the assumption that the prompt is steered
Prompt injection still has no filter you can rely on. Simon Willison has made the case for years, and his lethal trifecta talk puts it bluntly. Asking the model in the system prompt not to fall for tricks fails, because the attacker's text comes last. Detection layers might catch 99% of attacks, and "in application security, 99% is a failing grade." In late 2025 a paper with authors from OpenAI, Anthropic and Google DeepMind, summarized in Willison's notes on the attacker moving second, ran adaptive attacks against 12 published defenses. Most fell to attack success rates above 90%.
So the useful design question is what a hijacked assistant can reach, not how to keep it from being hijacked. The design patterns paper with authors from IBM, Invariant Labs, ETH Zurich, Google and Microsoft states the principle. Once an agent has read untrusted input, it must be constrained so that the input cannot trigger any consequential action.
An admin assistant reads untrusted input all the time. A ticket, a field report, a maintenance log, a file an admin attached: any of them can carry instructions. The paper's Table 3.1 answers the reach question directly.
| Target | How far a steered prompt gets |
|---|---|
| Host files and processes | Absent by construction |
| Network | Withheld commands |
| Your graph data | Read only, as the admin |
| Your configuration | Sudo's own copy, staged as a diff |
| The live workspace | Only after an approval |
At worst, a steered prompt changes the edits in Sudo's own copy. That copy cannot reach the host, cannot call out and cannot apply itself.
Absent beats refused
The first half of the thesis comes from one choice. Sudo runs its scripts in an interpreter,
and there is no shell behind it. Computerwelt, an open source .NET library, runs bash and
Python in process over a virtual filesystem. There is no bash binary, no PATH lookup and no
CPython. Nothing is forked or executed, and no container is started. The commands that
configuration work needs still work: cat, grep, sed, jq, pipes, heredocs, loops.
The paper's point is about the shape of the guarantee. A blocklist has to be kept complete forever. A capability the interpreter never implemented has nothing to refuse. Network commands are withheld by name as well, so a future library version that adds one does not hand it to the session.
This is an old lesson. Norm Hardy's The Confused Deputy tells how a compiler with write access to its own directory was talked into overwriting the billing file. Every patch to the rules for opening a file made the rules more complex. The last version Hardy wrote down "required fourteen boolean operators." His fix was to stop checking names and hand the program only the authority it needed. An agent that can shell out is a deputy with the host's authority, and an injected prompt is the user handing it a file name. An interpreter over nine mounts, two of them writable, has only what it was given.
The Computerwelt series covers how the interpreter is built. The paper puts it in the terms a security review uses: which mounts take writes and which limits raise an error instead of truncating.
Where the person sits
Meta's Agents Rule of Two, also in Willison's post, gives a way to place Sudo. An agent should combine at most two of three properties in a session: it processes untrusted input, it can reach sensitive systems or private data, and it can change state or communicate externally. A task that needs all three should not run on its own. At a minimum, a person has to approve it.
Sudo needs all three to be useful. It reads tickets, it reads your graph, and its job is to
change configuration. So the paper is precise about where the person goes. Sudo reads,
edits and builds in its own copy, then commit stages the change set and stops. A person
reads the diff and applies it, under their own permissions.
Four gates sit between a draft and your workspace:
| Gate | Checks | Refuses when |
|---|---|---|
| build | Every changed file, in its scope | A file fails to compile |
| commit | The whole change set, together | The build fails, unforced |
| Approve | The commit id you were shown | Sudo staged a newer one |
| Your account | Rights to commit and run | Read only, or write protected |
The third row is the one I would ask any vendor about. Approval is bound to the commit id on the card. If Sudo staged a newer commit while the card was open, the card refuses to apply, because applying it would ship something nobody read. Approving a description of a change and approving its exact contents are different acts. Only the second is worth a signature.
Two smaller rules come from the same thinking. Approving says so in the conversation, in your voice, and discarding says nothing, so a quiet chat never reads as consent. And an approved commit goes through the same definitions importer as an uploaded bundle, so no second writer exists to drift out of step with it.
The rubber stamp objection
The strongest objection showed up in the thread under that Rule of Two post. One commenter argued that a person in the loop needs the knowledge and the time to act on each request. Otherwise they "would just rubber stamp everything", in effect the third property with extra steps.
That is a fair hit, and no approval design makes a tired reviewer careful. The paper's answer is to make each approval worth a person's attention, in four ways.
Reads need no approval. Sudo reads your graph and configuration freely, as you, so the
person is asked only about changes. A change arrives already compiled against the workspace
as the whole set leaves it, so a reviewer never spends attention on a change that would not
build. It arrives as a diff, in a file list or a pull request view, the same shape as a code
review. And Sudo's own skill, sudo-persona, is visible and editable in your workspace. It tells the assistant to
proceed on the small and reversible, and to ask first on anything destructive,
security sensitive, externally visible or materially ambiguous.
When a reviewer still misses something, the change can be undone. Every applied commit is one entry in the configuration history, attributed to the admin who approved it. Every code surface keeps its own history, so an endpoint changed through Sudo rolls back like one changed by hand. The approval cannot guarantee a careful reviewer. It does guarantee that the review covered the exact bytes, and that a mistake can be traced and reversed.
Permissions bound it from below
Sudo's permissions are the chatting admin's, narrowed. It reads the graph with your permissions and skips node types that are never sent to clients. It writes none of your data; a migration runs only once approved. It can declare a secret and write code that reads one, but it never sees the value. Packages, backups, restarts and licensing are not Sudo's to do.
A read only admin gets a read only Sudo. Commit and run refuse, reading still works, and the draft waits for someone who can hand it over. The same holds for any admin while administrator write protection is on. There is nothing to approve that the approver could not apply by hand.
What to take into your own review
The paper ends on three things to keep, and they make a decent checklist for any agent that touches production configuration, ours or not:
- No route to the host or the network, enforced by what exists, not by what is refused.
- No route in except an approved diff, bound to the exact commit shown.
- Bounded by the approver's permissions, and recorded in the history you already audit.
The same sandbox is open to your own assistants, through an AI tool that returns an
ISandbox. The last Computerwelt post shows
how to build one.
The full paper has the mount listing, the session limits, every button on the review card and what it keeps, and a glossary. Read it on the whitepaper's page, or download the PDF and hand it to whoever signs off on your agents.
Further reading
- My Lethal Trifecta talk at the Bay Area AI Security Meetup, Simon Willison. Why prompt begging and detection layers fail, and why removing one leg of the trifecta stops the attack. (HN discussion)
- Design Patterns for Securing LLM Agents against Prompt Injections, Simon Willison's notes on the paper. Six patterns that trade agent freedom for resistance to injected instructions.
- New prompt injection papers: Agents Rule of Two and The Attacker Moves Second, Simon Willison. Meta's Rule of Two, and 12 defenses broken by adaptive attacks. The HN thread carries the rubber stamp objection and a reply from one of the Rule of Two authors.
- The Confused Deputy, Norm Hardy. The case for handing a program capabilities instead of checking names, and still the clearest account of why rule lists grow without end.
Referenced by
Read next
Articles on context graphs, enterprise search and industrial AI