Skip to content

feat: add enrollsecureboot action - #214

Open
mcanevet wants to merge 1 commit into
tinkerbell:mainfrom
mcanevet:enrollsecureboot
Open

feat: add enrollsecureboot action#214
mcanevet wants to merge 1 commit into
tinkerbell:mainfrom
mcanevet:enrollsecureboot

Conversation

@mcanevet

@mcanevet mcanevet commented Aug 14, 2026

Copy link
Copy Markdown

What does this PR implement/change/remove?

Adds enrollsecureboot, a new Action that enrolls a UEFI Secure Boot trust anchor into db while
the firmware is in Setup Mode - the state a freshly-reset or factory key database is in before any
key has been enrolled. It's meant to run during provisioning, after an OS has been written to disk
but before the machine reboots into it, so a later boot can enforce Secure Boot against a db that
actually trusts the installed OS.

PK and KEK are populated with a throwaway, freshly generated self-signed keypair: nothing
re-signs db/KEK afterwards, so there's no PK/KEK material worth persisting, and Setup Mode
accepts any well-formed signed variable update regardless of whether the signing key is already
trusted. The required input is DB_CERT_URL; two opt-in flags additionally broaden db beyond
just that certificate (both default false - narrowest trust set, matching Talos's own
IncludeWellKnownCertificates default):

  • PRESERVE_VENDOR_CERTIFICATES keeps whatever's already in db instead of discarding it. If a
    ResetAllKeysToDefault BMC action ran before this Action (as ours does), that's the vendor's
    factory-default set - untouched by a subsequent DeletePK, which only removes PK to enter
    Setup Mode - so it's still sitting in db right up until this Action's own write would otherwise
    replace it wholesale. Without this flag, enrollment silently drops trust for anything signed
    against those vendor/Microsoft CAs (e.g. third-party Option ROM drivers for RAID/HBA
    controllers).
  • INCLUDE_WELL_KNOWN_CERTIFICATES additionally enrolls a small, fixed, vendored bundle of
    Microsoft's UEFI CA certificates (the same three Talos's own secureboot database generator
    embeds), regardless of what's currently in db. Deterministic/reproducible across machines,
    unlike PRESERVE_VENDOR_CERTIFICATES, but generic - it won't include vendor-specific certs.

Both are opt-in rather than default-on because broadening trust is a real security tradeoff (an
attacker doesn't need to break your own signing if a still-validly-signed but vulnerable bootloader
chains up through a CA left in db) that should be a deliberate per-deployment choice.

Built on github.com/foxboron/go-uefi rather than shelling
out to efitools/openssl, so the image stays a static scratch-based binary like the rest of this
repo's Actions - no apk add needed at runtime. go-uefi also ships an in-memory efivarfs test
double, so the enrollment logic (Setup Mode gating, signature-list construction, PKCS7 signing) has
real unit test coverage without needing physical UEFI firmware.

Motivation

We use this in a Tinkerbell Workflow's Template, right after streaming a Talos image to disk, to
trust Sidero's Image Factory signing cert
before the machine's next boot enforces Secure Boot. We considered relying on sd-boot's own
boot-time "Enroll Secure Boot keys" mechanism instead, but that enrolls after the Workflow has
already finished - by then there's nothing left to flip Secure Boot enforcement back on in the BMC,
which is a hard requirement for our Supermicro fleet (we have to disable Secure Boot to netboot
HookOS/iPXE at all, then re-enable it once the installed OS can be trusted). Doing the enrollment as
a Task Action, while Tinkerbell still controls the machine, lets bmc.Action/preparingActions/
postActions bracket the whole thing cleanly. Verified end to end against real Supermicro hardware.

Checklist

  • Tests added (enrollsecureboot/enroll/enroll_test.go - Setup Mode gating, successful
    enrollment with signature verification, invalid input handling, PRESERVE_VENDOR_CERTIFICATES
    with and without an existing db, INCLUDE_WELL_KNOWN_CERTIFICATES)
  • enrollsecureboot added to the ACTIONS list in Makefile, the build/release matrices in
    .github/workflows/{ci,release}.yml, and the top-level README.md table

Description for changelog/release notes

Add enrollsecureboot: enrolls a UEFI Secure Boot trust anchor into db while the firmware is in Setup Mode.

@mcanevet

Copy link
Copy Markdown
Author

This and https://github.com/tinkerbell/tinkerbell/pull/930/changes allows full SecureBoot enrollment at provisioning in one step

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new enrollsecureboot Action to enroll a UEFI Secure Boot trust anchor into db while firmware is in Setup Mode, intended for provisioning workflows before first secure boot.

Changes:

  • Introduces enrollsecureboot Action implementation (binary + scratch image) with efivarfs mounting and certificate download.
  • Adds enrollment library code using github.com/foxboron/go-uefi plus unit tests using the in-memory efivarfs double.
  • Wires the new Action into the repo’s build/release workflows, Makefile ACTIONS list, and README tables.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Adds enrollsecureboot to the top-level Actions list.
Makefile Adds enrollsecureboot to the buildable ACTIONS list.
go.mod Adds github.com/foxboron/go-uefi (and new indirect deps).
go.sum Records module checksums for the new dependency graph.
enrollsecureboot/README.md Documents the new Action usage and requirements.
enrollsecureboot/main.go Implements runtime flow: mount efivarfs, fetch cert, call enrollment.
enrollsecureboot/enroll/enroll.go Implements Setup Mode gating + PK/KEK/db enrollment via go-uefi.
enrollsecureboot/enroll/enroll_test.go Adds tests using in-memory efivarfs to validate enrollment behavior.
enrollsecureboot/Dockerfile Builds a static binary in a scratch image with CA certs.
.github/workflows/release.yml Adds enrollsecureboot to the release matrix.
.github/workflows/ci.yml Adds enrollsecureboot to the CI matrix.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread enrollsecureboot/main.go
Comment thread enrollsecureboot/enroll/enroll.go
Comment thread enrollsecureboot/enroll/enroll_test.go
Comment thread enrollsecureboot/enroll/enroll_test.go Outdated
Adds enrollsecureboot, an Action that enrolls a UEFI Secure Boot trust
anchor into db while the firmware is in Setup Mode, meant to run during
provisioning right after an OS has been written to disk but before the
machine reboots into it - so a later boot enforces Secure Boot against a
db that actually trusts the installed OS.

PK and KEK are populated with a throwaway, freshly generated self-signed
keypair by default: nothing re-signs db/KEK afterwards, so there's no
PK/KEK material worth persisting, and Setup Mode accepts any well-formed
signed variable update regardless of whether the signing key is already
trusted.

Built on github.com/foxboron/go-uefi rather than shelling out to
efitools/openssl, so the image stays a static scratch-based binary like
the rest of this repo's Actions. go-uefi also ships an in-memory efivarfs
test double, giving the enrollment logic (Setup Mode gating, signature-
list construction, PKCS7 signing) real unit test coverage without
physical UEFI firmware.

Two opt-in flags, both defaulting to false (narrowest trust set, matching
Talos's own IncludeWellKnownCertificates default):

- PRESERVE_VENDOR_CERTIFICATES: keeps whatever is already enrolled in db
  and KEK instead of discarding it. A ResetAllKeysToDefault BMC action
  run before this one (to reach Setup Mode) restores the vendor's
  factory-default db/KEK - DeletePK only removes PK, so that factory
  content is still sitting there right up until this Action's own write
  would otherwise replace it wholesale. Wiping it silently drops trust
  for anything signed against those vendor/Microsoft CAs, which on at
  least one real fleet (Dell PowerEdge, PERC/MegaRAID) breaks the RAID
  controller's boot-time Option ROM driver trust and makes its disks
  invisible to the installed OS - confirmed live, and independently
  confirmed by a colleague's working Dell iDRAC Ansible playbook using
  the same additive-enrollment approach (into both KEK and db).
- INCLUDE_WELL_KNOWN_CERTIFICATES: additionally enrolls a small, fixed,
  vendored bundle of Microsoft's UEFI CA certificates (the same three
  Talos's own secureboot database generator embeds), regardless of what's
  currently in db. Deterministic/reproducible across machines, unlike
  PRESERVE_VENDOR_CERTIFICATES, but generic - it won't include
  vendor-specific certs.

Both are opt-in rather than default-on because broadening db/KEK trust is
a real security tradeoff (an attacker doesn't need to break your own
signing if a still-validly-signed but vulnerable bootloader chains up
through a CA left enrolled), so it should be a deliberate per-deployment
choice.

Verified end to end against real Supermicro and Dell hardware.

Also bumps golang.org/x/text to v0.39.0, fixing GO-2026-5970 (infinite
loop on invalid input), flagged by Harbor's image scan.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Mickaël Canévet <mickael.canevet@proton.ch>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants