macOS (Virtualization.framework)
Capsa's macOS backend uses Apple's Virtualization.framework, available on macOS 11 (Big Sur) and later.
Requirements
System
- macOS 11.0 (Big Sur) or later
- Apple Silicon (M1/M2/M3) or Intel Mac with Hypervisor.framework support
Code Signing
Virtualization.framework requires your application to be signed with the com.apple.security.virtualization entitlement.
For distribution, add this entitlement to your app:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.virtualization</key>
<true/>
</dict>
</plist>Development
For development, see the Development Guide which covers how to use the codesign-run tool for automatic signing during development.
Cargo Configuration
[dependencies]
capsa = { version = "0.1" }
tokio = { version = "1", features = ["full"] }Supported Features
| Feature | Status | Notes |
|---|---|---|
| Linux Direct Boot | Supported | kernel + initrd |
| UEFI Boot | Supported | Via EFI firmware |
| virtio-fs Shares | Supported | DynamicCaller ownership only |
| NAT Networking | Supported | Platform-native NAT |
| UserNat Networking | Supported | Userspace NAT with policies |
| Cluster Networking | Supported | Multi-VM communication |
| VM Sockets (vsock) | Supported | Host-guest communication |
| VM Pools | Supported | Pre-warmed VMs |
| Sandbox Mode | Supported | With guest agent |
Shared Directory Ownership
macOS only supports DynamicCaller ownership mapping for shared directories. Files appear owned by whoever is accessing them. Passthrough and Squash ownership modes are silently converted to DynamicCaller with a warning.
Boot Configuration
Linux Direct Boot
let boot = LinuxDirectBoot::new("kernel", "initrd");
let vm = capsa::vm(boot)
.cpus(2)
.memory_mb(1024)
.console_enabled()
.build()
.await?;UEFI Boot
macOS supports UEFI boot with disk images:
use capsa::{ DiskImage};
let disk = DiskImage::new("disk.img");
let boot = UefiBoot::new(disk)
.with_efi_variable_store("efi_vars.bin");
let vm = capsa::vm(boot)
.cpus(2)
.memory_mb(2048)
.console_enabled()
.build()
.await?;INFO
UEFI boot is slower than direct boot but supports more operating systems.
Networking
Platform NAT
The simplest option using macOS's built-in NAT:
use capsa::Network;
let vm = capsa::vm(boot)
.network(Network::Nat)?
.build()
.await?;VirtualNetwork (Recommended)
For network policies and port forwarding:
use capsa::{VirtualNetwork, Gateway, NetworkInterface, NetworkPolicy};
let policy = NetworkPolicy::deny_all()
.allow_dns()
.allow_https();
let network = VirtualNetwork::with_gateway(
Gateway::new("10.0.2.0/24").unwrap()
.policy(policy).unwrap()
);
let vm = capsa::vm(boot)
.interface(NetworkInterface::new(&network).forward_tcp(8080, 80))?
.build()
.await?;Troubleshooting
Entitlement Errors
Error: The operation couldn't be completed. (Virtualization error -1)Solution: Your binary needs to be signed with the virtualization entitlement. For development, use the devenv which provides automatic signing.
Slow First Start
First VM launch may be slower as macOS initializes Virtualization.framework. Subsequent launches are faster.
Limitations
- Single vsock Connection: Each vsock port currently supports only one connection
- DynamicCaller Ownership Only: Shared directories always use DynamicCaller ownership mapping
- Linux Guests Only: macOS guests cannot be run via Virtualization.framework directly
Sandbox Mode
The easiest way to use Capsa on macOS:
let vm = capsa::sandbox()
.build()
.await?;
let agent = vm.agent().await?;
let result = agent.exec("uname").arg("-a").run().await?;
println!("Kernel: {}", result.stdout);Raw VM Example
For custom configurations:
use capsa::VirtualNetwork;
let boot = LinuxDirectBoot::new("kernel", "initrd");
let network = VirtualNetwork::new();
let vm = capsa::vm(boot)
.cpus(4)
.memory_mb(2048)
.console_enabled()
.network(&network)?
.vsock_listen(1024)
.build()
.await?;
// Console for boot detection
let console = vm.console().await?;
console.wait_for("# ", Duration::from_secs(30)).await?;
// VM is ready for your workload...
vm.shutdown().await?;Performance
| Metric | Apple Silicon | Intel Mac |
|---|---|---|
| Boot Time | ~2-3 seconds | ~3-5 seconds |
| Memory Overhead | Low | Moderate |
| CPU Overhead | Very Low | Low |
Apple Silicon Macs generally provide better virtualization performance due to hardware optimizations.