Model or dataset
trailofbits/coop avatar
trailofbits/coop

coop runs coding agents inside disposable microVMs

Isolated VM environment for running Claude Code and Codex

796 stars44 forksRustApache-2.0

At a glance

What is it?
coop is a Rust CLI from Trail of Bits that starts an isolated virtual machine for each coding session and hands Claude Code, Codex or Grok Build full tool access inside it, so Docker, git, compilers and package managers cannot touch the host. Each VM is cheap to create and destroy, and the configuration is a TOML file rather than a daemon.
Who is it for?
Adopt coop if you let an agent run shell commands on your machine and want those commands confined to a throwaway VM, particularly on Linux where the Firecracker backend gives a microVM with a real kernel. Skip it if you are on Linux arm64, which is buildable but untested, or if macOS without Lima installed, because setup fails without it.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Full tool access, confined to a machine you can throw away

The proposition is stated in the first line of the README: isolated VM environments for running Claude Code, Codex and Grok Build.

coop is a Rust CLI that manages disposable virtual machines where those agents have full tool access. Docker, git, compilers and package managers, all of it, and none of it a risk to the host machine. Each VM is described as isolated, reproducible, and cheap to create and destroy.

That last property is what makes the design work in practice. An agent that can install packages, run compilers and modify a filesystem is dangerous precisely because the damage persists. A disposable VM removes the persistence problem rather than trying to sandbox the agent's behaviour, so there is no allowlist to maintain and no prompt-injection defence to get right. The risk becomes the cost of rebuilding an image.

The name is spelled out in the README, which is unusually thorough about it: coop is pronounced with one syllable, rhymes with loop, like the thing you keep chickens in, and explicitly not co-op.

Two configuration hooks make the environment yours rather than generic. Shared dotfiles can be copied in through `guest_files`, and a global `post_create` command installs tools for each new VM.

Install is a curl pipe, a cargo build, or nix build

Three install routes are documented, and the fastest one is a shell pipe:

bash
curl -fsSL https://raw.githubusercontent.com/trailofbits/coop/main/install.sh | bash

Building from source requires Rust and CMake:

bash
cargo build --workspace --release
cp target/release/coop target/release/coop-proxy /usr/local/bin/

Note that two binaries come out of that build. coop is the CLI, and coop-proxy is a separate binary that has to be copied alongside it.

With Nix, `nix build` produces both binaries in `result/bin`, and `nix run . -- --help` runs the CLI. The repository carries flake.nix and flake.lock, and the documentation points to separate pages for Nix builds and Nix development.

After installation, the VM template image is built with:

bash
coop setup

On Linux that step also installs Firecracker and fetches a guest kernel. On macOS you need Lima first, installed with `brew install lima`, because setup fails without it. The README states that coop is tested on macOS arm64 and Linux x86_64, and that Linux arm64 builds are available but untested.

Keeping it current is a separate command:

bash
coop update

with its own command reference page and an `updates` section in the configuration reference.

Each project gets its own instance

The usage pattern is short enough to read in one go. You change into your project directory and bring up an instance, then launch whichever agent CLI you want:

bash
cd ~/code/my-project
coop up
coop claude
# or
coop codex
# or
coop grok

The per-project framing matters more than it looks. The instance is scoped to the directory you were in when you ran `coop up`, so a different project means a different VM with a different set of files visible. That is the isolation boundary doing real work, and it means the workspace sync rules matter as much as the VM boundary.

The documentation tree shows how much surface the tool has. There is an index, a getting started page, a command reference, a configuration reference, pages on images and profiles, workspace sync, editor integration, multi-instance, platform backends and shell completion, plus a separate page for each of the three agent integrations: Claude Code, Codex and Grok Build.

Two pages are worth singling out because they answer the question a security-minded reader asks first. There is an architecture document and a trust model document, and the repository also carries a SECURITY.md for reporting vulnerabilities, a CHANGELOG.md, a RELEASING.md, an AGENTS.md and a CLAUDE.md.

The workspace is a Cargo workspace with a deliberately odd member list

The Cargo manifest at the root is small and its comments explain the structure better than prose would.

toml
[workspace]
members = ["coop-proxy"]
# No `default-members`: with a root package present, plain `cargo build` /
# `cargo test` build only `coop`, so the integration scripts and everyday dev
# builds don't pull in coop-proxy's aws-lc-sys (and its cmake requirement).
# coop-proxy is reached explicitly via `--workspace` — CI clippy/test, the
# release build, and `cargo deny --workspace` all pass it.
# `fuzz/` is its own detached workspace (cargo-fuzz), kept out of this one.
exclude = ["fuzz"]

The reason for that arrangement is a build dependency. coop-proxy pulls in aws-lc-sys, which needs cmake, and the project does not want every everyday build and the integration scripts to pay for that. So plain `cargo build` builds only the root package, and the proxy is built explicitly with `--workspace`, which is what CI, the release build and `cargo deny --workspace` do.

The fuzzing directory is likewise detached, as its own cargo-fuzz workspace, and excluded from this one.

The dependency list tells you the shape of the code. clap with derive handles the CLI, and clap_complete provides dynamic shell completion. Configuration is TOML through the toml crate, with serde and serde_json for data. There is a YAML parser, serde-saphyr, which suggests configuration or policy files are read in YAML as well as TOML. Tracing and tracing-subscriber with an env-filter give you log control by environment variable. sha2 and hex are there for hashing, url and percent-encoding handle paths and URLs, and thiserror and anyhow cover errors.

The package is version 0.8.1, edition 2024, licensed Apache-2.0, with the matching releases v0.8.1, v0.8.0 and v0.7.1 published in the preceding weeks and the last push on 2026-10-20.

Firecracker on Linux, Lima on macOS, and the requirement difference between them

The platform split is the part most likely to affect your decision, and the documentation is explicit that each backend has its own host requirements.

On Linux the backend is Firecracker, and setup installs it and fetches a guest kernel for you. The repository topics list includes firecracker, kvm, microvm and vm, which matches that picture of a lightweight virtual machine monitor running on KVM.

On macOS the backend is Lima, and it has to be installed before setup will run. The failure mode is stated plainly: setup fails without it.

The tested matrix is macOS arm64 and Linux x86_64. Linux arm64 builds are available but untested. That is a real constraint rather than a footnote, since a Raspberry Pi or an ARM cloud instance falls into the untested column.

There is also a Cargo.lock and rust-toolchain.toml at the root, so the Rust toolchain version is pinned, along with a deny.toml for dependency policy checks, a .taplo.toml for TOML formatting, a .pre-commit-config.yaml, and a fuzz/ directory for the cargo-fuzz targets that the workspace manifest excludes.

What this protects against, and what it does not

The security argument for coop is worth stating precisely, because it is narrower than it first appears.

What it protects against is an agent that modifies or installs things on your host: a package install, a file overwritten outside your project, a Docker daemon left in a broken state. The VM boundary contains that, and because the VM is disposable, a bad state is thrown away rather than repaired.

What it does not change is the agent's behaviour inside the VM, where the agent still has full tool access and still reads whatever the workspace sync exposes. The README's separate pages for the Claude Code, Codex and Grok Build integrations, along with the editor integration and workspace sync pages, are where that arrangement is configured.

The trust model document is the place to check before you point coop at a project with credentials in it, since the question of what the agent can reach outside the VM depends on how workspace sync and the integrations are set up.

One operational note: the guest images are built locally by `coop setup`, which on Linux means downloading Firecracker and a guest kernel. Air-gapped or restricted networks need that step planned for, and the updates mechanism means the VM template itself can change over time, so a rebuilt image is not guaranteed to be identical to last month's.

Editorial conclusion

Adopt coop if you let an agent run shell commands on your machine and want those commands confined to a throwaway VM, particularly on Linux where the Firecracker backend gives a microVM with a real kernel. Skip it if you are on Linux arm64, which is buildable but untested, or if macOS without Lima installed, because setup fails without it. Verify first that your agent integration and the guest image are built for your platform, that the workspace sync rules cover the directories the agent will read, and that the trust model in the repository matches how much you intend to let the agent reach outside the VM.

Frequently asked questions

How do I install coop?

Run `curl -fsSL https://raw.githubusercontent.com/trailofbits/coop/main/install.sh | bash`, or build from source with Rust and CMake using `cargo build --workspace --release` and copying the coop and coop-proxy binaries to /usr/local/bin. With Nix, `nix build` produces both binaries in result/bin.

Which platforms does coop support?

coop is tested on macOS arm64 and Linux x86_64, and Linux arm64 builds are available but untested. On Linux, `coop setup` installs Firecracker and fetches a guest kernel. On macOS you need Lima installed with `brew install lima`, because setup fails without it.

How do I run Claude Code or Codex inside coop?

Change into your project directory, run `coop up` to start the instance, then run `coop claude`, `coop codex` or `coop grok` to launch an agent CLI inside it.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. trailofbits/coop on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/trailofbits-coop.svg)](https://hysenlabs.com/projects/trailofbits-coop)

Was this useful?