Day 68 — Secure Boot & TPM path

Updated

July 30, 2026

Day 68 — Secure Boot & TPM path

Stage VI · ~4h (hardware-dependent)
Goal: Document and, if hardware allows, implement a Lanzaboote Secure Boot path and/or TPM-backed LUKS unlock—or produce a lab-limits dossier that is honest about what you cannot do on VMs.

Important

Copy-paste without the upstream guide bricks boots. Treat this day as process + documentation first; enable on a disposable machine second. Recovery USB and recovery keys before enrollment.

Why this day exists

Fleet images and metal boxes increasingly expect Secure Boot and disk encryption that does not beg for a passphrase at every reboot in a datacenter. NixOS’s community answer for SB is primarily Lanzaboote (uki/systemd-boot + signed generations). TPM2 unlock pairs with LUKS (Day 57 Disko often declares the encrypted volumes).

Capstone B (stretch) lists SB/TPM; Capstone A does not require full enablement—but Stage VI experts must know the path and the failure modes.


Theory 1 — Problem statement

Threat Control
Evil maid bootloader swap Secure Boot + enrolled keys
Disk theft LUKS (or vendor disk encryption—know the difference)
Passphrase at scale TPM2 PCR-bound unlock (with enrollment process)
Unsigned kernel modules policies SB + your key hierarchy
Silent rollback to unsigned attacker kernel Sign each generation you boot

NixOS’s generation model must sign new boots—not only ship a distro shim forever. That is why Lanzaboote exists relative to “turn on SB and hope.”


Theory 2 — Lanzaboote overview (2026)

Lanzaboote integrates Secure Boot with NixOS (systemd-boot oriented flows).

Typical story (always verify against current README for your pin):

  1. Enable Secure Boot in firmware (setup mode / enroll keys carefully)
  2. Generate or enroll machine keys (PK/KEK/db as relevant to the guide)
  3. Import Lanzaboote NixOS modules so boots are signed
  4. Keep recovery path (USB installer + known recovery keys)
  5. Re-test boot after each major change before trusting prod
# Conceptual only — follow current Lanzaboote README for 26.05-compatible paths
{
  imports = [ lanzaboote.nixosModules.lanzaboote ];
  boot.loader.systemd-boot.enable = lib.mkForce false; # lanzaboote replaces aspects
  boot.lanzaboote = {
    enable = true;
    pkiBundle = "/etc/secureboot"; # path patterns per docs
  };
}

Flake input sketch:

# inputs.lanzaboote.url = "github:nix-community/lanzaboote/…";
# inputs.lanzaboote.inputs.nixpkgs.follows = "nixpkgs";
Warning

Firmware Setup Mode, key enrollment, and Microsoft/3rd-party key politics vary by vendor. Laptop OEM SB is not the same as a server you control end-to-end.


Theory 3 — TPM2 + LUKS

Goals:

  • Unlock root (or data) volume without typing a passphrase every boot
  • Still retain a recovery passphrase or recovery key file offline
  • Survive policy: which PCRs bind the sealed key
# Sketch — systemd-cryptenroll / auto-unlock patterns evolve
{
  boot.initrd.systemd.enable = true; # often required for modern enroll flows
  # boot.initrd.luks.devices."crypted".crypttabExtraOpts = [ "tpm2-device=auto" ];
  # Exact options: verify on your nixpkgs 26.05 pin and systemd version
}

Manual enrollment often looks like:

# list TPM
systemd-cryptenroll --tpm2-device=list
ls /sys/class/tpm

# enroll (EXAMPLE — adjust device + PCR set per threat model)
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/nvme0n1p2

PCR trade-offs

Choice Security Fragility
Fewer PCRs Weaker binding Survives more firmware changes
PCR 7 (Secure Boot state) common Ties to SB Firmware/SB policy changes may require re-enroll
Many PCRs Stronger Breaks after BIOS updates more often

Document which PCRs and the re-enroll procedure after BIOS updates. Never TPM-only without recovery credentials.


Theory 4 — VM lab limits

Environment Secure Boot TPM
Bare metal modern laptop Often yes Often yes
Cloud VM Sometimes virtual SB/TPM Vendor-specific
libvirt QEMU Emulated possible swtpm possible
Nested cheap VPS Often no Often no

QEMU/swtpm note (advanced lab)

You can practice pieces with OVMF Secure Boot and swtpm—but it is a project of its own. Stage VI accepts a document-only track if hardware refuses you. Do not fake “SB enabled” in notes without evidence.


Theory 5 — Recovery & break-glass

Asset Storage
Disk recovery key / passphrase Password manager / sealed paper / offline encrypted store
SB setup mode knowledge Runbook steps
Unsigned rescue ISO / installer USB Physical media
Age/sops keys Separate from disk encryption keys
Old generation unsigned Know when SB will reject boot
Failure Friday scenario:
  BIOS update → PCR mismatch → TPM unlock fails
  → boot installer USB
  → unlock with recovery key
  → re-enroll TPM
  → document time-to-recover

Never enroll TPM-only without a recovery passphrase backup you have tested.


Theory 6 — Relation to Disko, deploy, and images

Concern Link
LUKS layout Day 57 Disko declares partitions; TPM enroll often post-install
Impermanence Day 58: encrypted root + persist datasets
Images Day 62 generators may not equal metal SB story
Deploy Remote deploy does not replace firmware SB enrollment
Capstone B Fleet policy: which classes require SB

Write one paragraph: which host classes require SB vs best-effort.


Worked example — dossier template

# SECUREBOOT-TPM.md

## Hardware
- Machine:
- Firmware vendor/version:
- Firmware SB state: SetupMode / User / Disabled / Unknown
- TPM: 2.0 visible? (commands + output summary)
- Lab type: metal / libvirt / cloud

## Goals
- [ ] Secure Boot with Lanzaboote
- [ ] LUKS passphrase only
- [ ] LUKS + TPM2
- [ ] Document-only (limits)

## Upstream sources
- Lanzaboote README URL + commit/date consulted:
- NixOS wiki / manual notes:

## Steps performed
1. 
2. 

## Recovery
- Recovery key location (not the key itself):
- USB installer location:
- Re-enroll after BIOS update:
- Estimated RTO if TPM fails:

## Residual risks
- 

## Fleet policy
- Host classes requiring SB:
- Best-effort only:

Lab — multi-step

Suggested notes: ~/lab/90daysofx/02-nixos/day68

Step 1 — Probe hardware

mkdir -p ~/lab/90daysofx/02-nixos/day68
bootctl status 2>/dev/null | tee ~/lab/90daysofx/02-nixos/day68/bootctl.txt || true
efi-readvar 2>/dev/null | tee ~/lab/90daysofx/02-nixos/day68/efi-vars.txt || true
ls -la /sys/class/tpm 2>&1 | tee ~/lab/90daysofx/02-nixos/day68/tpm-sysfs.txt
systemd-cryptenroll --tpm2-device=list 2>&1 | tee ~/lab/90daysofx/02-nixos/day68/tpm-list.txt || true

Step 2 — Choose track

Track Criteria
A Metal + SB available → Lanzaboote guided enable on disposable
B TPM + LUKS available → enroll with recovery key tested
C VM only → emulate with swtpm or document-only dossier

Write the track choice first; do not improvise on your daily driver.

Step 3 — Read upstream (required even for Track C)

Open current Lanzaboote README + Secure Boot notes relevant to your generation. Save URLs in the dossier. Take notes—do not invent key enrollment sequences from memory.

Step 4 — Recovery assets first

Before any enrollment:

  1. Confirm installer USB or rescue media boots
  2. Confirm LUKS recovery key unlocks (lab disk)
  3. Write locations in dossier

Step 5 — Implement or simulate

If A/B: snapshot/backup first; proceed carefully; capture commands and outcomes.
If C: write why cloud images still matter (signed provenance vs local SB) and what you would do on metal.

Step 6 — Failure plan drill (written)

Write the exact steps to boot installer and decrypt disk if TPM fails after firmware update. Include who holds recovery keys.

Step 8 — Fleet policy paragraph

Which host classes require SB? Which are best-effort? Capstone A vs B expectations.

Step 9 — Tabletop: evil maid + firmware update

Write answers in the dossier (no need to re-brick hardware):

  1. Attacker replaces bootloader on stolen laptop with SB off historically—what changes with Lanzaboote enrolled?
  2. After OEM BIOS update, TPM unlock fails at initrd—ordered recovery steps?
  3. How do age/sops keys relate to disk recovery keys (separate custody)?
  4. Can deploy-rs fix a machine that will not boot? (Usually no—firmware/recovery path first.)

Step 10 — Capstone A vs B honesty line

One sentence each:

  • Capstone A: SB/TPM not required—document limits OK.
  • Capstone B: which pieces become mandatory for your stretch goals?

Worked example — recovery USB checklist

## Recovery USB
- [ ] Boots on target hardware (tested date: …)
- [ ] Contains or can fetch flake tools / nix installer as needed
- [ ] Operator knows LUKS recovery unlock command
- [ ] Network plan if flake must be cloned (ethernet? Wi-Fi firmware?)
- [ ] Time estimate from power-on to decrypted root shell: …

If you never tested the USB on this machine, Track A/B is incomplete even if enrollment “worked once.”


Common gotchas

Symptom / mistake What to do
Bricked boot Installer USB; setup mode; recover keys
PCR mismatch after update Re-enroll; reconsider PCR set
Lost recovery key Undecryptable disk; prevention only
Enabled SB without signing new gens Use Lanzaboote properly
Assumed cloud disk encryption = LUKS Understand vendor encryption separately
Experiment on only laptop Use disposable or accept data-loss risk consciously
Docs lag code Date-stamp upstream guide you followed

Checkpoint

  • Hardware probed with saved outputs
  • Track A/B/C completed with artifacts
  • SECUREBOOT-TPM.md filled
  • Recovery path written and assets exist
  • No production host left without recovery keys
  • Upstream sources recorded
  • Tabletop answers written
  • Recovery USB checklist honest
  • Three personal gotchas

Commit

git add .
git commit -m "day68: secure boot / TPM path dossier"

Write three personal gotchas before continuing.

Tomorrow

Day 69 — Backup story: Borg/Restic/ZFS—pick one; restore drill of state.