AI Security

Agent Sandboxing (Microsoft Execution Containers)

Agent sandboxing runs an AI agent's commands and tools inside an isolated environment whose files, network, processes and desktop access are limited by policy, so a mistaken or hijacked agent can only damage what it was allowed to touch. Microsoft Execution Containers (MXC), generally available since October 7, 2026, is a prominent open implementation.

Agent sandboxing means running the commands, code and tools an AI agent produces inside an isolated environment, with a written policy that decides which files it can read or write, which network destinations it can reach, which processes it can start and whether it can see the desktop. The idea is old (browsers, mobile apps and CI runners all use it), but agents make it urgent: an agent decides what to run at runtime, from text that may include untrusted web pages, emails and documents, so the question is no longer “can I trust this program?” but “what is the worst this program can do if it is talked into something?”. On October 7, 2026 Microsoft made Microsoft Execution Containers (MXC) generally available on Windows 11, with a cross-platform, MIT-licensed SDK. It is a good concrete example of where the field has landed.

Why Agents Need a Sandbox

A traditional application has a fixed set of behaviors you can review in advance. An agent does not: it plans, writes a shell command, calls a tool, reads the output and plans again. Microsoft’s own framing is that an agent’s containment needs can change with each prompt and each tool call, which is why static, one-size-fits-all sandboxes fall short.

Three failure modes make the case:

  • Mistakes. An agent asked to “clean up the build folder” deletes the wrong directory, or an rm -rf runs with a variable that expanded to nothing.
  • Prompt injection. A web page, README or email the agent reads contains hidden text that tells it to read credentials and send them somewhere. Filtering the text is a losing game; limiting what the agent can do is not.
  • Over-reach. A capable agent given broad access to a laptop will use it, including reading unrelated documents, using the clipboard or opening other applications.

A sandbox is a blast-radius limit: it does not stop an agent from being wrong or tricked, it bounds how much that costs. It sits beside, not in place of, approval prompts and human-in-the-loop review.

The Four Things a Policy Controls

MXC expresses policy through a unified JSON configuration and a multi-language SDK (Rust, .NET and Node), and maps the requested controls onto whatever isolation backend the platform offers. The policy areas are a good checklist for any sandbox:

AreaWhat it controlsTypical agent setting
ContainmentThe kind of isolation (process, session, WSL, microVM)Process container for quick tasks, session or microVM for long-running or desktop work
ProcessThe command, arguments, working directory and environmentFixed command, scrubbed environment (no secrets in env vars)
File systemRead-write, read-only and denied locationsProject folder read-write, dependencies read-only, home and credentials denied
NetworkInbound and outbound access, including host loopbackDefault deny egress, allow-list only the hosts the task needs
User interfaceDesktop, clipboard and GUI accessOff unless the agent genuinely drives an app

The most important single setting is the network default. In the MXC README’s Node example, the container is created with a deny-by-default egress rule (network: { egress: { default: 'deny' } }) and a timeoutMs of 30,000, so the workload cannot phone home and cannot run forever.

// Scenario: an agent harness wants to run a generated build script from a
// downloaded repo. Only the egress deny rule and the timeout are taken from the
// MXC README; the rest of this sketch (function name, fs shape) is illustrative,
// so check the SDK reference for the real API before using it.
import { runContained } from '@microsoft/mxc-sdk';   // illustrative import

const result = await runContained({
  command: 'npm run build',
  timeoutMs: 30_000,                         // kill runaway workloads
  filesystem: {
    readWrite: ['./project'],
    readOnly: ['./node_modules'],
    denied: ['~/.ssh', '~/.aws'],            // credentials never visible
  },
  network: { egress: { default: 'deny' } },  // nothing leaves unless allow-listed
});
console.log(result.exitCode, result.stdout);

Isolation Backends: How Strong Is the Wall?

Isolation is a spectrum from cheap and lightweight to heavy and strong. MXC offers several backends behind the same policy surface, which lets a developer pick the strength that fits the task.

BackendPlatformsMechanism and fit
Process containerWindows 11, macOS, LinuxUses AppContainer, Seatbelt or Bubblewrap; fast and responsive, the right default for short tool calls
Session containerWindows 11 onlyRuns under a distinct Windows account and session with its own desktop, clipboard, UI and input; suits long-running or desktop-driving agents
WSL container (WSLc)Windows 11 onlyLinux execution through WSL for Linux-first toolchains
MicroVMWindows 11 and LinuxMarked experimental; hardware-enforced isolation with full Linux compatibility

The README lists further backends (Windows Sandbox, LXC, Hyperlight and others), with Windows Sandbox, MicroVM and Hyperlight marked experimental. The general trade-off holds well beyond MXC: process-level sandboxes share the host kernel, so they are fast but rely on the operating system’s enforcement; virtual-machine boundaries put a hypervisor between the agent and the host, so they cost more startup time and memory but are much harder to escape. Match the wall to the stakes: a formatter call needs little, an agent running unreviewed code from the internet deserves more.

%%{init: {'theme': 'base'}}%%
graph LR
    classDef default fill:#ffffff,stroke:#4338CA,stroke-width:2px,color:#0F172A,rx:8px,ry:8px;
    classDef data    fill:#EEF0F7,stroke:#0D9488,stroke-width:2px,color:#0F172A,rx:8px,ry:8px;
    classDef process fill:#F7F8FC,stroke:#6366F1,stroke-width:2px,color:#0F172A,rx:8px,ry:8px;
    classDef output  fill:#4338CA,stroke:#4338CA,stroke-width:2px,color:#ffffff,rx:8px,ry:8px;

    A[Agent harness]:::data -->|"command plus policy"| M[Container SDK]:::process
    M -->|"validate and pick backend"| B{Backend}:::process
    B --> P[Process container]:::output
    B --> S[Session container]:::output
    B --> V[MicroVM]:::output
    P --> R[Workload runs under policy]:::data
    S --> R
    V --> R
    R -->|"denied access"| L[Blocked or logged]:::data

Enforcement, Learning and Permissive Modes

Writing a policy tight enough to be safe but loose enough that the agent can work is the hard part. MXC’s process containers ship three operating modes for exactly that:

ModeUngranted operationRecord
EnforcementBlockedNone, this is production
LearningBlockedWritten to a JSON activity report so you can see what the workload tried
PermissiveAllowedWritten to the report

The workflow is: start in permissive or learning mode on a trusted run, read the report to see which paths and hosts the agent actually needed, turn that into an allow-list, then switch to enforcement. Microsoft notes that permissive mode does not bypass other operating-system or organizational restrictions, and that activity reports for process containers are Windows-only. The README also carries a sharp warning about its --audit option: it turns off all sandbox security for the workload being analyzed, so never use it on untrusted code.

Interactive: Build a Policy and Watch It Decide

The widget below is a simplified teaching model of a policy engine, not the MXC schema. Set the mode and the allow-rules, then see what happens to six things a compromised agent might try.

Interactive: an agent has just read an injected instruction. Choose your policy and see which of its attempted actions get through.

    Try switching the egress default to Allow, or the mode to Permissive: the exfiltration step runs even though the file read was blocked or logged. A sandbox is only as strong as its weakest open channel, which is why the network default matters more than any single path rule.

    What a Sandbox Does Not Solve

    Containment is necessary, not sufficient. Treat these as the remaining risks after you have a good policy:

    • Allowed channels can still leak. If the agent may write to the project and talk to an allow-listed host, an injection can encode data in a commit message or an API call. Keep allow-lists small and scoped.
    • Secrets inside the sandbox are exposed. Anything you mount, pass as an environment variable or place in the working directory is visible to the workload. Give the agent narrowly scoped, short-lived credentials, not your own.
    • Confused-deputy tools. A tool outside the sandbox (an email sender, a payments call) that the agent can invoke is not contained by the sandbox. Gate those with approval and consider mandate-style limits.
    • Wrong or missing logs. If you cannot see what was denied, you cannot tune the policy. Use the learning mode and keep the reports.
    • Escape risk. A shared-kernel sandbox has a larger attack surface than a hypervisor boundary; for hostile code, prefer the stronger backend.

    What’s New (2025-2026)

    DateEvent
    Oct 7, 2026Microsoft makes Execution Containers generally available on Windows 11 and announces cross-platform SDKs (Rust, .NET, Node)
    Oct 2026Windows 365 support for MXC is generally available, for running agents on Cloud PCs
    • Broad early adoption. Microsoft lists OpenAI Codex, GitHub Copilot, OpenClaw, Replit, LM Studio, NVIDIA OpenShell and Unsloth AI as supporting MXC now, with Anthropic’s Claude Code, Nous Research’s Hermes Agent, Manus, Perplexity and others announced as coming. NVIDIA’s OpenShell has been integrated into MXC, adding network controls, credential management and OCSF auditing.
    • Management is the next layer. Intune policy for process containers on Windows 11, Microsoft Entra identity separation (so agent activity can be told apart from the signed-in user) and Agent 365 controls for local agents are described as coming soon, not shipped.
    • A shared vocabulary. The unified policy schema across Windows, macOS and Linux is the notable part: agent harnesses can describe containment once and let the SDK choose the backend.

    Practical Guidance

    SituationRecommendation
    Agent runs shell commands or generated codeRun every call in a sandbox with default-deny egress and a read-only file system except the working folder
    You are not sure what the agent needsStart in learning mode, read the activity report, then promote the observed needs into an allow-list and switch to enforcement
    Agent reads untrusted content (web, email, files)Assume prompt injection will eventually succeed and design the sandbox to make it harmless
    Agent drives a desktop or browserUse a session container or VM so it has its own desktop, clipboard and input rather than yours
    Running code you do not trust at allPrefer a microVM or full VM backend over a process container
    Agent can call tools outside the sandboxPut approvals or limits on those tools; the sandbox does not cover them

    Sandboxing does not make an agent trustworthy. It makes trust unnecessary for the most dangerous mistakes: when the policy says no, it does not matter how convincing the injected instruction was.

    How to Use: Run an agent's shell command in a deny-by-default sandbox (Linux, bubblewrap)

    python
    import subprocess
    
    # Scenario: a coding agent wants to run `pytest` on a repo it just edited.
    # The command runs inside bubblewrap (the Linux backend MXC uses by default):
    # the system is read-only, only the project is writable, and there is no
    # network at all, so even an injected instruction cannot send data out.
    def run_contained(cmd: list[str], project: str, timeout_s: int = 30) -> str:
        sandbox = [
            "bwrap",
            "--ro-bind", "/usr", "/usr",        # system binaries, read-only
            "--ro-bind", "/lib", "/lib",
            "--ro-bind", "/lib64", "/lib64",
            "--proc", "/proc", "--dev", "/dev",
            "--tmpfs", "/tmp",                  # scratch space that vanishes
            "--bind", project, "/work",         # the only writable path
            "--chdir", "/work",
            "--unshare-net",                    # no network namespace access
            "--die-with-parent",
        ]
        done = subprocess.run(sandbox + cmd, capture_output=True, text=True, timeout=timeout_s)
        return done.stdout + done.stderr
    
    print(run_contained(["python", "-m", "pytest", "-q"], "/home/dev/app"))
    # Reading ~/.ssh or calling an external API from inside fails: those paths and
    # sockets simply do not exist in the sandbox.
    

    Ready to build?

    Leverage AI technologies to build your product stack

    Superteams can help you build, deploy and launch AI application stacks using open source technologies — from architecture through to production.

    Talk to Superteams