To run Secure Boot with your own keys on Linux, back up the current PK, KEK, db and dbx, clear the Platform Key in firmware so the machine enters Setup Mode, create and enrol your own PK, KEK and db (sbctl does it in three commands), then sign your boot loader and kernel or unified kernel image before turning enforcement back on. Keep Microsoft's certificates enrolled unless you have checked every option ROM, and have a recovery key ready for any TPM-sealed disk.
This guide goes one level deeper than our explainer on Secure Boot, trusted boot and measured boot and our runbook on the 2026 Secure Boot certificate rotation. If a dual boot machine has just stopped starting, read why Windows updates break Linux dual boot and keep our GRUB rescue guide open.
Key takeaways
- The PK holds one certificate and controls KEK. KEK controls db (allow list) and dbx (deny list). dbx is checked first.
- On a new PC the device maker owns the PK and Microsoft's certificates sit in KEK and db. Distributions boot through shim, which Microsoft signs, and shim adds its own allow list, MOK.
- Owning the keys means only what you signed boots. It also means revocation, rotation and recovery become your job.
- Option ROMs on graphics, storage and network cards are usually signed by Microsoft's third party CA. Remove that CA without checking and a machine can lose its display before the OS starts.
- sbctl is the short path:
create-keys,enroll-keys -m,sign -son each boot file,verify. efitools is the manual path with signed.authfiles. - Sign a unified kernel image, not just the kernel, or the initrd and command line stay unprotected.
- db keys land in the kernel's platform keyring, which does not verify modules. Modules need a MOK or a built-in key.
- Changing any key store changes TPM PCR 7, so disks sealed to PCR 7 will ask for a recovery key once.
What PK, KEK, db, dbx and MOK are, and who owns each
Secure Boot is a set of authenticated firmware variables plus a rule: check the signature of every executable the firmware loads before the OS. Microsoft's guidance for device makers says that covers firmware drivers, option ROMs, UEFI drivers on disk, UEFI applications and boot loaders.
NSA's Secure Boot customization guidance on GitHub defines the stores this way:
- dbx, the deny list. Certificates and hashes of boot binaries that must not run. NSA notes that dbx is consulted before db.
- db, the allow list. Certificates and hashes of trusted boot binaries. A binary runs if its hash is in db or its signature chains to a certificate in db.
- KEK. Certificates allowed to sign updates to db and dbx. This is how Microsoft pushes dbx revocations to machines it never touched.
- PK. Exactly one certificate, which authorises changes to KEK. NSA notes that the device vendor normally sets it. Microsoft's guidance adds that makers may run their own PK or use a Microsoft managed PK held in Microsoft hardware security modules.
Two more names matter on Linux. MOK is shim's own allow list, stored in a variable called MokList, with a deny list in MokListX. shim's documentation calls MokList "a list of authorized keys and hashes" and copies it to MokListRT for the running kernel. SBAT is a generation number scheme that shim enforces through a variable called SbatLevel, covered in the revocation section.
| Store | Holds | Who can change it | Typical contents on a new PC |
|---|---|---|---|
| PK | One certificate | PK private key holder (maker, or Microsoft for its managed PK) | The maker's or Microsoft managed platform key |
| KEK | Keys that sign db and dbx updates | PK holder | Microsoft Corporation KEK CA 2011, and on updated machines KEK 2K CA 2023, sometimes a maker KEK |
| db | Allowed certificates and hashes | Any KEK holder | Windows Production PCA 2011, Microsoft UEFI CA 2011 (third party), their 2023 successors, sometimes maker certificates |
| dbx | Denied certificates and hashes | Any KEK holder | Microsoft's published revocations |
| MokList | Keys and hashes shim trusts | The person at the keyboard, through MokManager | Empty, or a DKMS or distribution key you enrolled |
| SbatLevel | Minimum generation numbers | shim | The level built into your shim |
The 2023 names come from Microsoft's key guidance and the Arch Wiki. Microsoft names Microsoft Corporation KEK 2K CA 2023 as the KEK it needs to push dbx revocations, plus a Microsoft Option ROM UEFI CA 2023 for card firmware. Our rotation runbook covers the 2011 expiry dates.
Setup Mode, User Mode and Custom Mode
- Setup Mode: no PK is enrolled, so writes to the key stores need no signature. Microsoft's guidance says an empty PK write in setup mode needs no authentication.
- User Mode: a PK is enrolled. KEK changes must be signed by the PK and db or dbx changes by a KEK. Enrolling the PK is what ends Setup Mode, so the Arch Wiki says to enrol it last.
- Custom Mode: a vendor menu option. sbctl's manual warns that on some firmware it only disables signature verification, so use it only when the firmware offers no other way into key management.
Enforcement is a separate switch. You can be in User Mode with Secure Boot off, which is where you want to be while testing.
Why replace the default keys, and what can go wrong
Why. With factory keys, anything signed by Microsoft's third party CA boots: every distribution's shim, vendor tools, and old signed binaries not yet revoked. With your own db key, only what you signed runs. NSA calls this full customization and recommends it for especially sensitive organisations and for teams that compile their own operating systems. Your own keys also let you sign a unified kernel image so the initrd and command line are covered, and they make TPM sealing to PCR 7 specific to your machine rather than to every PC that trusts Microsoft's CAs.
Why not. NSA warns that full customization "requires significant administrative overhead", because you must vet what is trustworthy and react to vulnerabilities in binaries you trust. Nobody will revoke a vulnerable boot loader for you. If that is too much, add your own db key next to Microsoft's, which NSA calls partial customization.
| Approach | What changes | Microsoft CAs kept | Windows dual boot | Option ROM risk | Ongoing work |
|---|---|---|---|---|---|
| Distribution default (shim plus MOK) | Nothing in firmware; add a MOK for DKMS | Yes | Works | None added | Distribution handles shim, GRUB, SBAT |
| Partial: own db key appended | Your certificate added to db | Yes | Works | None added | You sign your own binaries |
| Own PK and KEK, Microsoft certificates kept | PK and KEK replaced, Microsoft certificates re-added to db | Yes | Works if Windows CAs are in db | Low | You own key rotation |
| Full: only your keys | PK, KEK and db are yours alone | No | Only by hash | High until every option ROM is checked | You own revocation, rotation, recovery |
Option ROMs
This is the failure that bricks machines. Graphics cards, storage controllers and network cards carry small UEFI drivers that run before any boot loader. sbctl's FAQ says they are usually signed by the Microsoft Corporation UEFI CA 2011, and a failed check can effectively soft brick the device: with no integrated graphics there may be no display, and so no way to reach the setup menu. The Arch Wiki says this affects some business and gaming laptop lines, and sbctl's manual says "It's recommended to enroll your own keys with Microsoft certificates."
Check first. sbctl's FAQ reads option ROM loads from the TPM event log, and the Arch Wiki lists devices that expose a ROM:
sudo cp /sys/kernel/security/tpm0/binary_bios_measurements /tmp/eventlog
tpm2_eventlog /tmp/eventlog | grep -c BOOT_SERVICES_DRIVER
find /sys/devices/ -name rom
A non zero count means the firmware loaded drivers from outside its own image. Either keep Microsoft's certificates in db, or enrol the option ROM hashes from the event log, which sbctl's manual labels experimental. The FAQ's advice: "The safe option is to just enroll the Microsoft CA."
Dual boot with Windows
The Arch Wiki explains that re-signing Windows Boot Manager with your own key is unreliable: some firmware rejects a file with two signatures, and stripping Microsoft's breaks updates. Either add the hash of bootmgfw.efi to db after every boot manager update, or keep the Windows certificates in db. Keep the certificates. BitLocker usually seals to PCR 7, so expect one recovery prompt after the change.
Firmware updates
Microsoft's guidance tells makers not to use the PK as the firmware update key, so replacing the PK does not by design block a maker's signed capsule. What breaks is the OS side: fwupd hands capsules to fwupdx64.efi, which must be signed by your db key. Some firmware also writes default keys back after an update or settings reset, so check sbctl status after every firmware update.
Other things that stop booting: unsigned tools on the ESP (memtest, a UEFI shell, vendor diagnostics), and live USB sticks or VM images carrying their own shim if you removed Microsoft's third party CA.
Before you start: checks and backups
1. Confirm UEFI boot and current state.
test -d /sys/firmware/efi && echo "UEFI boot" || echo "Legacy BIOS boot: stop here"
mokutil --sb-state
sbctl status
2. Find the ESP. sbctl's manual says it may be on /efi, /boot or /boot/efi.
findmnt -t vfat
3. Back up the key stores. The Arch Wiki's loop saves all four as EFI signature lists; sbctl can export them too.
mkdir -p ~/sb-backup && cd ~/sb-backup
for var in PK KEK db dbx ; do efi-readvar -v $var -o old_${var}.esl ; done
sudo sbctl export-enrolled-keys --dir ~/sb-backup/sbctl-export --format esl
These are public lists, not private keys, but copy them off the machine.
4. Collect recovery keys: BitLocker recovery keys, LUKS passphrases or recovery keys, and the firmware admin password.
5. Check option ROMs as above.
6. Have a rescue path: a live USB that boots under the current keys and, for servers, an out of band console. To reach firmware setup from Linux:
systemctl reboot --firmware-setup
How to put firmware into Setup Mode
The sbctl manual says you normally do this by clearing the Secure Boot keys, or at least the Platform Key, while leaving Secure Boot itself enabled. Look for "Clear Secure Boot keys", "Delete all Secure Boot variables" or "Delete PK". Leave "Restore factory keys" alone for now; it is your undo button.
Warning: clearing keys does not touch disks, but it changes what boots and changes PCR 7. Do it only after the backups and recovery keys above are in hand. Back in Linux, sbctl status should show Setup Mode enabled.
Step by step with sbctl
sbctl describes itself as "a user-friendly secure boot key manager". It creates the keys, enrols them from the running system, tracks files to sign and verifies the ESP. Its README lists packages for Arch, Alpine, Gentoo and openSUSE, plus unofficial Fedora and Ubuntu builds.
| Step | Command | What it does | Writes to |
|---|---|---|---|
| 1 | sbctl status | Confirms Setup Mode | Nothing |
| 2 | sbctl create-keys | Creates PK, KEK, db keys and an owner GUID | /var/lib/sbctl/ |
| 3 | sbctl enroll-keys -m | Enrols your keys plus Microsoft's certificates | EFI variables |
| 4 | sbctl verify | Lists signed and unsigned EFI files | Nothing |
| 5 | sbctl sign -s FILE | Signs and records each boot file | The file, files.db |
| 6 | Reboot, enable Secure Boot | Starts enforcement | Firmware |
| 7 | sbctl sign-all after updates | Re-signs recorded files | The files |
Create the keys.
sudo sbctl create-keys
Keys go to /var/lib/sbctl/keys/{PK,KEK,db}. The manual says file keys are always RSA 4096, belong only on a system whose root partition is encrypted, and cannot be password protected. sbctl can also keep keys in the TPM (RSA 2048), and suggests TPM keys for PK and KEK with a file key for db, because TPMs sign slowly. The README shows a hardware token option too.
Enrol them.
sudo sbctl enroll-keys -m # add -f to also enrol the firmware's built-in default db and KEK
sudo sbctl status
sudo sbctl list-enrolled-keys
-m adds Microsoft's UEFI certificates to db. -f enrols the firmware's own default signatures, which some laptops need for their own components; the Arch Wiki's example uses both. If sbctl stops on an option ROM error, it is protecting you; its override flag is literally named "yes-this-might-brick-my-machine". If writes fail, sbctl's -i option clears the immutable attribute on the efivars files, and the Arch Wiki covers firmware admin passwords that block writes on some laptops.
Sign the boot path.
sudo sbctl verify
sudo sbctl sign -s /efi/EFI/BOOT/BOOTX64.EFI
sudo sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi
sudo sbctl sign -s /boot/vmlinuz-linux
sudo sbctl sign -s -o /usr/lib/fwupd/efi/fwupdx64.efi.signed /usr/lib/fwupd/efi/fwupdx64.efi
Paths differ by distribution. The fwupd line comes from the sbctl README. For systemd-boot the Arch Wiki signs the copy in /usr/lib/systemd/boot/efi/ to a .signed file so bootctl update installs the signed one. If sbctl verify lists a file you do not recognise, find out what it is before you sign it.
Enforce and keep it signed. Reboot into firmware, enable Secure Boot, boot, and run sbctl status. The manual says to run sign-all after updates; on Arch a pacman hook does it. On other distributions make sure a kernel install hook runs it, or the next kernel update will not boot.
Step by step with efitools and sbsigntools
The manual route follows the Arch Wiki and the efitools and sbsigntools man pages.
1. Create a GUID and three key pairs.
mkdir -p ~/sb-keys && cd ~/sb-keys && chmod 700 .
uuidgen --random > GUID.txt
for k in PK KEK db; do
openssl req -newkey rsa:4096 -noenc -keyout $k.key -new -x509 -sha256 -days 3650 \
-subj "/CN=my $k key/" -out $k.crt
openssl x509 -outform DER -in $k.crt -out $k.cer
done
The private keys are unencrypted, so keep them on an encrypted disk or move them somewhere safer.
2. Build signature lists and signed updates.
cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl
sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth
cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl
sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl KEK.auth
cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl
sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth
The PK signs its own update and the KEK update; the KEK signs db. The sign-efi-sig-list man page notes the timestamp comes from system time unless you pass -t, and a wrong one can make firmware reject the update. The Arch Wiki also signs an empty PK update, noPK.auth, to leave User Mode later, and warns never to copy it to the ESP: anyone who reads it can clear your PK.
3. Append Microsoft's certificates if you need them. Download the DER files from Microsoft's own links (listed in its key guidance and in the secureboot_objects repository), convert them with Microsoft's owner GUID as the Arch Wiki shows, and sign an append update with your KEK:
cert-to-efi-sig-list -g 77fa9abd-0359-4d32-bd60-28f4e78f784b microsoft-uefi-ca-2011.crt ms.esl
sign-efi-sig-list -a -g 77fa9abd-0359-4d32-bd60-28f4e78f784b -k KEK.key -c KEK.crt db ms.esl add_ms.auth
4. Enrol db and KEK first, PK last.
sudo chattr -i /sys/firmware/efi/efivars/{PK,KEK,db}* 2>/dev/null
sudo efi-updatevar -f db.auth db
sudo efi-updatevar -a -f add_ms.auth db # only if you kept Microsoft's CA
sudo efi-updatevar -f KEK.auth KEK
sudo efi-updatevar -f PK.auth PK
The efi-updatevar man page: -f adds or replaces from an .esl or .auth file, -a appends, and -e writes a plain list, which "only works in Setup Mode". Alternatives: sbkeysync reads a tree of .auth files under /etc/secureboot/keys (run a dry run first), and systemd-boot offers an enrol entry for files in /loader/keys/NAME/ on the ESP. Its secure-boot-enroll setting defaults to if-safe, which only enrols automatically inside a virtual machine, and its documentation opens with "Danger: this feature might soft-brick your device if used improperly."
5. Sign the boot chain.
sudo sbsign --key db.key --cert db.crt --output /efi/EFI/BOOT/BOOTX64.EFI /efi/EFI/BOOT/BOOTX64.EFI
sudo sbsign --key db.key --cert db.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux
sbverify --list /boot/vmlinuz-linux
As the Arch Wiki warns, "Signing kernel only will not protect the initramfs from tampering."
Sign a unified kernel image instead of only the kernel
A unified kernel image (UKI) is one PE file holding the systemd stub, kernel, initrds, command line and os-release data. One signature covers all of it. sbctl's own manual says its bundle feature is being phased out in favour of dracut, mkinitcpio and ukify.
sudo ukify build \
--linux=/boot/vmlinuz-$(uname -r) \
--initrd=/boot/initrd.img-$(uname -r) \
--cmdline="root=UUID=REPLACE-ME rw quiet" \
--secureboot-private-key=/var/lib/sbctl/keys/db/db.key \
--secureboot-certificate=/var/lib/sbctl/keys/db/db.pem \
--output=/efi/EFI/Linux/linux.efi
ukify's manual says that with a Secure Boot key "the resulting PE binary will be signed as a whole", and that it merges any .sbat sections from the stub and kernel so shim applies revocations for either part.
To make it permanent, put the key paths in /etc/kernel/uki.conf. The manual notes that the 60-ukify.install plugin for kernel-install reads that file by default, so each new kernel is built and signed on install:
[UKI]
SecureBootPrivateKey=/etc/kernel/secureboot-private-key.pem
SecureBootCertificate=/etc/kernel/secureboot-certificate.pem
ukify genkey can generate those files; if you use a fresh key, its certificate must still be enrolled in db. systemd-boot lists UKIs in /EFI/Linux/ automatically.
How shim and MOK fit if you keep the distribution chain
Firmware checks shim against db; shim is signed by Microsoft's third party CA. shim then checks the next stage against its built-in vendor certificate, db and MokList. Its README says that if the normal firmware load fails, shim checks the binary against its built-in certificate and runs it only if neither the binary nor its key is on a deny list. Since shim 16.1, its loader protocol lets signed UKIs load "even if the nested kernel is not signed"; inner images are still checked against dbx, MOKX and SBAT.
Enrolling a MOK:
openssl req -newkey rsa:2048 -nodes -keyout MOK.key -new -x509 -sha256 -days 3650 \
-subj "/CN=my Machine Owner Key/" -out MOK.crt
openssl x509 -outform DER -in MOK.crt -out MOK.cer
sudo mokutil --import MOK.cer
mokutil --list-new
mokutil asks for a one time password. On the next boot shim starts MokManager, which asks you to confirm and type it. shim's variable notes explain the check: mokutil stores the request in MokNew with a password hash in MokAuth, and MokManager enrols only if what you type matches. That physical presence step stops root malware from silently adding a key. The Arch Wiki recommends 2048 bit MOKs because shim may hang on 4096 bit ones.
You can also own PK and KEK and still boot through shim: keep Microsoft's third party CA in db, or sign the distribution's shim with your own db key and re-sign it after every shim update.
How to sign kernel modules (DKMS, NVIDIA, VirtualBox) under your own keys
Modules do not use db, which surprises most people.
Which keys verify modules. The kernel's module signing documentation describes the .builtin_trusted_keys keyring, compiled in, plus certificates from CONFIG_SYSTEM_TRUSTED_KEYS. The kernel's integrity Kconfig explains where firmware keys go. The platform keyring is filled from firmware (db on UEFI) for verifying kexec kernel images and possibly initramfs signatures, according to its help text, not for modules. The machine keyring holds MOKs, and unlike platform keys they "will be trusted within the kernel." So a module signed with your db key will not load on an enforcing kernel (unless your distribution patches this), while one signed with a MOK will on kernels built with the machine keyring. Check yours:
sudo keyctl list %:.builtin_trusted_keys
sudo keyctl list %:.machine 2>/dev/null
sudo keyctl list %:.platform
cat /sys/kernel/security/lockdown
When signatures are enforced. The documentation says that with CONFIG_MODULE_SIG_FORCE or module.sig_enforce=1 the kernel loads only modules with a valid signature from a key it holds. Kernel lockdown, added in Linux 5.4, has the same effect: "Only validly signed modules may be loaded". Some distribution kernels switch lockdown on under Secure Boot and some do not; the lockdown file shows yours.
DKMS. GPU drivers and desktop hypervisor modules are usually built by DKMS. Its README says DKMS creates a self signed certificate and signs every module it builds, keeping mok.key and mok.pub in /var/lib/dkms. Enrol the certificate once:
sudo mokutil --import /var/lib/dkms/mok.pub
To reuse another key, set mok_signing_key and mok_certificate in /etc/dkms/framework.conf; the README's example points at Ubuntu's /var/lib/shim-signed/mok/MOK.priv and MOK.der. Two cautions from the README: if either file is missing DKMS regenerates both, leaving you with an unenrolled key, and from DKMS 3.1.7 the certificate carries the code signing key usage, so keys from older versions may need regenerating.
By hand. The kernel's scripts/sign-file takes the hash, private key, certificate and module:
sudo /lib/modules/$(uname -r)/build/scripts/sign-file sha256 \
/var/lib/dkms/mok.key /var/lib/dkms/mok.pub /path/to/example.ko
The documentation calls signed modules "BRITTLE": the signature is appended, so never strip after signing, and the ~Module signature appended~ marker shows a signature exists, not that it is valid.
Without shim there is no MOK. If you boot a UKI straight from your own db key and your kernel enforces signatures, out of tree modules need a key the kernel already trusts. Keep shim in the chain, build your own kernel with your certificate in CONFIG_SYSTEM_TRUSTED_KEYS, or accept a kernel that does not enforce. Check the keyrings before you choose.
How to keep dbx and SBAT revocations current
To stop a vulnerable boot loader you can add its hash or signing certificate to dbx, or raise its SBAT generation. Once you own KEK, dbx is your job.
dbx
Microsoft signs dbx updates with its KEK. If Microsoft's KEK is still enrolled, they keep arriving from Windows Update or fwupd. fwupd's dbx plugin documentation says it checks whether dbx holds the latest revoked checksums, identifies devices from the SHA256 of the certificates in your KEK, matches components against a hash of the system PK, and hardcodes the vendor as UEFI:Microsoft. It also notes dbx updates are "typically no longer done from a firmware update" because a machine can be bricked if the boot loader is not updated first.
If you removed Microsoft's KEK, take the revocation content from Microsoft's secureboot_objects repository and sign an append update yourself:
sign-efi-sig-list -a -g "$(< GUID.txt)" -k KEK.key -c KEK.crt dbx dbx-update.esl dbx-update.auth
sudo efi-updatevar -a -f dbx-update.auth dbx
First confirm the boot loader you actually use is not in the update. If you trust only your own db key, most of Microsoft's revocations cover binaries your machine already refuses. Your real question is whether you ever signed something that later proved vulnerable; if so, add its hash to dbx or rotate the db key and re-sign only current binaries.
dbx is small. shim's SBAT document records that the 2020 BootHole revocation added 3 certificates and 150 hashes on x64, using "10kB of the 32kB" of typical revocation storage. That is why SBAT exists.
SBAT
Each shim, GRUB or UKI carries a small CSV section naming its component and security generation. shim compares it with SbatLevel and refuses anything older, so one short entry revokes a whole family of builds. shim's SbatLevel_Variable.txt is the canonical list. On 23 October 2026 its newest entry, for the November 2025 GRUB issues, reads sbat,1,2025112400 with shim,4 and grub,6.
mokutil --list-sbat-revocations
sudo mokutil --set-sbat-policy latest
mokutil's manual says the policy picks between shim's latest and automatic revocation sets, and warns: "If UEFI Secure Boot is disabled, then shim will automatically delete SBAT revocations". SBAT is enforced by shim, not firmware; the level file says "On systems that run shim, shim will manage these revocations." Boot a UKI without shim and SBAT is not enforced, so dbx and key rotation are your only revocation tools.
Rotating your keys
sbctl's rotate-keys replaces the keys with newly generated ones, saving old keys under /var/tmp and re-signing every recorded file; -p rotates one level. Rotating db is routine. Rotating PK should be planned like the first enrolment. With efitools, sign the new db .esl with your KEK, append it, re-sign binaries, then remove the old entry.
How to recover if the machine will not boot
Go from least to most invasive: turn Secure Boot off in firmware (your keys stay) and sign what sbctl verify reports; boot a signed live USB if you kept Microsoft's third party CA; use "Restore Factory Keys"; or clear the keys and re-enrol a corrected set from Linux. Your .auth files and efi-readvar backups let you put your own set back later.
| Symptom | Likely cause | First fix |
|---|---|---|
| Security violation before the boot menu | Boot loader or shim not trusted by db | Disable Secure Boot, sign it, re-enable |
| Menu appears, chosen entry fails | Kernel or UKI unsigned or signed with an unenrolled key | sbctl sign-all from a rescue boot |
| GRUB says "prohibited by secure boot policy" | Kernel shim cannot verify | Sign with a MOK, or use a signed UKI |
| No display until the OS loads, or never | An option ROM failed verification | Integrated graphics or another card, then restore factory keys and re-enrol keeping Microsoft's CA |
| Out of tree module fails to load | Unsigned, or key not in a trusted keyring | Enrol the DKMS key as a MOK |
| Disk will not unlock from TPM | PCR 7 changed | Recovery key, then re-seal |
| Windows asks for BitLocker recovery | PCR 7 changed | Enter the recovery key |
For a machine with no display at all, try integrated graphics or a serial or out of band console. Clearing firmware settings with the board's reset may or may not restore default keys; check the maker's documentation rather than assuming.
How this combines with TPM-bound disk encryption
systemd-cryptenroll binds LUKS2 key slots to TPM PCRs. Its PCR table says PCR 7 changes when Secure Boot is turned on or off or when PK, KEK, db or dbx change, matching the UAPI Group's Linux TPM PCR registry. The manual prefers PCR 7 to PCRs 0 and 2, because the certificates in PCR 7 already cover that code indirectly, and notes that PCR 2 includes option ROMs on pluggable cards. With your own keys, PCR 7 reflects a db that trusts only you, so only your signed chain reproduces it.
The order: make sure every volume has a passphrase or recovery slot; enrol keys and enable Secure Boot; unlock once with the recovery key; then re-seal.
Warning: the re-seal command wipes a LUKS key slot. On the wrong device or without another slot, you can lose access. Check the device path and slots first:
lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINTS
sudo cryptsetup luksDump /dev/nvme0n1p3 | sed -n '/Keyslots:/,/Tokens:/p'
Confirm the path is your LUKS volume (replace /dev/nvme0n1p3) and a passphrase or recovery slot exists, then:
sudo systemd-cryptenroll /dev/nvme0n1p3 --recovery-key # only if you have none yet
sudo systemd-cryptenroll /dev/nvme0n1p3 --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=7
The manual gives that last form to "update existing enrollments". If you sign PCR policies into your UKIs with ukify's PCR key options, you can bind to the public key instead; the manual says the policy then defaults to PCR 11, which accepts any unified kernel image you have signed a PCR policy for, so kernel updates do not need a re-seal.
Common mistakes
- Removing Microsoft's third party CA without checking option ROMs. The top way to lose a display at boot.
- Enrolling the PK first. It ends Setup Mode and later unsigned writes fail.
- Using Custom Mode when "clear keys" exists. On some firmware it only disables verification.
- Signing only the kernel. Use a UKI so the initrd and command line are covered.
- No re-sign hook. The first kernel update after enrolment will not boot.
- Forgetting
fwupdx64.efi. Firmware updates through fwupd stop working. - Unencrypted private keys on an unencrypted disk. Anyone with your db key can sign a loader your machine trusts.
- Copying
noPK.authto the ESP. It hands anyone a way back to Setup Mode. - Expecting db keys to verify modules. Use a MOK or a built-in key.
- Testing with Secure Boot off for weeks. shim deletes SBAT revocations while it is off.
- Changing keys without BitLocker or LUKS recovery keys. PCR 7 will change.
FAQ
Do I need to replace the Platform Key to sign my own kernel?
No. Add your certificate to db, or enrol a Machine Owner Key and keep the distribution's shim. Replacing PK and KEK matters only if you want to stop anyone else's keys changing what your firmware trusts.
Will Windows still boot with my own Secure Boot keys?
Yes, if Microsoft's Windows certificates are in db. sbctl's -m option enrols Microsoft's certificates; confirm with sbctl list-enrolled-keys before rebooting. Expect one BitLocker recovery prompt.
What is the difference between db and MOK?
db is a firmware variable the firmware checks. MOK is a list shim checks, changed through MokManager at boot with a password. db keys reach the kernel's platform keyring; MOKs reach the machine keyring, which can verify modules.
How do I sign NVIDIA or VirtualBox modules with Secure Boot on?
Both are usually built by DKMS. Let DKMS sign them, enrol /var/lib/dkms/mok.pub once with mokutil's import command (shown in the DKMS section above), and confirm in MokManager on the next boot. If your driver package uses another key path, set it in /etc/dkms/framework.conf.
How do I check if Secure Boot is enforcing on Linux?
Run sbctl status, or mokutil with its Secure Boot state option. sbctl status also shows whether the firmware is in Setup Mode, which would let anyone change the keys.
Do I still need dbx updates if I only trust my own keys?
Fewer, but some. Microsoft's dbx mostly revokes binaries signed by its CAs, which your machine no longer trusts if you removed them. Anything you ever signed is your responsibility: use dbx or rotate the db key.
Why does my disk ask for a recovery key after enrolling keys?
PCR 7 measures the Secure Boot certificates. Changing any of them changes PCR 7, so the old seal fails. Unlock with the recovery key and re-seal with systemd-cryptenroll.
Can I keep Secure Boot private keys in the TPM or on a hardware token?
sbctl supports TPM shielded keys (RSA 2048) and its README shows a hardware token option. Its manual suggests TPM keys for the rarely used PK and KEK and a file key on an encrypted disk for db.
Where Safeguard fits, and where it does not
Safeguard does not manage firmware keys, sign boot binaries, scan firmware or option ROMs, or manage devices. Everything above is done with sbctl, efitools, ukify, mokutil and your firmware menu. The honest link is the software in the chain: shim, GRUB, systemd-boot, the kernel, DKMS, fwupd and sbctl are open source components with their own vulnerabilities and fixed versions, and SBAT exists because old GRUB and shim builds keep turning up flaws. If you build OS, golden or container images from a repository, Safeguard can scan that repository, the image or its SBOM, show which projects carry a given component version and match versions against vulnerability data. It cannot tell you what is enrolled in a given machine's db.
Owning your Secure Boot keys means owning the response when a boot component you signed turns out to be vulnerable, and the same is true one layer up for every open source package on the machine. A re-keyed or rebuilt machine pulls its tools and dependencies again, and the boot loaders, signing tools and drivers in this guide ship open source components, so the dependency hygiene below still applies even though its fit with firmware itself is indirect.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
None of these demos touch firmware, Secure Boot keys or signing. They show the software side of a machine you have just re-keyed or rebuilt.
This is a real Safeguard CLI session: install, open the interactive terminal, ask it to fix a lodash CVE, and approve each command as it edits package.json and runs npm install and npm test, with nothing pushed. After a re-key and a fresh kernel, the same flow is how you would rescan and fix the projects you clone back onto the machine, approving every command yourself.
Click through it at your own pace, or open it full screen.
This demo sets up the Safeguard runner on your own machine, approves it with a device code, and runs a scan from the terminal. If you build your own OS or golden images in a repository, the same runner can scan that repository or an SBOM of the image, so the shim, GRUB, kernel and tool versions you ship are checked against vulnerability data.
Click through it at your own pace, or open it full screen.
Here Claude connects to the Safeguard MCP server with OAuth, and you choose which Safeguard tools Claude may use. That is useful when you want to ask, in plain language, which of your projects carry a given boot or build component version, while keeping the assistant's access limited to the tools you picked.
Click through it at your own pace, or open it full screen.
To try it on your own projects, download Safeguard or read the CLI documentation.
Quick check
Why should the Platform Key be enrolled last?
Enrolling the PK moves the firmware from Setup Mode to User Mode. After that, every KEK change must be signed by the PK and every db or dbx change by a KEK, so unsigned writes of the other keys would fail.
A module signed with your db key will not load on a kernel that enforces signatures. Why?
The kernel loads db certificates into its platform keyring, which is used for kexec images, not module signatures. Modules need a key in the built-in, secondary or machine keyring, and enrolling a Machine Owner Key through shim is the usual way to get one into the machine keyring.
Sources
- sbctl README, Foxboron/sbctl on GitHub
- sbctl(8) manual, Foxboron/sbctl on GitHub
- sbctl FAQ: Option ROM, Foxboron/sbctl wiki
- shim README, rhboot/shim on GitHub
- SBAT.md, rhboot/shim on GitHub
- SbatLevel_Variable.txt, rhboot/shim on GitHub
- MokVars.txt, rhboot/shim on GitHub
- Kernel module signing facility, Linux kernel documentation
- security/integrity/Kconfig, Linux kernel source on git.kernel.org
- kernel_lockdown(7), Linux man-pages
- ukify(1), systemd manual
- systemd-boot(7), systemd manual
- loader.conf(5), systemd manual
- systemd-cryptenroll(1), systemd manual
- Linux TPM PCR Registry, UAPI Group
- mokutil(1), Debian manpages
- efi-updatevar(1), Debian manpages
- cert-to-efi-sig-list(1), Debian manpages
- sign-efi-sig-list(1), Debian manpages
- sbsign(1), Debian manpages
- DKMS README: module signing and Secure Boot, dell/dkms on GitHub
- Plugin: UEFI dbx, fwupd on GitHub
- Windows Secure Boot Key Creation and Management Guidance, Microsoft Learn
- microsoft/secureboot_objects, GitHub
- UEFI Secure Boot Customization, NSA Cybersecurity on GitHub
- Unified Extensible Firmware Interface/Secure Boot, Arch Wiki
Last reviewed: 23 October 2026. Tool options change between releases; check the sbctl, systemd and shim documentation for the version you run.