Linux Unified Kernel Images (UKI) and systemd-boot: A 2026 Secure Boot Guide
Build, sign, and enroll Unified Kernel Images on Linux: ukify, sbctl, systemd-boot, and TPM2 PCR policies for a measured, tamper-evident Secure Boot chain in 2026.
A Unified Kernel Image (UKI) is a single signed UEFI PE binary that bundles the Linux kernel, initrd, kernel command line, microcode, and a stub loader, so the firmware can verify and boot it as one measured artifact. That closes the historical gap where Secure Boot signed the kernel but left the initrd unsigned and tamper-able. In 2026, with systemd 256+ shipping ukify and systemd-pcrlock, distributions like Fedora 41, Arch, and Debian 13 treat UKIs as the default path to a measured, tamper-evident boot chain. This guide shows how to build, sign, and enroll UKIs end-to-end on modern Linux.
A UKI is a single PE/COFF binary (kernel + initrd + cmdline + stub) that Secure Boot can verify atomically, closing the unsigned-initrd attack surface.
Build UKIs with ukify (systemd 254+) or mkosi; sign with your own MOK or shim-enrolled key, not the vendor key.
UKIs make TPM2 measurement deterministic: PCR 11 records the stub, kernel, and initrd hashes, enabling reliable LUKS auto-unlock via sd-cryptenroll.
systemd-pcrlock (systemd 255+) predicts future PCR values across firmware updates, so TPM-bound secrets survive kernel upgrades.
The Microsoft third-party UEFI CA used by shim expires in 2026. Distros are migrating to a new CA, and self-signing with sbctl or sbsigntools is the most resilient long-term posture.
Pair UKIs with systemd-boot (not GRUB) for the smallest verified surface. GRUB cannot meaningfully extend measurements into PCRs without invasive patches.
What is a Unified Kernel Image?
A Unified Kernel Image is a single Portable Executable (PE) file, the same binary format Windows uses, that contains every artifact UEFI needs to boot Linux: the kernel itself, the initramfs, the kernel command line, an optional splash image, microcode updates, devicetree blobs, and a small loader called systemd-stub (also known as sd-stub). UEFI firmware treats the entire file as one executable, so a single Secure Boot signature covers the whole boot payload.
The contrast with the traditional model is stark. Historically, GRUB or systemd-boot would load vmlinuz (Secure Boot signed) and then a separate initrd (unsigned, world-readable, and easily replaced by an attacker with root or physical access). The boot loader would pass a kernel command line that nothing verified. UKIs collapse all three into one signed artifact. When the firmware verifies the PE signature, it has implicitly verified the kernel, the initrd, and the cmdline together.
The format is defined by the UAPI Group Unified Kernel Image specification. The stub portion ships with systemd and is itself signed; when called by the firmware it parses the embedded sections, hashes each into TPM2 PCR 11, and hands control to the kernel.
Why UKIs matter in 2026
Three forces have pushed UKIs from niche to default in 2026. First, the Microsoft third-party UEFI CA that signs nearly every distribution's shim binary is scheduled for expiration, with the replacement CA only trusted by firmware shipped from mid-2023 onward. Distributions are using the transition as an opportunity to encourage users away from shim's chain-of-trust gymnastics toward self-enrolled keys with UKIs, a posture documented in detail in the Fedora UnifiedKernelImage change proposal.
Second, TPM2-bound disk encryption only works reliably when the measurements that derive the unlock key are predictable. With a split kernel + initrd, every kernel update or initrd regeneration shifts PCR 4, 8, and 9 values unpredictably, and users routinely lock themselves out. I've personally locked myself out of a workstation twice this way before switching to a UKI flow. A UKI rolls everything into a single measurement in PCR 11, and systemd-pcrlock can pre-compute the next boot's PCR value before you reboot, so TPM-sealed LUKS secrets survive updates gracefully. If you've struggled with this pattern, our companion article on LUKS2, TPM2, and FIDO2 disk encryption walks through the enrollment side.
Third, confidential computing platforms (AMD SEV-SNP and Intel TDX) demand a deterministic boot artifact for remote attestation to be meaningful. UKIs give attestation services a single hash to verify rather than a fragile chain. This complements measured-boot patterns covered in our piece on confidential computing with SEV-SNP and TDX.
Anatomy of a UKI: PE sections explained
A UKI is a PE/COFF executable whose .text section is the systemd-stub loader. The interesting payload lives in additional named PE sections that the stub parses at boot. Inspect any UKI with objdump to see them:
Because every section sits at a fixed offset in a signed PE, mutating any of them invalidates the Authenticode signature. There's no realistic way to swap an initrd or inject an init=/bin/sh on the cmdline without resigning, and resigning requires the private key.
Building your first UKI with ukify
So, let's get into the actual build. The reference UKI builder is ukify, shipped with systemd 254 and refined heavily in 256. It produces signed PE files from a kernel and initrd, optionally embedding microcode, splash images, and devicetrees. On Arch, Fedora, and Debian 13, install it via:
Most distributions wire kernel-install to call ukify automatically on kernel upgrades via the 60-ukify.install hook. Once configured, a routine pacman -Syu or dnf upgrade produces a freshly signed UKI in /efi/EFI/Linux/ with no manual step.
How do you sign a UKI for Secure Boot?
UKIs sign with the same Authenticode mechanism as any other UEFI binary. You have three practical signing key choices: shim plus MOK (vendor-friendly, complex), self-enrolled PK/KEK/db keys (clean, requires firmware enrollment), or systemd's built-in signing tooling.
The most resilient long-term posture is self-enrollment with sbctl, which manages your own Platform Key (PK), Key Exchange Key (KEK), and signature database (db) on disk and enrolls them into firmware:
# Generate your own SB keys (one-time)
sbctl create-keys
# Enter firmware Setup Mode (varies by vendor, usually clear all keys in BIOS first)
# Then enroll, including Microsoft's own keys for option ROM compatibility
sbctl enroll-keys --microsoft
# Sign the UKI
sbctl sign -s /efi/EFI/Linux/arch-6.8.7.efi
# Verify
sbctl verify
sbctl list-files
If you prefer the systemd-native path, ukify accepts --secureboot-private-key and --secureboot-certificate flags and will sign during build:
Keep private keys out of the EFI partition. A reasonable compromise stores them on the encrypted root with 0400 permissions and a signed kernel-install hook that has access. For air-gapped builds, sign on a separate workstation and copy the signed PE file over.
Booting UKIs with systemd-boot
UKIs are technically standalone. UEFI firmware can boot them directly via efibootmgr entries. In practice, systemd-boot (also called sd-boot) is the right pairing: it auto-discovers UKIs in /EFI/Linux/, sorts them by version embedded in the .uname section, generates a menu, and supports automatic fallback if a boot fails.
Install sd-boot and let it discover your UKIs:
# Install sd-boot to the ESP
bootctl install
# UKIs in /efi/EFI/Linux/ appear automatically
bootctl list
# Sign the sd-boot binary too
sbctl sign -s /efi/EFI/BOOT/BOOTX64.EFI
sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi
A minimal /efi/loader/loader.conf for a hardened deployment:
default arch-*.efi
timeout 3
console-mode max
editor no
auto-entries no
auto-firmware yes
random-seed-mode always
The two security-relevant settings: editor no disables the boot-time cmdline editor (otherwise anyone at the keyboard can append init=/bin/bash to a non-UKI entry), and auto-entries no prevents Windows or auto-discovered installers from being added without your knowledge.
TPM2, PCR policies, and systemd-pcrlock
UKIs make TPM2-bound secrets practical because measurement becomes deterministic. When systemd-stub runs, it measures each PE section into PCR 11 with a phase tag: enter-initrd, leave-initrd, sysinit, ready, shutdown, and final. You can bind secrets to specific phases, so a key released during enter-initrd is no longer accessible once userspace starts.
Enroll a LUKS volume to unlock against UKI PCR 11 measurements:
The killer feature in systemd 255+ is systemd-pcrlock, which builds a policy from predicted future PCR values rather than the current ones. Before reboot, run:
# Build prediction policy from event log + boot components
systemd-pcrlock make-policy
# After kernel update, before reboot
systemd-pcrlock predict
systemd-pcrlock make-policy --recovery-pin=ask
Honestly, this is the feature that finally made TPM-sealed disks usable in production for me. It solves the historical pain of TPM-sealed disks bricking after every kernel update. For deeper measurement strategies including file integrity, see our coverage of IMA, EVM, and TPM attestation.
UKI vs traditional kernel + initrd
The trade-offs are not all in UKI's favor. Here's the honest comparison:
Dimension
UKI
Kernel + initrd
Secure Boot coverage
Kernel + initrd + cmdline atomic
Kernel only; initrd + cmdline unsigned
TPM2 measurement
Deterministic, PCR 11
Spread across PCR 4/8/9, fragile
Disk space per kernel
~100–200 MB (ESP)
~80 MB (boot) + small ESP
Bootloader choice
sd-boot, direct UEFI
GRUB, sd-boot, syslinux
Per-host initrd customization
Requires local rebuild + sign
Trivial via dracut hooks
Distro vendor signing
Possible but inflexible
Standard
Attestation friendliness
Excellent (single hash)
Poor
Recovery from broken update
Older UKIs remain in ESP
Easy: edit cmdline at boot
The biggest practical cost is ESP size. A traditional Debian install allocated 100 to 200 MB to /boot/efi; with three UKI generations kept, you want at least 1 GB. Resizing the ESP on an existing system is non-trivial, so plan ahead on new installs. Disk recovery is also different. The safety net is keeping the previous N UKIs in /efi/EFI/Linux/ and letting sd-boot's automatic fallback take over after three failed boots.
Troubleshooting boot and signing failures
The errors you'll see, in rough order of frequency:
"Security Violation" at firmware: the UKI is unsigned or signed with an unenrolled key. Run sbctl verify; re-enroll keys with sbctl enroll-keys.
Stub loads but kernel panics on initrd: initrd lacks the modules needed for your root device. Rebuild with dracut --regenerate-all --force (or mkinitcpio -P) before ukify packaging.
TPM2 unlock fails after kernel update: you skipped systemd-pcrlock make-policy. Use the LUKS recovery passphrase, boot, and re-run pcrlock.
sd-boot doesn't show the UKI: the file is in the wrong location. UKIs must live in /EFI/Linux/ on the ESP, with a .efi extension, and must contain an .osrel section.
"shim-review" SBAT failure: your UKI's SBAT level is below the system's revocation threshold. Rebuild with current systemd; SBAT updates ship in revocations.efi.
For systematic verification, the upstream ukify man page documents every option, and bootctl status on a running system reports the loaded UKI, the firmware's Secure Boot state, and the active PCR policy version.
Frequently Asked Questions
Does using a UKI require Secure Boot to be enabled?
No. A UKI is a valid UEFI executable regardless of Secure Boot state, so you can boot one with SB disabled. However, you lose most of the security benefit: the whole point is that the firmware verifies the signed PE before execution. Pair UKIs with Secure Boot in production.
What is the difference between ukify and mkosi?
ukify builds a single UKI from existing kernel and initrd files; it is the right tool for day-to-day use on an installed system. mkosi is a full OS image builder that can produce UKIs as part of a larger pipeline, including DDIs, root images, and confidential-computing images. Use ukify on hosts, mkosi for CI.
Can I use GRUB with a UKI?
Technically yes, since GRUB can chainload any UEFI PE binary, including a UKI. In practice this defeats the purpose: GRUB will not extend the UKI hash into PCR 11 the way the firmware would, breaking TPM-bound secrets. Use sd-boot, or have UEFI boot the UKI directly via efibootmgr.
How much space does a UKI take on the EFI System Partition?
Typical UKIs run 80 to 200 MB depending on initrd size, included microcode, and any embedded firmware. Plan for at least 1 GB of ESP space to hold three or four generations of UKIs plus the bootloader and any vendor utilities.
Will UKIs work on ARM64 servers?
Yes. The PE/COFF format and systemd-stub are architecture-neutral; ARM64 UKIs use the .dtb section to embed a devicetree blob when needed. AWS Graviton, Ampere Altra, and Apple Silicon Linux installs all support UKI workflows with the same ukify and sbctl tooling.
How Linux kernel live patching works in 2026 with kpatch, Ubuntu Livepatch, and TuxCare KernelCare. Install commands, comparison table, and audit tips for zero-downtime CVE fixes.
Wolfi vs Distroless vs Alpine base images for 2026 Linux workloads, with CVE benchmarks, apko and cosign pipeline snippets, and real migration examples for Node.js and Python services.
Deploy Keylime continuous remote attestation on Linux with TPM 2.0: registrar, verifier, Rust agent, IMA runtime policies, and revocation webhooks in 2026.