Last time, we covered AI risks inside and against your organization, and how to reduce them. In this post, we’ll touch on some specific risks and mitigations for using coding agents. Coding agents are a specific case of “AI in your organization,” so the guidance from the prior post still applies. But developers writing code with agents typically have more access to sensitive data and systems than other folks at your organization, and coding agents are often granted broad permissions to do things like “run arbitrary code,” so it’s worth going beyond the basics to control and restrict coding agents, especially on developer endpoints.
Letting a coding agent run wild directly on your endpoint is a pretty bad idea. Your machine almost certainly contains sensitive credentials, whether on disk, in an unlocked password manager vault, as browser session cookies, or, more likely, all of the above. You probably have third-party dependencies that could have prompt injection payloads, and you might have longer sessions with an AI agent where it can go off the rails even without an explicit prompt injection. Finally, your computer can likely access the internet and make a mistake that either uses those credentials to access systems it shouldn’t or exfiltrates them somewhere you don’t want them to be.
Together, these three factors create the lethal trifecta. The good news? While it’s difficult to completely avoid giving agents access to private information, network access, and untrusted input, sandboxing can significantly reduce all three surfaces.
Sandboxing coding agents is an extremely active area of development right now, so if you’re hoping for a “Latacora-blessed” option, I’ve got bad news for you: we don’t have one, and if we did, it would probably be outdated within a few hours. And while I’m a security engineer primarily thinking about security concerns, I understand you probably have non-security goals for your coding agents like “be productive,” “work with my existing toolchain,” and “my team will like this.” So to make this post relevant to a broad set of organizations and up to date for at least a few weeks, I’ll focus on what you should get out of a sandbox and how to evaluate the options available for your coding agent of choice, rather than recommending specific tools.
A quick note on “auto” modes (such as Claude Code’s auto mode, or Codex’s auto-review mode): these are increasingly popular, and often the default mode. They rely on an LLM “judge” to classify the underlying agent’s actions and automatically approve or reject permission prompts. While they’re certainly safer than running to full auto-approve/YOLO mode, and in many cases safer than requiring manual permission prompts due to approval fatigue, they’re not a substitute for strict, deterministic sandboxing. Anthropic’s own testing shows auto mode missing 11% of harmful actions, and novel prompt injection techniques are able to reliably execute malware when auto mode is on.
Filesystem sandboxing
Your sandbox should ensure that agents only have access to the files they need. This should cover both reading and writing: you want to keep them from reading credentials they don’t need, and from writing to files unrelated to the task at hand. This is an area where the built-in agent sandboxes are often insufficient as they often provide read access to your whole filesystem.
The challenge with fully sandboxing reads is that many coding tools rely on shared cache directories. For example, uv needs read access (and, for installing new dependencies, write access) to ~/.cache/uv. There are three main approaches to strengthening the built-in sandboxing of filesystem operations:
- Block access to sensitive directories. You can identify which directories
contain secrets (for example,
~/.aws,~/.ssh, browser cookies, etc) and restrict reads to those directories. However, keeping this list up-to-date is challenging and error-prone. - Change the read behavior to default-deny. Configure your agent sandbox to not allow reads anywhere except the project directory and specifically allowed shared cache and temp directories. This isn’t foolproof security-wise—an agent with write access to a shared cache directory could escape the sandbox by dropping malicious code for other, unsandboxed processes to pick up—but it’s a pretty good start.
- Use a VM. The best way to fully isolate the filesystem is to give the agent its own filesystem in a separate VM. That way, it gets its own installed packages, cache directories, etc. This can also be helpful for productivity: instead of worrying about agents installing conflicting dependency versions or language package managers or messing with each others’ caches, each agent gets its own filesystem to play in. This could be a local VM running on a developer endpoint, or a cloud-based VM / Cloud Development Environment.
Even within the project directory, be careful with write access. Make sure the
agent can’t write to files that allow it to change its own behavior (for
example, allowing Claude Code to update settings in ./.claude, which is
blocked by default) or configure tools that are likely to be run by the user
outside of the agent sandbox (for example, allowing Claude Code to update
.git/config to set some malicious command as the difftool, which could
trick a user into running that malicious command when they run git diff in
order to inspect changes that the agent made—Claude Code blocks this by default
as well).
Network sandboxing
You should also control what network access the agent has. Revisiting the “lethal trifecta,” the goal is minimizing the agent ‘s access to external network resources, making it more difficult to exfiltrate any sensitive data (such as your proprietary source code) out to an untrusted network location.
As with filesystem sandboxing, it’s challenging to block 100% of network traffic. And even allowing very common domains like github.com presents risks, because a malicious or misguided agent could end up uploading private data to a public GitHub repository. However, combined with filesystem sandboxing to reduce the amount of private information an agent can access, overall risk can be reduced by blocking the agent from accessing fully untrusted destinations or being tricked into communicating directly with an attacker-controlled server via prompt injection.
The built-in agent sandboxes typically provide good support for network
restrictions, both through tools that fetch web pages (like Claude Code’s
“Fetch”) and the OS-level sandboxes they use for code execution (like Claude
Code’s “Bash” tool sandboxing).
Make sure those restrictions are consistent across both mechanisms, as agents
will try both specific network tools and running shell commands to access the
network (Claude Code, for example,
merges WebFetch permission rules into the sandbox’s allowedDomains configuration,
but this behavior may differ across different agent harnesses).
Support for network sandboxing is uneven across VM-based isolation solutions. You might need to combine a VM for filesystem isolation with the agent’s built-in network sandbox if you’re using a VM sandboxing solution that doesn’t natively provide network isolation. Ideally, though, network isolation should happen at the VM level, so that development servers or other tools running inside the VM get the same network egress protections as your coding agent.
Credential management
Ideally, your agents should be able to work without touching any credentials. This is easy for us to say but probably more difficult for you in practice: the ability to test features end-to-end often requires the ability to authenticate with third-party systems. Additionally, agents usually need credentials to talk to their LLM providers (Anthropic, OpenAI, etc), unless you’re using a local model.
There are two actions you can take to reduce the risk of agents misusing credentials:
- Get rid of any credentials possible, and reduce the scope of remaining credentials. Configure your development environment to talk to mocked versions of third-party services by default, rather than the real APIs. When that’s not possible, use tightly scoped credentials and create separate credentials for development that don’t have access to production systems. This falls into the category of “stuff that has always been a good idea.” It’s especially important when working with agents, but it’s a great security win regardless (and it also makes things like running end-to-end tests in CI without depending on third-party systems much easier).
- Move credentials out of the agent’s reach. This is a little more complicated, but increasingly supported by agent sandboxing solutions. Some sandboxes have built-in support for this, but you can also wire it up yourself by running a proxy server outside the sandbox. The idea is if you’re running your agent inside a VM or container, instead of giving credentials to the agent inside that VM, you run a proxy outside the VM that injects the credentials into requests as they leave the VM (selecting credentials for the request based on the target hostname, so credentials are only sent to the systems they’re meant for). Then, you point your agent / software inside the VM to use that proxy. A straightforward example would be getting LLM provider credentials out of the agent’s reach: instead of having Claude Code talk directly to the Anthropic AI, you’d run one of the many available open-source LLM gateway/proxies outside the VM, and point Claude Code at that proxy. The proxy has your real credentials; the agent in the VM never sees them. A similar approach can be used for any credentials that need to be passed to third-party services.
Kernel vs. container isolation
Here, we’re getting a bit in the weeds. But since you’re at the end of a lengthy, two-part post on the Latacora blog, I’m going to assume you’re OK with it. When evaluating container or VM-based sandboxing approaches, it’s useful to consider what kind of isolation exists between the sandbox environment and your host. The most minimal level of isolation is container-based isolation: these use Linux cgroups to monitor and control resource usage of the workload (CPU usage, memory usage, etc.) and Linux namespaces to isolate what that workload can see (presenting a filtered view of the host filesystem, PIDs, network interfaces, etc.) While this is a good start (and much better than not isolating agents from the host filesystem), it isn’t designed to be a hard security boundary: there are broad classes of vulnerabilities allowing containerized workloads to break out and access resources on the host system. Firecracker, Kata Containers, and gVisor all exist specifically to strengthen this boundary and get stronger isolation for preventing these types of breakouts.
If you’re not running on Linux (or Windows with Windows Containers), you already have another layer of isolation in play: containers running on macOS are hosted inside a Linux VM. In most setups (like Docker Desktop), all containers share a single Linux VM, so a container breakout is generally limited to that VM—though depending on what else is running there, that can still be significant. Some container runtimes (like Apple’s container) create a separate VM for each container, which gives you much better isolation.
In any case, you should look for sandboxing solutions that provide VM-level isolation (a separate kernel/OS) for the agent. While the idea of a sandboxed agent exploiting a container breakout to get access to the host system may seem a bit far-fetched, we’ve seen agents be quite aggressive in punching through any available hole in their sandbox in order to complete the task at hand. This is especially true when they’re performing security work, such as penetration testing your app. VM-level isolation gives you the best setup for keeping your sandboxes intact even if the agent tries its best to find a way out. One straightforward way to get this level of isolation is to use cloud-based sandboxes rather than local sandboxes, which require more setup (and a plan for getting your code into / out of the sandbox, rather than just using a local file mount), but provide excellent isolation out of the box (and can also help productivity, but allowing engineers to run a bunch of sandboxes at once, and leave them running for long-lived tasks).
Conclusion
In part 1 we explored the current landscape of AI risk and defined a new baseline level of controls that simultaneously address the risk of AI being used against your organization, and the risks of adopting AI within your organization. In Part 2, we dug deeper into coding agents, with a practical set of goals for sandboxing this particular form of AI adoption within your organization. Those controls, tools, and goals all work together to decrease overall risk—and none of them are new. If there’s one takeaway from all of this, it’s that while the risks and threats may feel new, and the pace of attacks is certainly ramping up, the fundamentals of how to secure your accounts, endpoints, deployment pipelines, and production systems haven’t changed. AI-empowered attackers and rogue agents within your organization are able to find even minor weaknesses faster, cheaper, and more easily than ever before, and the best defense is to nail those fundamentals to keep your organization safe.