VM Isolation
VM Isolation
When you pass --vm, mentu runs tool calls inside a sandboxed macOS virtual machine. The agent stays on the host. Orchestration never crosses the VM boundary.
Why VMs
Long-running sequences call external tools, spawn shell commands, and reach network services. In normal mode, all of that happens directly on your machine. VM mode puts a boundary around it.
Three things change when VM mode is active:
- Filesystem. The guest VM starts with a minimal Linux root. Your project files are shared in through controlled mount points (read-only or read-write). The agent can only see what you expose.
- Network. The guest can run with no network, NAT, or a restricted outbound policy. Domain allowlists and denylists control what the agent can reach.
- Process. Everything the agent executes runs inside the VM. If a process goes off-script, the blast radius stays inside the guest. The host can stop the entire VM at any time.
Two backends
mentu supports two VM backends. You can switch between them at any time.
| Backend | Based on | Best for |
|---|---|---|
| vz | Apple Virtualization.framework | Save/restore snapshots, pause/resume, Rosetta x86 translation |
| krun | libkrun | Fast startup, small footprint, short-lived tasks |
mentu-runtime engine switch vz
mentu-runtime engine switch krunSandbox profiles
A sandbox profile is a JSON file that declares the full execution environment: command, arguments, environment variables, mount points, network mode, and port bindings.
{
"command": "/usr/local/bin/claude",
"args": ["--model", "claude-sonnet-4-6"],
"env": { "CLAUDE_CODE_FORCE_SANDBOX": "true" },
"mounts": [
{ "source": "/project", "destination": "/work", "readOnly": false }
],
"networkMode": "nat",
"restartPolicy": "on-failure"
}Template snapshots
A template is a saved VM state. Instead of booting from scratch, mentu restores a pre-configured snapshot in under a second. Templates are keyed by configuration hash, so the same recipe config always hits the same snapshot.
Available with the vz backend only.
Using VM isolation
Three ways to enable it:
CLI flag (highest priority):
mentu sequence my-recipe --vmRecipe-level (applies to all steps):
{
"name": "my-recipe",
"vm": true
}Step-level (per-step override):
{
"steps": [
{ "name": "trusted-step", "vm": false },
{ "name": "untrusted-step", "vm": true }
]
}Resolution order: CLI flag, then step-level, then recipe-level, then false.
Composition with transfer modes
VM isolation and transfer modes are independent axes. You can combine them:
mentu sequence my-recipe --vm --transfer worktreeThis creates a git worktree for file isolation and runs execution inside a VM for process isolation.
See also
- Transfer Modes & VM for filesystem isolation options
- Interceptor for capturing network activity during VM runs
- Runtime CLI for daemon and VM management commands