swtpm), so
systemd-cryptenroll PCR-7 sealing and the vault unlock run exactly as they
will on NitroTPM or bare metal.
Prerequisites
qemu-system-x86_64,swtpm,packer, OVMF (UEFI firmware).- KVM makes this fast; on macOS it runs under QEMU TCG (works, slow).
1. Build the golden image
ds=nocloud-net), lays down the GPT
ESP / rootA / rootB / /data layout, installs Docker + gVisor (runsc),
Tailscale (off), the preloaded image tarballs, and the firstboot units. Output:
image/output/naive-tower.raw.
2. Boot it
/datasealed to the TPM —systemd-cryptenroll --tpm2-pcrs=7creates a LUKS2 volume bound to the vTPM and prints a one-time owner recovery key (store it). Subsequent boots auto-unlock; no passphrase.- The region comes up —
naive-region.servicerunsdocker compose upwithvaultd(reveal compiled out), the governor, api, gateway, and therunsc-sandboxed agent runtime. - A claim QR + code rendered to the console by the device-agent.
curl http://localhost:3000/health returns 200 once /data is unlocked and the
region is live.
3. Claim it against a local control plane
Run the CP (the API in cloud mode) on your workstation:NAIVE_DEV_KYC_BYPASS=1 on the CP — a
loud, logged, dev-only bypass that is refused in Tower/prod builds (the KYC
leg is otherwise BLOCKED). The device
polls, attests (PCR-7 quote; CP verification is beta), provisions, and comes up
live in sandbox.