Isolation Models: VMs vs Containers vs Safehouse
Safehouse is not a VM replacement. It’s a low-friction host-level containment layer optimized for local agent workflows on macOS. Understanding the differences helps you choose the right tool for your threat model.Quick Comparison
*Containers on macOS often run inside a lightweight VM (Docker Desktop, Lima, etc.), adding VM-level isolation.
Virtual Machines
How They Work
VMs run a complete guest operating system on a hypervisor:1
Hypervisor Layer
Software like VMware, Parallels, or Apple’s Hypervisor.framework creates isolated guest instances
2
Separate Kernel
Each VM runs its own kernel, completely isolated from the host
3
Guest Filesystem
VM disk is a file on the host; guest sees it as a complete filesystem
4
Explicit Host Mounts
Host directories must be explicitly shared and mounted
Security Properties
✅ Strongest Isolation
Separate kernel means bugs in the guest cannot directly affect the host
✅ Escape Resistance
VM escapes exist but are rare and typically patched quickly
✅ Network Isolation Options
Can fully disconnect guest from network or use NAT/bridge configurations
✅ Snapshotting
Easy rollback to known-good states after risky operations
Practical Tradeoffs
Workflow Friction:- Duplicate toolchains: Must install Node, Python, Go, etc. inside the guest
- Workspace syncing: Need strategy for keeping host/guest files in sync
- Credential management: SSH keys, git config, API tokens must be managed separately
- GUI limitations: Running GUI agents (Cursor, Claude.app) in a VM is awkward
- Copy/paste friction: Clipboard integration varies by hypervisor
When to Use VMs
Adversarial Scenarios
Testing untrusted code, analyzing malware, or defending against sophisticated attackers
Air-Gapped Environments
Work that must be completely network-isolated
Regulatory Compliance
Environments where VM boundaries are required by policy
Containers
How They Work
Containers use OS-level virtualization (namespaces, cgroups) to isolate processes:1
Shared Kernel
All containers share the host kernel (unlike VMs)
2
Namespace Isolation
Process, network, filesystem, and user namespaces provide separation
3
Container Filesystem
Layered filesystem (overlayfs) provides isolated view of files
4
Explicit Bind Mounts
Host directories must be explicitly mounted with
-v or --mountSecurity Properties
✅ Process Isolation
Container processes cannot see or signal host processes
✅ Filesystem Isolation
Container sees only its own filesystem unless bind mounts are added
⚠️ Shared Kernel
Kernel exploits can potentially escape the container
⚠️ Privileged Containers
Easy to accidentally weaken isolation with
--privileged or excessive capabilitiesPractical Tradeoffs
Better for Apps Than Agents:- Containers excel at packaging server applications with dependencies
- Desktop-hosted agents (Cursor, Claude.app) don’t fit the container model well
- CLI agents in containers work but lose native shell integration
- Toolchain packaging: Can bundle exact versions, good for reproducibility
- Volume mounting: Easy to mount host workdir read-only or read/write
- Credential mounting: Can mount SSH keys, cloud configs as volumes (security risk)
- Network: Usually NAT’d by default, can be isolated if needed
- macOS specifics: Docker Desktop runs containers inside a lightweight Linux VM
When to Use Containers
Reproducible Environments
Ensuring the agent uses exact toolchain versions across machines
CLI-Only Agents
Non-GUI agents (Aider, Goose) running on servers or in CI
Dependency Isolation
Preventing agent dependencies from conflicting with host packages
Safehouse (sandbox-exec)
How It Works
Safehouse uses macOS’s built-in Seatbelt/sandbox-exec mechanism:1
Policy Composition
Assembles a Sandbox Profile Language (.sb) policy from modular components
2
Sandbox-Exec Invocation
Launches your command under
sandbox-exec -f policy.sb -- command3
Kernel Enforcement
macOS kernel enforces the policy for the process and all its children
4
Filesystem Interposition
Every file operation is checked against the policy; unauthorized attempts are denied
Security Properties
✅ Filesystem Containment
Fine-grained control over which paths are readable/writable
✅ Process Restrictions
Can limit process signaling, debugging, and IPC (configurable)
⚠️ Shared Kernel
Same kernel as host; not a VM boundary
⚠️ Escape Potential
Sandbox escapes have occurred in the past; not proof against sophisticated attackers
Practical Tradeoffs
Optimized for Usability:- Native tooling: Uses your host’s Node, Python, Go installations directly
- No duplication: No need for separate tool installs inside a container/VM
- Zero syncing: Works directly on host filesystem (with restrictions)
- GUI support: Works perfectly with desktop agents like Cursor and Claude.app
- Minimal overhead: Near-zero performance impact
- Same shell environment (with sanitization)
- Same git config and SSH setup
- Same editor/IDE
- Same package manager caches
When to Use Safehouse
Daily Coding Workflows
Regular use of agents on your local machine
GUI Agents
Cursor, Claude.app, VS Code with Copilot, etc.
Low-Friction Security
Want protection without workflow disruption
Blast Radius Reduction
Limit damage from mistakes, not defending against nation-states
Detailed Comparison
Threat Model Match
Workflow Compatibility
Administrative Overhead
Layering Models
VM + Safehouse
1
VM Isolation
Run your coding workflow inside a VM (UTM, Parallels, VMware)
2
Safehouse Inside VM
Install Safehouse in the VM guest and wrap your agent commands
3
Defense in Depth
- VM boundary protects host from guest escapes
- Safehouse restricts agent filesystem access inside guest
- Network isolation can be added at VM level
Container + Safehouse
1
Container Base
Package your agent environment as a container
2
Safehouse Layer
Install Safehouse in the container and set it as the entrypoint wrapper
3
Combined Protection
- Container provides process/network isolation
- Safehouse restricts filesystem within container
Choosing the Right Model
Use Safehouse alone when:
Use Safehouse alone when:
- You’re doing daily coding with agents on your local machine
- You want protection without workflow disruption
- You use GUI agents (Cursor, Claude.app, etc.)
- Threat model is mistakes and simple attacks, not sophisticated adversaries
- You need minimal overhead and native tooling
Use Containers when:
Use Containers when:
- You’re running CLI-only agents in server environments
- You need reproducible toolchain versions
- You’re packaging agents for deployment or CI/CD
- You can tolerate the overhead of volume mounts and networking config
Use VMs when:
Use VMs when:
- You’re testing untrusted code or analyzing malware
- Your threat model includes sophisticated attackers or sandbox escapes
- Regulatory/compliance requirements mandate VM boundaries
- You need true air-gapped environments
- Workflow friction and resource overhead are acceptable
Layer VMs + Safehouse when:
Layer VMs + Safehouse when:
- You want the strongest practical protection
- You can tolerate VM overhead
- You still want fine-grained filesystem control inside the guest
- Defense-in-depth is a priority
Summary
VMs
Strongest isolationBest for adversarial scenarios, but highest friction and overhead
Containers
App packagingGreat for servers and CLI tools, awkward for desktop agents
Safehouse
Practical hardeningNative workflows with meaningful blast-radius reduction
There’s no single “best” model. Choose based on your specific threat model, workflow needs, and tolerance for friction.
Next Steps
Default Assumptions
Learn what Safehouse allows and denies by default
Getting Started
Install Safehouse and run your first sandboxed agent