{"slug": "sandboxing", "title": "Sandboxing", "summary": "Zed, the code editor from Zed Industries, has introduced sandboxing for its agent panel's terminal and fetch tools, enabled by default for all users starting with the 1.14 release. The sandbox, enforced by operating system APIs like Seatbelt on macOS, namespaces via Bubblewrap on Linux, and WSL on Windows, restricts agents from writing outside project directories, modifying .git, or making network requests, with agents able to request temporary privilege escalation. This move addresses the risk of prompt injection attacks and the inability to trust agents with unrestricted access, as highlighted by a real-world incident where a modified AGENTS.md file instructed an agent to exfiltrate a secret API key.", "body_md": "Zed now supports [sandboxing](https://zed.dev/docs/ai/sandboxing) within the agent panel.\n\nSandboxing restricts what the agent is able to do when using the `terminal`\n\nand `fetch`\n\ntools. These restrictions are enforced by the operating system and do\nnot rely on an agent following instructions.\n\nSandboxing is enabled by default for all users, starting on the 1.14 release.\n\n[Why sandboxing?](#why-sandboxing)\n\nSome users prefer to tightly control what the agent is allowed to do, while others opt for \"YOLO mode\" and give agents freedom to do anything and everything on their computer.\n\nThere are advantages and downsides to both approaches. Manually approving/denying each action the agent takes can get tedious, and sacrifices some of the automation which agents provide. On the other hand, an agent in YOLO mode can wreak havoc on your machine (or any machines you can reach over the network).\n\nThe tension comes from the fact that agents cannot be trusted to determine\nwhether an action is something the user would want. You may be disappointed to\nlearn that we are not announcing that we have solved this [famously hard\nproblem](https://en.wikipedia.org/wiki/AI_alignment). Until we do, sandboxing is the best way to constrain an agent's behavior.\n\n[Sandboxing in Zed](#sandboxing-in-zed)\n\nIn Zed, the [agent panel](https://zed.dev/docs/ai/agent-panel)'s `terminal`\n\nand `fetch`\n\ntools 1 are now sandboxed by default. The default sandbox rules forbid an agent from writing outside the\nproject directories, writing to\n\n`.git`\n\n, or making network requests.For many interactions, this is more than enough. But when it's not, agents can request permission to temporarily escalate their privileges. The user will see:\n\n- which privileges the agent is asking for\n- a reason why they're asking for it\n\nNote: The agent maynotrequest write access to`.git`\n\n, since this allows an agent to write hooks that run outside the sandbox.\n\n[Implementation](#implementation)\n\nSandboxes are implemented using operating system APIs:\n\n- macOS uses Seatbelt\n- Linux uses namespaces (through Bubblewrap)\n- Windows uses WSL\n- Non-WSL shells on Windows do not support sandboxing\n\nLinux users will need to make sure they have a working `bwrap`\n\nbinary without\nthe `setuid`\n\nbit set in their `$PATH`\n\n. WSL users will need to make sure this is true inside their WSL environment.\n\n[Can't I just tell my agent not to edit certain files?](#cant-i-just-tell-my-agent-not-to-edit-certain-files)\n\nYou can, and a lot of the time, that's sufficient. Modern LLMs are pretty good\nat following instructions, but it's not a guarantee. Instructions also do very little to protect against [prompt injection\nattacks](https://en.wikipedia.org/wiki/Prompt_injection).\n\nPerhaps you work on an open source project, and you're reviewing a contributor's PR. You open an agent and ask \"review this PR\". Little do you know, however,\nthat the PR contains a modified `AGENTS.md`\n\nthat instructs your agent to upload\n`$MY_SECRET_API_KEY`\n\nto a server controlled by the attacker.\n\nThis has [already happened](https://labs.cloudsecurityalliance.org/research/csa-research-note-comment-control-github-prompt-injection-20/), and it's only going to get more common.\n\nThe benefit of sandboxes is that they simply do not allow access to certain resources 2.\n\n[But what about fine-grained rules?](#but-what-about-fine-grained-rules)\n\nZed has supported fine-grained rules for the `terminal`\n\ntool for a while. You\ncan, for example, disallow any command that matches `git .*`\n\n. Why bother with\nsandboxing when we could ship a set of rules that achieves the same\nrestrictions?\n\nThe answer is that it's simply not possible. A rule that bans `git .*`\n\ndoes\nvery little to prevent an agent that *really wants* to modify your `.git`\n\nfolder. It can:\n\n`bash -c 'git ...'`\n\n`EVIL_CMD=\"git ...\" bash -c $EVIL_CMD`\n\n`echo 'git @$' > evil_git; chmod +x evil_git; evil_git ...`\n\n`python ...`\n\n- the list goes on...\n\nFine-grained rules work well as a guideline when dealing with a well-aligned agent. They fall over instantly in the presence of an even vaguely sophisticated attacker.\n\n[Sandboxes are tricky to get right](#sandboxes-are-tricky-to-get-right)\n\nSandboxes are similar to other software features in many respects, but differ in a couple of key ways:\n\n- A single bug may compromise a user's security.\n- There must be no bugs\n*even in the presence of adversaries*.\n\nThis means that you can't just say \"Oh, this won't happen in practice\". Instead, you need to ask:\n\nCould an attacker make this happen?\n\n[Symlink swaps](#symlink-swaps)\n\nA good example of this is what I've been calling the \"symlink swap\" attack. Note\nthat Zed's sandbox *does* catch this attack and will fail-closed, meaning that\nthe untrusted command will not be run.\n\nSome background: on Linux, Zed's sandbox controls filesystem access\nusing Bubblewrap. This is a program called `bwrap`\n\nwhich allows running a\ncommand within a \"namespace\" 3. The simplest\n\n`bwrap`\n\ninvocation might be:This command:\n\n- creates a new namespace\n- mounts the real\n`/`\n\ninto the namespace at`/`\n\n, read-only - runs\n`echo hello`\n\nwithin the namespace\n\nNote that, without `--ro-bind / /`\n\n, this command would fail, since it wouldn't\nbe able to find `echo`\n\n.\n\nWhen Zed creates a sandbox with access to specific directories, it constructs a\nset of `--bind`\n\nor `--ro-bind`\n\narguments to pass to `bwrap`\n\n.\n\nThe flow for the symlink swap attack goes like this:\n\n- A malicious agent is given write access to\n`/foo`\n\n. - It then spawns two subagents which run in parallel:\n- Subagent 1 repeatedly tries to write the attacker's public key to\n`/foo/bar/.ssh/authorized_keys`\n\n- Critically, it also requests write access to\n`/foo/bar`\n\n. A user is likely to grant this, since it already has`/foo`\n\n, so it seems safe.\n\n- Critically, it also requests write access to\n- Subagent 2 replaces\n`/foo/bar`\n\nwith a symlink to`/home/alice`\n\n- Note that this can succeed even if the sandbox only grants\n**read** access to`/home/alice`\n\n- Note that this can succeed even if the sandbox only grants\n\n- Subagent 1 repeatedly tries to write the attacker's public key to\n- Initially, the writes to\n`/foo/bar/.ssh/authorized_keys`\n\nfail, since there's no such file. - However, after the second subagent's symlink swap succeeds, the path\n`/foo/bar/.ssh/authorized_keys`\n\npoints to`/home/alice/.ssh/authorized_keys`\n\n. - But this is still blocked by the sandbox, since write access to\n`/home/alice`\n\nwas never granted.\n\nSo far, so good. But there's a catch! There's a small timing window between:\n\n- the time when the user is shown the prompt and clicks \"allow\"\n- the time when the path is given to\n`bwrap`\n\nIf the symlink swap happens in that window, then:\n\n- the user sees\n`/foo/bar`\n\nand approves `/foo/bar`\n\nbecomes a symlink to`/home/alice`\n\n- Zed passes\n`--bind /foo/bar /foo/bar`\n\nto`bwrap`\n\n- Within the sandbox,\n`/foo/bar`\n\nis mounted to the real`/home/alice`\n\n, with write access.\n\nAt this point, the sandboxed program can write to\n`/foo/bar/.ssh/authorized_keys`\n\n, which resolves to\n`/home/alice/.ssh/authorized_keys`\n\n. The attacker's public key is now trusted by\nthe machine!\n\nThis is a classic *time-of-check-time-of-use* (TOCTOU) bug. Left unaddressed, it\nwould allow a malicious agent to gain write access to any directory it has read\naccess to.\n\n**In practice**, the timing window is incredibly small - it's essentially just\nthe time it takes to spawn a subprocess - usually a few hundred microseconds.\nBut that's not good enough. Attackers can repeatedly try 4, and they only need to\nsucceed once.\n\n[How safe is the sandbox?](#how-safe-is-the-sandbox)\n\nSandboxes are just one layer in a [defense in depth](https://en.wikipedia.org/wiki/Defense_in_depth_(computing)) strategy.\nFor more detail, check out our [docs on this topic](https://zed.dev/docs/ai/privacy-and-security).\n\nThe sandbox covers the `terminal`\n\nand `fetch`\n\ntools in Zed's agent, but it does\n*nothing* to protect you when you use:\n\n- Other tools in the Zed agent like the\n`edit`\n\ntool. - Agents connected over\n[ACP](https://zed.dev/acp) - LSP and MCP servers\n- The regular built-in terminal\n- External programs like\n`ghostty`\n\nor VSCode\n\nA malicious agent may not be able to execute `pwn_my_machine.sh`\n\nfrom within the\nZed agent's terminal, but it *might not need to*, if it can trick you into\nrunning it outside the sandbox.\n\nFor example:\n\n- It could add a\n`build.rs`\n\nfile that runs the script. Then, when you run[5](#user-content-fn-5)`cargo run`\n\nin the built-in terminal, it executes that`build.rs`\n\n*outside the sandbox*. - If given access to write to\n`/home/alice`\n\n, it could edit your`.bashrc`\n\nto run the script*outside the sandbox*. - It could edit your project using regular editing tools to contain a Rust crate\nwith a malicious procedural macro\nthat runs the script.[6](#user-content-fn-6)`rust-analyzer`\n\nwill then build and run this macro*outside the sandbox*. - If your project contains a Git submodule, it could install a hook that runs\nthe script when you commit. If you run\n`git commit`\n\nfrom a regular terminal app, then the hook would run*outside the sandbox*.\n\nThe list is almost endless. Closing everything requires more than what sandboxing alone can provide.\n\n[Wrapping up](#wrapping-up)\n\nSandboxing is now enabled by default in Zed's agent panel. The `terminal`\n\nand\n`fetch`\n\ntools run with restrictions enforced by the operating system: agents\ncan't write outside your project directories, can't touch `.git`\n\n, and can't\nreach the network unless you grant access. When an agent needs more, it has to\nask, with a reason you can evaluate. As one layer in a security strategy, it\nmeaningfully limits what an agent can do to your machine.\n\n[Footnotes](#footnote-label)\n\n-\nThe\n\n`create_directory`\n\ntool, while not strictly \"sandboxed\", participates in the sandboxing permissions flow. Note that, even when permission has*not*been granted, the`create_directory`\n\ntool may temporarily create the requested directory, but will clean it up if permission is not granted.[↩](#user-content-fnref-1) -\nAssuming no bugs in the sandbox implementation.\n\n[↩](#user-content-fnref-2) -\nNamespaces are the core primitive provided by the Linux kernel that underpin sandboxes. They allow creating a context in which a user can run a program where it gets a simulated OS environment (i.e. it has a different view of the filesystem, devices, users, etc.).\n\n[↩](#user-content-fnref-3) -\nThere are also techniques that can widen this gap, which makes it even easier to exploit.\n\n[↩](#user-content-fnref-4) -\nA\n\n`build.rs`\n\nis a special file in a Rust project that runs code before compiling your programor library.[↩](#user-content-fnref-5) -\nA procedural macro is another Rust feature that allows writing a program that manipulates Rust source code (for example,\n\n`#[derive(Serialize)]`\n\nis a procedural macro). While they are typically pure functions, they are not required to be, and can even do some pretty cursed things like[forking the compiler](https://crates.io/crates/whichever-compiles/1.0.0)![↩](#user-content-fnref-6)\n\n### Related Posts\n\nCheck out similar blogs from the Zed team.\n\n### Looking for a better editor?\n\nYou can try Zed today on macOS, Windows, or Linux. [Download now](/download)!\n\n### We are hiring!\n\nIf you're passionate about the topics we cover on our blog, please consider [joining our team](/jobs) to help us ship the future of software development.", "url": "https://wpnews.pro/news/sandboxing", "canonical_source": "https://zed.dev/blog/sandboxing", "published_at": "2026-08-05 17:26:29+00:00", "updated_at": "2026-08-05 17:37:00.791763+00:00", "lang": "en", "topics": ["ai-safety", "ai-agents", "ai-tools", "ai-policy"], "entities": ["Zed", "Zed Industries", "Seatbelt", "Bubblewrap", "WSL", "GitHub", "Cloud Security Alliance"], "alternates": {"html": "https://wpnews.pro/news/sandboxing", "markdown": "https://wpnews.pro/news/sandboxing.md", "text": "https://wpnews.pro/news/sandboxing.txt", "jsonld": "https://wpnews.pro/news/sandboxing.jsonld"}}