Start Debugging

Copilot Local Sandbox vs Cloud Sandbox vs a Dev Container: How Much Isolation Each Gives an Agent

Turn on the local sandbox for everyday Copilot CLI work, move to a cloud sandbox when the code or the task should never touch your laptop, and use a dev container when the team needs the same reproducible toolchain. Compared on Copilot CLI 1.0.104: what each boundary isolates, what it leaks, what it costs, and how to stack them.

Short answer: the local sandbox is the default you should turn on today, because it costs nothing, keeps your toolchain, and fences every shell command, grep, local MCP server and LSP server Copilot spawns. It is the weakest of the three boundaries, though: the agent process itself still runs as you, and since Copilot CLI 1.0.100 sandboxed commands can reach localhost and your private network by default. A cloud sandbox (copilot --cloud --experimental) is the strongest: the whole session runs in an ephemeral GitHub-hosted Linux environment with nothing of your laptop in it, billed per second. A dev container sits in the middle. It isolates the whole agent process, not just its commands, but shares your kernel, sees whatever you mount, and has open egress unless you add a firewall. Everything below is checked against Copilot CLI 1.0.104 (October 27, 2026), the copilot-cli dev container feature 1.1.3, and GitHub’s docs as of today. Cloud sandboxes are still in public preview.

Three boundaries drawn in three different places

The names make these sound like three sizes of the same thing. They are not. Each one draws the line around a different part of the agent:

That is why “how much isolation” has no single ranking. The local sandbox can be stricter than a sloppy dev container on network egress, and a dev container can be stricter than the local sandbox on what the agent process itself can read.

Feature matrix

Local sandbox (CLI 1.0.104, GA)Dev container (copilot-cli feature 1.1.3)Cloud sandbox (CLI 1.0.104, preview)
What is isolatedChild processes only (shell, grep/glob, local MCP and LSP servers)Agent process and all childrenEntire session
Agent process runs asYou, on your hostContainer userGitHub-hosted environment
KernelYoursYours (Docker Desktop VM on macOS/Windows)Not yours
Your home dir, ~/.ssh, ~/.awsRead-only by default, writes blockedInvisible unless mountedNot present
WorkspaceRead/writeRead/write (bind mount)Not mounted from your machine
Network defaultInternet and local network allowed (local since 1.0.100), host allow/deny rules availableFully open unless you add a firewallInherits Copilot cloud agent policies
git / gh credentialsFake tokens, proxy injects real ones per approved hostWhatever you pass in (COPILOT_GITHUB_TOKEN, GH_TOKEN)Your existing Copilot authentication
Headless -p runsYes (copilot --sandbox -p ...)YesNo, interactive only
Survives closing the laptopNoNoYes, stop/resume with snapshot
CostIncluded in the seatYour Docker hostPer second: $0.000024 compute, $0.000003 per GiB memory, $0.005 per GiB-month snapshot
Admin controlsandbox key in managed settings, failIfUnavailableNone from GitHub”Cloud Sandbox access” org/enterprise policy, off by default

Local sandbox: the fence you should always have

Turning it on is one command, and you can make it sticky:

# Copilot CLI 1.0.104
copilot --sandbox                 # this session only
copilot --sandbox -p "run the tests and fix the first failure"   # headless, still sandboxed

# inside a session: enable and persist to ~/.copilot/settings.json
/sandbox enable
/sandbox policy npm install       # print exactly what that command would get

The default policy is deny-by-default on the filesystem: the working directory, .git and temp are writable, the rest of the repo and your tools on PATH are read-only, and package-manager caches are writable when developer-tool access is on. Git and gh inside the sandbox receive placeholder tokens, and a local proxy swaps in the real ones only for approved HTTPS hosts. That last part is the strongest feature of the local sandbox, and neither alternative gives it to you for free: a malicious postinstall script can run, but it cannot read a real GitHub token out of the environment. The full setup is in how to turn on Copilot local sandboxing and restrict what an agent can touch.

Know its three holes before you rely on it:

  1. The agent process is not sandboxed. The CLI’s built-in file tools enforce the policy in software, best effort, with no OS backstop. If you are worried about a compromised Copilot process rather than a compromised npm dependency, this boundary does not cover you.
  2. Local network is open by default. Copilot CLI 1.0.100 (October 19, 2026) changed the default so “commands can reach localhost and private-network services.” That fixed a lot of broken test suites, but it also means a sandboxed command can talk to your local Postgres, your Docker socket over TCP if you exposed one, and your home router. Turn local access off in /sandbox (Network tab) if your tests do not need it.
  3. Remote MCP servers are never sandboxed. The sandbox constrains processes on your machine, not HTTP MCP servers somewhere else.

Pick the local sandbox when:

Dev container: isolate the agent, not just its commands

The official feature landed in devcontainers/features, so the minimum is one line:

// .devcontainer/devcontainer.json
// devcontainers/features copilot-cli 1.1.3 (installs Copilot CLI 1.0.104 at time of writing)
{
  "name": "agent-sandbox",
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "features": {
    "ghcr.io/devcontainers/features/copilot-cli:1": { "version": "latest" }
  },
  "remoteUser": "vscode",
  // Pass a fine-grained token instead of mounting ~/.config/gh
  "remoteEnv": {
    "COPILOT_GITHUB_TOKEN": "${localEnv:COPILOT_GITHUB_TOKEN}"
  },
  "runArgs": ["--cap-drop=ALL", "--security-opt=no-new-privileges"]
}

COPILOT_GITHUB_TOKEN takes precedence over GH_TOKEN for Copilot authentication, which lets you hand the container a token scoped to Copilot and nothing else. The feature also adds a postStartCommand that runs copilot update if auto-update is enabled, so a rebuilt container drifts to the newest CLI unless you pin version.

What a dev container buys you is that the agent process, the CLI’s built-in file tools, its MCP servers and every command live in a filesystem namespace that only contains what you put there. ~/.ssh, ~/.aws, your other repos and your browser profile simply do not exist unless you mount them. On macOS and Windows, Docker Desktop adds a Linux VM between the container and your real OS, which is a meaningfully harder wall than Seatbelt alone.

What it does not buy you:

Pick a dev container when:

Cloud sandbox: nothing of yours is in the room

# Copilot CLI 1.0.104, cloud sandboxes in public preview
copilot --cloud --experimental

# Since 1.0.92 you can also press Ctrl+E before the first prompt
# to switch a new session between local and cloud.

Each --cloud applies to that one session; it does not change the default. In the Copilot app you pick the cloud option when you create a session. Behind it, each session gets its own ephemeral Linux environment, isolated from your machine and from your other sessions. Stopping a session snapshots files, environment variables and in-progress work, and you can resume it from any device. Deleting it removes the environment and the snapshot.

This is the only one of the three where a fully compromised agent process still cannot reach your laptop, your LAN, your SSH keys or your other repositories, because none of them are there. GitHub says cloud sandbox policies “share the same configuration as Copilot cloud agent policies,” so the org-level controls you already set for the cloud agent apply. The agent firewall page only describes the GitHub Actions environment the cloud agent runs in, though, so check the behavior yourself: ask the session to curl a host outside your allowlist before you trust a cloud sandbox with untrusted code.

The constraints are real:

Pick a cloud sandbox when:

The gotcha that decides it for you

Two constraints pick for you before preference does.

If it must run headless, the cloud sandbox is out. No -p, no -i. Scheduled jobs and CI pipelines get the local sandbox on the runner, a dev container, or the separate Copilot cloud agent, which runs on GitHub Actions with its own firewall and opens a PR instead of giving you a terminal.

If you nest the local sandbox inside a dev container, test it first. It is tempting to stack the two: container for the agent, sandbox for its commands. On Linux the local sandbox is bubblewrap with its own user and network namespaces, and Docker’s default seccomp profile and dropped capabilities usually refuse unprivileged namespace creation. When that happens Copilot fails with the bubblewrap “requires unprivileged user and network namespaces, which this host refused” error, and with sandbox.enabled set it does not fall back to running unsandboxed: every shell command fails. Loosening the container (--privileged, seccomp=unconfined) to make the inner sandbox work weakens the outer one. In practice, pick one boundary per layer: dev container plus a firewall, or the local sandbox on the host.

Stacking that does work well is local sandbox plus cloud agent: fence your interactive sessions locally, and send anything you would not run on your own machine to /delegate or a cloud sandbox.

Which one to reach for

Turn on the local sandbox everywhere, today, and switch local network access off unless you need it. It is free, it is GA, and its credential proxy closes the most common real-world leak (a dependency reading GITHUB_TOKEN). Use a dev container when the team already wants a reproducible toolchain, and add a default-deny firewall, because the container alone gives you filesystem isolation and almost nothing on the network. Use a cloud sandbox for untrusted code and long-running work you want off your machine entirely, and put a budget on it, since memory is billed on allocation.

The ranking for “how much can a compromised agent reach” is cloud sandbox, then a firewalled dev container, then the local sandbox. The ranking for “how much friction do I add” is exactly the reverse, which is why most developers should start at the bottom and climb only when the code in front of them gets less trustworthy.

Sources

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Back