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
| Feature | VMs | Containers | Safehouse |
|---|---|---|---|
| Isolation Boundary | Guest OS boundary | Process namespace/cgroup | macOS Seatbelt policy |
| Kernel Separation | Yes (separate kernel) | No (shared kernel*) | No (shared kernel) |
| Default Filesystem | Guest filesystem only | Container filesystem | Deny-first host paths |
| Performance Overhead | High | Low to medium | Very low |
| Agent Workflow Compatibility | Lower (requires setup/sync) | Medium | High (native tooling) |
| Best For | Strong adversarial isolation | App packaging & deployment | Day-to-day coding agent use |
*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:Hypervisor Layer
Software like VMware, Parallels, or Apple’s Hypervisor.framework creates isolated guest instances
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:Security 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: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
| Threat | VM | Container | Safehouse |
|---|---|---|---|
| Prompt injection | ✅ Excellent | ✅ Good | ✅ Good |
| Buggy commands | ✅ Excellent | ✅ Good | ✅ Good |
| Confused deputy | ✅ Excellent | ✅ Good | ✅ Good |
| Supply chain compromise | ✅ Excellent | ⚠️ Medium | ⚠️ Medium |
| Sophisticated attacker | ✅ Excellent | ⚠️ Medium | ❌ Limited |
| Network exfiltration | ✅ Good (can air-gap) | ⚠️ Medium (NAT) | ❌ Not protected |
Workflow Compatibility
| Workflow | VM | Container | Safehouse |
|---|---|---|---|
| CLI agents | ⚠️ Requires setup | ✅ Native fit | ✅ Seamless |
| GUI agents | ❌ Awkward | ❌ Not supported | ✅ Seamless |
| Shell integration | ❌ Separate env | ⚠️ Limited | ✅ Native |
| Toolchain usage | ❌ Duplicate install | ⚠️ Must package | ✅ Host tooling |
| Performance | ❌ High overhead | ⚠️ Medium | ✅ Minimal |
| Workspace sync | ❌ Required | ⚠️ Volume mounts | ✅ Not needed |
Administrative Overhead
| Task | VM | Container | Safehouse |
|---|---|---|---|
| Initial setup | ❌ High | ⚠️ Medium | ✅ Low |
| Maintenance | ❌ High | ⚠️ Medium | ✅ Low |
| Updates | ❌ Guest OS + tools | ⚠️ Rebuild images | ✅ Host updates apply |
| Credential management | ❌ Duplicate/mount | ⚠️ Mount secrets | ✅ Selective access |
Layering Models
VM + Safehouse
Result: Strong isolation boundary plus granular in-guest path control.
Container + Safehouse
Result: Reproducible environment plus defense-in-depth filesystem policy.
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