Rename retained top-level docs to lowercase kebab-case and squash obsolete review/refactor notes into docs/open.md. Remove stale standalone plan documents that are now represented by the current open-issues summary.
1.9 KiB
NBDE materialisation
Legion manages NBDE policy for provider-backed Tribes nodes. The Guix-side boot
mechanism is documented in ../guix-tribes/docs/nbde.md.
Policy source
Cluster-derived NBDE thresholds live in src/main/cluster-derived-policy.ts.
The current policy is:
- fewer than 3 healthy managed NBDE nodes: degraded local unlock
- at least 3 healthy managed NBDE nodes: distributed Tang unlock
- at least 4 healthy managed NBDE nodes: Clevis SSS quorum unlock
Healthy nodes are managed NBDE nodes that are not deleting or errored and whose deployment has completed successfully.
Local boot key
Degraded mode uses /boot/nbde/local-boot.key. Legion generates the key when a
node enters degraded mode, writes it to the node, and adds it as a LUKS keyslot
using the durable recovery secret stored in encrypted Legion state.
The local boot key itself is not stored in Legion state. localBootKeyPresent
tracks intent/state only; the LUKS header decides whether the key actually
unlocks the disk.
When local unlock is removed, Legion removes the LUKS keyslot first. If that
succeeds, it overwrites the key file best-effort, syncs, unlinks it, and removes
the empty /boot/nbde directory.
Materialisation order
Legion reconciles NBDE before ordinary managed-node reconfiguration during
materialisation. NBDE reconciliation updates LUKS keyslots and Clevis bindings
directly; it does not require a Guix system generation rebuild for local key
changes because the initrd contains only the generic /boot/nbde reader.
Transitions are additive before destructive:
- degraded: install local boot key and keyslot, then remove obsolete Clevis bindings
- clustered/quorum: bind the new Clevis policy, remove old Clevis slots, then remove the local boot keyslot and file
Tang peer addresses and SSS quorum settings are stored as Clevis metadata in the LUKS header, not in the initrd.