Skip to content

Secure Boot enrolment for fleets: only Setup Mode + db scales (FOS cannot bootstrap its own trust) #134

Description

@mastacontrola

Rewritten 2026-08-03 after hardware testing. The original framing of this
issue was wrong in a way that mattered, and the correction is the most useful
thing to come out of it. See "What testing changed" below.

The gap

FOG generates a Secure Boot signing key by default and signs the FOS kernels
with it on every install and upgrade (_ensureSecureBootKeys / _resignKernels
/ _publishSecureBootKit). What it has no answer for is getting that
certificate trusted on more than a handful of machines. Both existing routes
need a technician with prepared media at each machine:

  • the USB kit — make a stick, boot a stock Ubuntu/Debian live image, run
    fog-enroll-mok.sh, compare a fingerprint, reboot, answer MokManager
  • PXE menu item 14 (_enrollSecureBootChoice) — chains MokManager directly,
    still needs MOK.der on local FAT media because MokManager has no network
    stack

The governing constraint

Whatever performs the enrolment must already be trusted by the firmware.
Every workable design is a different answer to "trusted by what?" Two
independent walls enforce this.

Wall 1 — MOK enrolment always requires a human.mokutil --import writes
MokNew, which is runtime-accessible. MokList — the store shim actually
consults — is boot-services-only, so the running OS physically cannot write
it. Only MokManager, in boot services, can promote one to the other, and it
demands a one-time password as proof of physical presence. That is shim's entire
security model; there is no bypass and there should not be one.

Wall 2 — FOS cannot bootstrap its own trust.This is what testing
established, and it invalidated the original plan.
On real firmware with Secure
Boot enforcing and MokList empty:

NBP filename is secureboot/snponly-shimx64.efi <- MS-signed, accepted
Fetching Netboot Image secureboot/snponly.efi <- iPXE-signed, accepted
iPXE 2.0.0 ... boot.php... ok
bzImage... ok
Verification failed: Security Policy Violation
init.xz... ok
Verification failed: Security Policy Violation
Could not boot: Error 0x7f04819a

iPXE verifies the kernel and the initrd through shim. The signed chain
loads fine until FOG's own artefacts are checked against a MokList that does not
yet contain FOG's certificate, and both are refused.

So a FOG task running inside FOS can never be what establishes trust in FOG's
key. The task that would enrol the key cannot run on the machine that needs
it.

What testing changed

The original version of this issue proposed a task type as the fleet answer:
"Path B — staged MOK", pitched as replacing the USB-stick visit with a scheduled
task. That was built on the assumption FOS could boot on an enforcing machine.

It cannot. And notably 26 unit-test cases passed against that assumption and
still would
— no harness can observe firmware policy. It took a real boot.

The task type still has a real, narrower use (below), but it is not the fleet
story, and the issue is rewritten so nobody builds on the old framing.

The three paths that survive, ranked

1. Setup Mode + db — the fleet answer.db/KEK/PK write policy follows
the presence of a PK, not the enforcement bit. In Setup Mode (PK absent)
nothing is enforcing, so FOS loads normally and can write FOG's certificate
straight into db — a plain efivarfs write, no signing tooling on the client.
No MokManager, no password, no media. Cost: one firmware visit to clear the
platform keys, which can be the same trip that enables Secure Boot. One BIOS
screen, once per machine, ever.

Secure Boot merely being switched off does NOT make db writable. A
machine in User Mode with enforcement disabled still has a PK. Only Setup Mode
helps. sbState() keeps setup and disabled as distinct answers for exactly
this reason.

2. Out-of-band (Redfish / vendor BMC) — the only zero-touch tier.
/redfish/v1/Systems/{id}/SecureBoot and its SecureBootDatabases collection
write db with the client powered off. No boot, no OS, no physical presence.
Dell cctk is the desktop equivalent. This is the only genuinely end-to-end
automated path and should be documented as a first-class tier, not a follow-on.

3. Borrowed trust (MS-signed live Linux) — the existing USB kit. Ubuntu live
boots under enforcing Secure Boot because Microsoft signed its shim. Still ends
at MokManager. Remains the answer for a machine that cannot be put into Setup
Mode — so it becomes more important, not less.

Where the staged-MOK task actually fits

Machines that currently have Secure Boot off and are going to have it turned
on.
Common in practice — many sites disable Secure Boot precisely to use FOG
and want it back on afterwards. There, the task stages the key with no USB stick,
no live image and no fingerprint transcription, and the tech confirms once. A
genuine improvement on the USB kit for that case, and nothing more.

No in-code guard is needed for the enforcing case: the failure happens in iPXE,
before FOS exists. The task description states both limits so nobody schedules it
against 200 enforcing machines and watches them all fail to boot.

db baseline: ship Microsoft's certificates

Decided, implemented in Phase 2. KEK CA 2011, Windows Production PCA 2011, UEFI
CA 2011, plus the 2023 generation.

The decisive reason is FOG's own chain, not Windows compatibility. The chain
measured above is shimx64.efi → signed iPXE → FOG-signed kernel, and that shim
is signed by Microsoft Corporation UEFI CA 2011. A db without it breaks
FOG's own Secure Boot PXE boot.

Capturing each machine's factory keyset was rejected as the baseline — no answer
for the first machine of a model, an ordering trap the admin cannot recover from,
and restoring a stale dbx re-trusts revoked bootloaders. Kept as optional
enrichment for OEM-specific db entries (Dell SupportAssist, HP Sure Recover,
Lenovo diagnostics). dbx will not be baked into the shipped bundle.

Status

Phase 1 — done, validated end to end 2026-08-03.

  • fstab mounted efivarfs as type efivars, which is not a mountable
    filesystem type (it was the old CONFIG_EFI_VARS sysfs interface). The
    entry silently failed under mount -a, so FOS has never had EFI variable
    access at all
    . Fixed.
  • BR2_PACKAGE_MOKUTIL=y (+ KEYUTILS) on all three arches — mokutil is a
    stock Buildroot package.
  • secureboot-funcs.sh, bin/fog.enrollsb, mode=enrollsb dispatch.
  • taskTypes row 25, schema step 322.
  • tests/checks/secureboot.sh — 26 cases, mutation-checked.
  • Hardware validation: boot.php emits mode=enrollsb; FOS dispatches it;
    MokNew/MokAuth land in NVRAM with FOG's exact 810-byte DER at offset 44
    of 854; task reports Complete; shim shows "Shim UEFI key management" on the
    next boot.

Phase 2 — the actual fleet path, not started.

  • fog-build-sb-authvars server helper (root-only, fog-sign-kernel sudo
    pattern).
  • MS baseline keyset; db/KEK/PK write from FOS in Setup Mode.
  • Refusal logic; Secure Boot page UI showing enrolment state.

Phase 3 — zero-touch and enrichment.

  • Redfish / cctk for the firmware half.
  • Capture-as-enrichment for OEM db entries.

Open

  • Hardware validation of the db write. Not reversible from the OS —
    a mistake needs a firmware trip to recover, per model.
  • 32-bit UEFI. No signed 32-bit shim exists, so the MOK path is moot on
    x86; the db path would still work. Decide refuse vs degrade.
  • _keaSecureBootClassCommented() in fogproject says no signed snponly
    equivalent exists and that is why the DHCP Secure Boot class ships
    commented out. The fog-ipxe MANIFEST shows secureboot/snponly.efiis
    signed as of iPXE v2.0.0 (iPXE Secure Boot Automatic Code Signing G1A).
    That reasoning looks out of date and is worth revisiting separately.

Related

  • fos ADR-0009 — docs/adr/0009-secure-boot-enrolment-paths.md
  • fogproject ADR-0008 — task type scope and the db baseline decision

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions