Skip to content

Add secure QEMU support on macOS #388

Description

@rgarcia

Summary

Add production-grade support for Hypeman's existing qemu hypervisor type on Apple Silicon using QEMU's standard ARM virt profile, HVF acceleration, and built-in vmnet-shared,isolated=on networking.

The complete proposed specification is on the pushed documentation branch:

User case

VZ remains the default macOS backend. QEMU is intended for users who need:

  • An explicit, enforceable guest-isolation contract through vmnet's isolated=on option.
  • QEMU behavior that is reproducible across Linux deployment hosts and macOS development hosts.
  • QEMU block-layer disk I/O limits, after macOS validation.
  • Version-pinned, inspectable VMM behavior and richer QMP diagnostics.

Before presenting isolation as a VZ differentiator, run the same two-guest peer-connectivity matrix against VZ. Hypeman currently creates VZNATNetworkDeviceAttachment devices without an isolation control, but we have not archived their observed peer behavior.

Decided architecture

  • Reuse public hypervisor type qemu; do not add qemu-darwin.
  • Reuse StandardProfile; macOS is an internal host-runtime dimension.
  • Apple Silicon and native ARM64 guests only.
  • QEMU ARM virt machine with HVF; no TCG or macOS microvm.
  • Mandatory vmnet-shared,isolated=on with direct host-routable guest IPs and outbound NAT/DNS.
  • No SLIRP, traffic tunnels, socket_vmnet, vmnet-helper, shared non-isolated networking, or permanent-root QEMU.
  • Root bootstrap through a narrow signed LaunchDaemon, followed by mandatory -run-with user=<service UID>:<service GID>.
  • Root-owned, signed, versioned QEMU/dylib and kernel/initrd bundles; never privileged Homebrew QEMU.
  • Virtio-serial guest-agent control transport because QEMU's current AF_VSOCK dialer is Linux-only.

Relationship to #376

#376 established QEMU profiles as private policy over the shared process, QMP, snapshot, and fork implementation:

qemu         -> StandardProfile -> q35/virt
qemu-microvm -> MicroVMProfile  -> microvm

This work should add a second internal composition axis instead of forking the backend:

StandardProfile + Linux  -> KVM, TAP, vhost-vsock, direct exec
MicroVMProfile  + Linux  -> KVM, TAP, vhost-vsock, direct exec
StandardProfile + Darwin -> HVF, isolated vmnet, virtio-serial, launcher

Darwin capabilities and ValidateConfig constraints must be composed with the QEMU profile. Darwin must not register qemu-microvm as available.

MVP scope

  1. Refactor shared QEMU into profile plus platform runtime without changing Linux behavior.
  2. Add platform-composed capabilities and transport-neutral guest-agent dialing.
  3. Add the sealed privileged launcher/supervisor and boot a network-disabled Darwin QEMU guest.
  4. Add HVF, isolated vmnet, DHCP discovery/cross-checking, direct ingress, and lifecycle reconciliation.
  5. Add virtio-serial guest control, signing/notarization, diagnostics, concurrency testing, upgrades, and rollback.

Snapshots, standby, warm forks, GPU passthrough, network shaping, memory hotplug, and unvalidated balloon/disk-throttling features remain disabled initially.

Existing feasibility result

A manual macOS 26.5.2/arm64 experiment with QEMU 10.1.3 validated two simultaneous guests using vmnet-shared,isolated=on and -run-with user=501:20:

  • Distinct host-addressable guest IPs.
  • Outbound TCP and DNS from both guests.
  • Bidirectional ARP, ICMP, TCP, and UDP peer isolation.
  • Real/effective/saved QEMU UID/GID permanently dropped to the invoking user.

This must be reproduced by a checked-in harness on dedicated Apple Silicon hardware and retained as durable CI evidence before release.

Release gates

  • Host reaches both guests over ICMP, TCP, and UDP.
  • Both guests have outbound TCP and DNS.
  • Guest-to-guest ARP/ICMP/TCP/UDP are blocked bidirectionally while host controls remain healthy.
  • QEMU real/effective/saved UID/GID equal the configured service identity and root cannot be regained.
  • Launcher rejects arbitrary arguments, paths, environments, identities, network modes, and mutable runtime artifacts.
  • VZ and QEMU network domains coexist without IP/subnet confusion.
  • API and LaunchDaemon restart reconciliation, process reaping, signed install, upgrade, rollback, and cleanup all pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions