How Lume works
Offline unattended setup, SIP through paired Recovery, macOS disk growth with rollback, and what Lume telemetry collects.
This page explains what Lume does behind a few commands, and what its telemetry collects.
Unattended setup#
lume create --unattended tahoe (or sequoia) never clicks through Setup
Assistant. Lume:
- installs macOS from the IPSW into a new disk;
- boots once so macOS writes its first-boot state, then stops;
- mounts the Data volume on the host and writes the
lumeaccount, SSH, autologin and no-sleep settings as plain files; - boots again and finishes only when SSH answers.
Writing files avoids depending on display timing or a release's Setup Assistant layout. Tahoe is the verified preset; Sequoia can still show an Accessibility step on first display boot (#2155).
SIP#
On Apple silicon, SIP lives in a LocalPolicy signed by the Secure Enclave
(Virtualization.framework provides it for VMs). It belongs to a paired state:
disk.img (macOS, personalized boot files, Recovery), nvram.bin (security and
anti-replay state) and the VM configuration. Editing files cannot sign a
policy, so lume sip uses three boots:
- normal: check the admin account over SSH;
- Recovery: run
csrutil enable|disablein Terminal over a temporary VNC session, reading the prompt and result with OCR (Lume stops the run if Tahoe Recovery does not halt); - normal:
csrutil statusover SSH.
Only the canonical System Integrity Protection status: enabled. or
disabled. is accepted; a customized policy is rejected. lume clone copies
disk and NVRAM together, which is why cloning a prepared seed works and copying
one file does not.
Disk growth#
A macOS disk is laid out as ISC, main APFS, then RecoveryOS. Growing the image appends space after RecoveryOS, where APFS cannot reach it:
[ ISC ][ main APFS ][ RecoveryOS ][ free ] -> [ ISC ][ expanded main APFS ][ RecoveryOS ]lume set --disk-size on a stopped VM copies RecoveryOS to the new end with
its type, id, attributes and contents intact, rewrites both GPT copies, and
grows APFS with diskutil. It is a transaction: a copy-on-write backup first,
a marker that blocks run, clone and push meanwhile, verification of the moved
bytes and the new capacity, and restore on failure (also on the next attempt
after a crash). Unfamiliar layouts and FileVault guests are refused. Linux
images have no RecoveryOS: Lume grows the image and the guest grows its
filesystem.
Telemetry#
Lume sends content-free, pseudonymous events to PostHog EU, on by default, after a first-run notice.
lume config telemetry status
lume config telemetry disable
lume config telemetry enable
lume config telemetry reset-idLUME_TELEMETRY_ENABLED overrides the setting per process. Events carry a
fixed name and bounded fields (Lume version, host OS major version and arch,
CI flag, transport, allowlisted operation, success, error class, duration
bucket), capped at 1,000 per process per hour. They never include VM or image
names, paths, URLs, arguments, MCP payloads, SSH commands or output, VNC
credentials, screenshots or raw errors. GeoIP is disabled.
The update check (lume check-update, lume update) is a separate request to
GitHub Releases, cached for 20 hours, without the telemetry id:
LUME_UPDATE_CHECK=false lume check-update