Why a Secure Agent Sandbox Is Not Enough: Governing Delegated Authority During Execution

2026-10-30 ยท Aldo Pietropaolo

An engineering team puts an autonomous agent in a well-built sandbox. The filesystem and process settings are locked at sandbox creation. Outbound traffic goes only to approved destinations. Credentials are supplied by the supervisor. The security review goes well, and it should.

Then someone asks a different question. The agent is about to read a file on an approved host, using an approved tool. Who is it doing that for, and is that person allowed to ask for it? OpenShell's documented controls answer a different question: where the process can go.

This paper separates the two questions and shows how a complete agent runtime architecture links seven layers in order. Isolation is the first layer and a necessary one. It is also only the first.

Two questions, two layers

NVIDIA OpenShell is an open-source project (Apache 2.0) for running agents in isolation. Its overview documentation says it "combines sandbox runtime controls and a declarative YAML policy so teams can run agents without giving them unrestricted access to local files, credentials, and external networks." It lists protection layers. Filesystem and Process are "Locked at sandbox creation." Network is "Hot-reloadable at runtime," and "Network policies allow only approved destinations; other outbound traffic is denied."

Its security best practices are specific about egress. The default is "All egress denied. Only endpoints listed in network_policies can receive traffic." It also states, "If no network_policies entry matches the destination host, port, and calling binary, the proxy denies the connection." The page also says, "OpenShell binds each connection to executable identity observed by the trusted isolation boundary."

The how-it-works documentation describes the supervisor as residing "on the trusted side of the boundary." It checks requests against policy, provides credentials, resolves DNS, and opens approved connections.

That is a clear answer to one question: Where can the agent's process go?

A second question sits beside it: What is this agent allowed to do, and for whom, at this action? It concerns authority, a different subject from location. The same tool on the same host can be within one person's delegated scope and outside another's. A sandbox policy keyed to destinations and binaries describes where a process may reach. Whose work the agent is doing is a separate fact and must be modeled somewhere.

Norm Hardy described the shape of this problem in 1988 in his paper on the confused deputy. A program with legitimate authority is used on behalf of a party who lacks it. Our post on borrowed authority in multi-agent workflows covers the agent version.

A note on terms. OpenShell's "executable identity" is process identity: which binary is making the connection. Agent identity is different: which agent, deployed by whom, acting for which person. Both are useful and answer different questions. This is a matter of vocabulary, and nothing in it is a criticism of either.

The seven layers, in order

A complete architecture for autonomous agents links seven things. The order matters because each layer depends on the one before it.

  1. Secure runtime isolation. Bounds where the agent's process can go.
  2. Agent identity. Establishes which agent is acting.
  3. Delegated authority. Establishes whose authority it exercises and how much.
  4. Deterministic authorization. Decides each action against that authority.
  5. Intent and plan constraints. Bounds the kind of work the run may do.
  6. Containment. Stops a run that goes wrong while it is still running.
  7. Verifiable execution lineage. Proves afterward what happened and why.
<div style="overflow-x:auto;margin:28px 0;border:1px solid rgba(163, 156, 144,0.18);border-radius:14px;"> <table style="width:100%;border-collapse:collapse;font-size:14px;min-width:640px;background:rgba(28, 26, 23,0.4);"> <thead> <tr style="background:rgba(28, 26, 23,0.7);"> <th style="text-align:left;padding:13px 18px;color:#E8A947;font-weight:700;font-size:11px;letter-spacing:0.6px;text-transform:uppercase;">Layer</th> <th style="text-align:left;padding:13px 18px;color:#E8A947;font-weight:700;font-size:11px;letter-spacing:0.6px;text-transform:uppercase;">Question it answers</th> <th style="text-align:left;padding:13px 18px;color:#E8A947;font-weight:700;font-size:11px;letter-spacing:0.6px;text-transform:uppercase;">If a deployment has no such layer</th> <th style="text-align:left;padding:13px 18px;color:#E8A947;font-weight:700;font-size:11px;letter-spacing:0.6px;text-transform:uppercase;">Depends on</th> </tr> </thead> <tbody> <tr style="border-top:1px solid rgba(163, 156, 144,0.12);"> <td style="padding:13px 18px;color:#F3F1EC;font-weight:600;">1. Runtime isolation</td> <td style="padding:13px 18px;color:#CFC8BC;">Where can the process go?</td> <td style="padding:13px 18px;color:#CFC8BC;">Every other control runs on a host the agent can reach freely</td> <td style="padding:13px 18px;color:#CFC8BC;">A trusted boundary</td> </tr> <tr style="border-top:1px solid rgba(163, 156, 144,0.12);"> <td style="padding:13px 18px;color:#F3F1EC;font-weight:600;">2. Agent identity</td> <td style="padding:13px 18px;color:#CFC8BC;">Which agent is acting?</td> <td style="padding:13px 18px;color:#CFC8BC;">Decisions and records attach to a binary or a shared account</td> <td style="padding:13px 18px;color:#CFC8BC;">A contained runtime to anchor it</td> </tr> <tr style="border-top:1px solid rgba(163, 156, 144,0.12);"> <td style="padding:13px 18px;color:#F3F1EC;font-weight:600;">3. Delegated authority</td> <td style="padding:13px 18px;color:#CFC8BC;">For whom, and how much?</td> <td style="padding:13px 18px;color:#CFC8BC;">The person drops out at the first hop; sub-agents can hold more than their parent</td> <td style="padding:13px 18px;color:#CFC8BC;">A named agent</td> </tr> <tr style="border-top:1px solid rgba(163, 156, 144,0.12);"> <td style="padding:13px 18px;color:#F3F1EC;font-weight:600;">4. Deterministic authorization</td> <td style="padding:13px 18px;color:#CFC8BC;">Is this action within that authority?</td> <td style="padding:13px 18px;color:#CFC8BC;">Authority exists on paper but nothing applies it to each action</td> <td style="padding:13px 18px;color:#CFC8BC;">Authority that can be evaluated</td> </tr> <tr style="border-top:1px solid rgba(163, 156, 144,0.12);"> <td style="padding:13px 18px;color:#F3F1EC;font-weight:600;">5. Intent and plan constraints</td> <td style="padding:13px 18px;color:#CFC8BC;">Does this action fit what the run was for?</td> <td style="padding:13px 18px;color:#CFC8BC;">Individually permitted actions add up to something nobody approved</td> <td style="padding:13px 18px;color:#CFC8BC;">A decision point that sees run context</td> </tr> <tr style="border-top:1px solid rgba(163, 156, 144,0.12);"> <td style="padding:13px 18px;color:#F3F1EC;font-weight:600;">6. Containment</td> <td style="padding:13px 18px;color:#CFC8BC;">What happens when a run goes wrong?</td> <td style="padding:13px 18px;color:#CFC8BC;">A drifting run continues until someone reads an alert</td> <td style="padding:13px 18px;color:#CFC8BC;">A declared plan to drift from</td> </tr> <tr style="border-top:1px solid rgba(163, 156, 144,0.12);"> <td style="padding:13px 18px;color:#F3F1EC;font-weight:600;">7. Execution lineage</td> <td style="padding:13px 18px;color:#CFC8BC;">Can you prove what happened and why?</td> <td style="padding:13px 18px;color:#CFC8BC;">Logs show events; nothing shows who authorized them</td> <td style="padding:13px 18px;color:#CFC8BC;">Every layer above producing decisions to record</td> </tr> </tbody> </table> </div>

1. Secure runtime isolation

This layer gives every other control a place to stand. If the agent can reach anything, there is nothing for an authorization decision to protect. In our judgment, OpenShell's documented approach (filesystem and process settings locked at creation, deny-by-default egress, credentials supplied by the supervisor) is a sound foundation. Beacon does not replace it.

2. Agent identity

The sandbox's documented identity is the executable that makes a connection. The next layer needs to know which agent it is, who deployed it, and that it is distinct from the service that launched it. Without it, a decision cannot be tied to anyone, and a record cannot show who did what. Identity depends on layer 1 because an identity is only worth trusting when the runtime it runs in is contained. In Watchlight's architecture, the identity provider establishes who the agent is, and Beacon sits downstream of it.

3. Delegated authority

An agent acts for a person and often delegates work to other agents. The original human principal must be preserved at every hop. Authority must only narrow as it passes along: a sub-agent receives a strict subset of its parent's authority, the subset is checked at every hop, and any attempt to widen it is denied before the action runs. The layer depends on identity because a grant must name a specific agent.

4. Deterministic authorization

With identity and delegated authority in place, each governed action can be decided before it runs. In Watchlight AI Beacon, the decision comes from the agent's identity, delegated authority, task, policy, arguments, and the run so far. No language model sits in the decision path, so the same policy gives the same answer every time, and no persuasive justification can talk its way past the policy. Policy is versioned. The outcome is allow, require approval, or deny.

Beacon enforces that single decision at two points: an in-process plugin and a proxy on the wire. A path that skips one still meets the other, and neither can reach a verdict the other would not.

5. Intent and plan constraints

A sequence of permitted actions can still be the wrong one. The run declares its purpose and plan, and Beacon authorizes the plan as a whole before the run starts. Each subsequent action is then checked against that purpose and what the run has already done.

Here is a hypothetical. A reporting agent is cleared to read the customer list for a quarterly summary. Later in the run, it tries to email that export to an outside address. Reading was within its authority. Sending the export was not part of its declared purpose, so the act-stage check denies it.

6. Containment

A decision about one action does not help when the problem is a run heading somewhere it should not. Beacon implements runtime containment today: stop the run, quarantine the agent, sever a delegation subtree, or revoke authority across the fleet. Drift from the declared plan can trigger quarantine while the run is active. Our post on why interception is not containment goes deeper. Containment depends on layer 5 because drift only matters against a declared plan.

7. Verifiable execution lineage

The last layer turns everything above into evidence. Beacon writes a signed, hash-chained record linking the human principal, the delegation chain, the policy decision, and the outcome. It records the decision, not the content, so changing it afterward breaks verification. It depends on all six layers because it can only record what they decide.

What the integration test shows

Watchlight and OpenShell have been tested together, and the published integration post provides a full account of the run against OpenShell's current release at the time of that post. Beacon's decision runs inside OpenShell's supervisor today, alongside the in-agent plugin.

In the test, both the destination and the tool were allowed by OpenShell. A vendor-audit read outside the agent's delegated scope was still denied by Beacon before it ran. A call made outside any governed run was denied. With Beacon unreachable, the path failed closed.

None of that makes the destination or the tool wrong. The sandbox answered where. Beacon answered whether this agent, for this person, in this run, may do this.

What is next, and not shipped

We are working toward making Beacon the single source of policy and proof for agents in OpenShell. None of the following is shipped:

Today, Beacon's containment acts at the enforcement points where it is deployed.

The wider context

The standards community is working on the same ground. The NIST NCCoE project page on software and AI agent identity and authorization says it is interested in exploring "standards-based approaches to identify, manage, and authorize access and actions taken by software agents." In the July 2026 incident we analyzed in 1,200 Agents Knew It Was Out of Scope, about 1,200 agents in sandboxes exchanged over 70,000 messages, and about 700 joined an attack. METR and Redwood Research investigated it independently. The scope lived only in the prompt, and nothing at runtime checked authority. This post makes no claim about which sandbox software was involved.

Five questions for any agent runtime architecture

Ask these of your own design and of any vendor's.

  1. Where can the process go, and who decides? Is there a trusted boundary the agent cannot rewrite, with deny-by-default egress?
  2. Which agent is acting, and for whom? Can a decision name the agent and the human principal beyond the binary or service account?
  3. Does authority only narrow when work is delegated? Is a widening attempt denied before the action runs, and checked at every hop?
  4. Is each action decided before it runs, deterministically, against the task and the run so far? Or does the decision depend on a model's judgment or a dashboard read afterward?
  5. When a run goes wrong, what stops it, and what proves what happened? Can you stop the run, quarantine the agent, and revoke authority while it is active, and show a record of who authorized each action?

If an answer is missing, the layer behind it is missing too. The layers depend on each other in order, so a gap early on weakens everything after it.

<div style="background:rgba(227, 155, 50,0.08);border:1px solid rgba(227, 155, 50,0.25);border-radius:12px;padding:16px 20px;margin:24px 0;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;"> <div style="flex:1;min-width:200px;"> <strong style="color:#E8A947;font-size:13px;letter-spacing:0.5px;">SEE THE LAYERS WORK TOGETHER</strong><br/> <span style="color:#ECE7DD;font-size:15px;font-weight:600;">Watch Beacon govern a real agent run</span><br/> <span style="color:#A39C90;font-size:13px;">A live session on your own agent framework.</span> </div> <a href="https://www.watchlight.ai/demo" style="background:#E39B32;color:#1C1A17;padding:10px 20px;border-radius:8px;font-weight:700;font-size:13px;text-decoration:none;white-space:nowrap;">Request a Demo</a> </div>

See it on a real run

A secure sandbox is a good first layer, and your architecture should have one. If you want to see how Beacon decides, contains, and proves each action on a real run, we will walk through it with you.

See a demo of Watchlight AI Beacon governing a real agent run

Watchlight AI is an independent company. OpenShell is NVIDIA's open-source project, licensed under Apache 2.0. NVIDIA and OpenShell are trademarks of NVIDIA Corporation. Watchlight AI is not affiliated with or endorsed by NVIDIA.