docs/sandboxing.md
Mise supports lightweight process sandboxing for mise exec and mise run, inspired by zerobox. Sandboxing restricts filesystem, network, and environment variable access with granular controls. No Docker required, minimal overhead.
::: warning
Sandboxing is an experimental feature. Enable it with mise settings experimental=true.
:::
Any --deny-* or --allow-* flag implicitly enables sandboxing:
# Full lockdown — no writes, no network, no env vars
mise x --deny-all -- node script.js
# Block network only
mise x --deny-net -- npm run build
# Block writes except to ./dist
mise x --allow-write=./dist -- npm run build
# Block everything, allow specific exceptions
mise x --deny-all --allow-read=. --allow-write=./dist --allow-net=registry.npmjs.org -- npm install
| Flag | Description |
|---|---|
--deny-all | Block reads, writes, network, and env vars |
--deny-read | Block filesystem reads (system libs and tool dirs still accessible) |
--deny-write | Block all filesystem writes (except /tmp) |
--deny-net | Block all network access |
--deny-env | Block env var inheritance (only PATH, HOME, USER, SHELL, TERM, LANG pass through) |
--allow-read=<path> | Allow reads from specific path (implies --deny-read for everything else) |
--allow-write=<path> | Allow writes to specific path (implies --deny-write for everything else) |
--allow-net=<host> | Allow network to specific host (implies --deny-net for everything else) |
--allow-env=<var> | Allow specific env var through (implies --deny-env for everything else). Supports wildcards: --allow-env='MYAPP_*' |
These flags work with both mise exec (mise x) and mise run.
Tasks defined in mise.toml can declare sandbox permissions:
[tasks.build]
run = "npm run build"
deny_net = true
allow_write = ["./dist"]
[tasks.lint]
run = "eslint ."
deny_all = true
allow_read = ["."]
[tasks.install]
run = "npm install"
deny_all = true
allow_read = ["."]
allow_write = ["./node_modules"]
allow_net = ["registry.npmjs.org"]
CLI flags on mise run override task-level config:
# Run with task's declared sandbox
mise run build
# Override: also allow network to a specific host
mise run --allow-net=registry.npmjs.org build
When filesystem restrictions are active, certain paths remain accessible so tools can function:
/usr, /lib, /lib64, /bin, /sbin, /etc, /dev, /proc, /sys, /tmp, /nix, /snap, /home/linuxbrew/System, /Library, /usr, /bin, /sbin, /dev, /etc, /var/run, /tmp, /private, /opt/homebrew, /nix~/.local/share/mise/installs/.../tmp (and /private/tmp on macOS)/dev (for /dev/null, /dev/tty, etc.)--allow-write paths are implicitly readable--allow-read paths include system essentials above| Feature | Linux | macOS |
|---|---|---|
| Deny/allow reads | Landlock | Seatbelt |
| Deny/allow writes | Landlock | Seatbelt |
| Deny all network | seccomp | Seatbelt |
Per-host network (--allow-net=<host>) | Not supported (v1) | Seatbelt |
| Env filtering | Built-in | Built-in |
| Docker support | Yes | N/A |
Filesystem sandboxing uses Landlock (available since Linux 5.13). Network sandboxing uses seccomp-bpf to block inet socket creation while allowing Unix sockets.
If Landlock is unavailable or cannot apply filesystem restrictions, the command fails.
Limitation: Per-host network filtering (--allow-net=<host>) is not supported on Linux in v1. On Linux, --allow-net falls back to allowing all network access. This works on macOS via Seatbelt.
Uses Apple's sandbox-exec (Seatbelt) with a generated profile. Supports all features including per-host network filtering.
Sandboxing is not currently supported on Windows. A warning is printed and the command runs unsandboxed.
mise x --deny-write -- bash untrusted-script.sh
mise x --deny-net -- make build
mise x --deny-all --allow-read=./src --allow-write=./dist node@20 -- node build.js
# Only pass through env vars starting with MYAPP_
mise x --allow-env='MYAPP_*' -- node app.js
# Allow multiple patterns
mise x --allow-env='MYAPP_*' --allow-env='NODE_*' -- node app.js
[tasks.test]
run = "npm test"
deny_net = true
deny_write = true
allow_write = ["./coverage", "./node_modules/.cache"]
allow_env = ["NODE_*", "npm_*"]