A simple sandbox for dangerous tools like coding agents
bulle is an easy-to-use sandbox for running local commands while exposing only the essential parts of your machine. It allows you to run tools you don’t fully trust, without handing over all your files or secrets, and with an option to deny network access. bulle sandboxes are especially helpful when running LLM coding agents or untrusted scripts.
You can spin up an agent with restricted permissions using this simple command:
bulle claude /path/to/project
The profile is always explicit: claude selects the built-in Claude profile and launches its declared default app. The same form works for codex, opencode, and pi; bulle never selects a credential-bearing profile merely because a command has a matching basename.
Sandboxes are not limited to agents. You can use bulle to run any command with custom permissions. See the Quick start section below, Permissions for the grants you write by hand, and the CLI reference for every flag.
This software was written for my personal use. You are free to use it, but the license makes no guarantees.
bulle is still experimental. Please report bugs, comments, and feature requests on GitHub.
Risk mitigation
bulle uses Operating System-level sandboxing to constrain a command’s access to paths and environment variables. Like all sandboxing approaches, this strategy imposes trade-offs between convenience and safety. bulle will not solve all your security problems, but it can mitigate some important risks.
bulle can mitigate risk when- a prompt or skill injection tells an agent to steal passwords or keys stored outside its granted paths (agent profiles typically grant network and credential-directory access, so this protects files you have explicitly withheld);
- an LLM agent or script tries to rewrite
~/Documentsinstead of the project where it should be running; - a malicious package searches your home directory for cloud credentials;
- a crash log exposes your
API_KEYenvironment variable; - a tool surreptitiously runs code from downloads, caches, or another project.
bulle is not sufficient when- the command needs network access but should not send readable code to a specific service;
- the command itself needs secrets or paths you cannot afford to leak;
- you are running code from hostile parties and need a separate machine boundary, not just local OS rules.
For more information on sandboxing tradeoffs, read A field guide to sandboxes for AI by Luis Cardoso.
Install
bulle is only available on MacOS and Linux.
With the install script:
curl -fsSL https://raw.githubusercontent.com/vincentarelbundock/bulle/main/install.sh | sh
With Homebrew:
brew install vincentarelbundock/tap/bulle
Or download a prebuilt darwin/linux, amd64/arm64 archive from the latest GitHub release.
Quick start
By default, bulle runs in the current directory. Access to any other location in the filesystem is denied unless you grant it explicitly, and only a small floor of environment variables (HOME, PATH, locale, terminal) is passed regardless of profile. A command named explicitly after -- always gets its own binary auto-granted, so it can run — but that alone does not open up the rest of the filesystem:
bulle -- cat ~/.gitconfig
cat: /home/user/.gitconfig: Permission denied
bulle: the sandbox denied accesses
bulle: rerun with: --ro '?$HOME/.gitconfig'
bulle: for a one-off, the flags above are enough; to make it permanent, bulle would create a new profile "cat" (~/.config/bulle/profiles/cat.toml):
ro = ["?$HOME/.gitconfig"]
That denial is intentional: reading a file outside the workspace requires permission, even for a command that is otherwise free to run. Add the suggested flag and try again:
bulle --ro ~/.gitconfig -- cat ~/.gitconfig
Instead of granting paths by hand for every tool, we can use profiles: explicitly selected bundles of permissions for common tools. bulle never selects a credential-bearing profile from an executable basename. The commands below each give read-write access to a workspace and launch an agent with the named profile:
bulle claude
# bulle claude /path/to/project
# bulle codex
# bulle pi
# bulle opencode
Profiles can be combined left to right (bulle claude,offline) and composed with one-off grants. See Profiles for the complete model.
Where to go next
- Permissions — filesystem and environment grants, network, policy inspection, and how the sandbox is enforced.
- Profiles — named bundles of permissions, the TOML format, portable path entries, and how to write your own.
- Scratch workspaces — run an agent against a disposable clone and review the diff before it touches your checkout.
- Diagnostics — what to do when the sandbox blocks something, and how to retry with the missing grant.
- CLI reference — the full
bulle --helpoutput.
License and attribution
bulle is distributed under the MIT License. See LICENSES/bulle-MIT.txt.
Thank you to Landrun, an excellent, compact Go implementation of practical Landlock sandboxing. The Linux sandbox backend and filesystem permission model owe a clear debt to Landrun’s design, and portions of the Linux backend and ELF dependency discovery are derived from or inspired by Landrun. See LICENSES/landrun-MIT.txt for the full third-party notice and license.