Secure Boot: sign CachyOS kernel + nvidia modules, auto-enroll via ISO #13

Merged
Mondrethos merged 3 commits from add-secure-boot into main 2026-06-27 06:27:58 +00:00
Mondrethos commented 2026-06-27 05:37:16 +00:00 (Migrated from github.com)

Makes the GNOME editions Secure Boot capable with a self-managed MOK key, and adds a manual ISO-generation job that auto-enrolls it.

What this does

  • Mint a MOK keypairopenssl.cnf + just generate-secureboot-key. Private key (MOK.priv) is build-only (gitignored, lives in the KERNEL_SIGNING_SECRET repo secret); the public .der is committed and baked into the image.
  • Sign the CachyOS vmlinuz (sign-kernel.sh, sbsign) in gnome-base.yml, so both GNOME editions boot under Secure Boot. Unlike ublue/BlueBuild base images, we swap in the unsigned CachyOS kernel, so shim/GRUB reject it until it's signed by an enrolled key.
  • Sign the nvidia module (sign-modules.sh + sign-check.sh, adapted from blue-build/base-images with zstd support) in nvidia.yml, with the same key. One enrolled MOK covers the whole boot+driver chain.
  • CI materializes MOK.priv from KERNEL_SIGNING_SECRET (base64) and mounts it via the recipe secrets; skip_checkout preserves it.
  • Auto-enrollment — the ISO installer pre-stages MOK enrollment of our public cert with the password monolith, so users get the MokManager screen on first boot and just type the password. A ujust enroll-secure-boot-key fallback covers rebased systems.
  • ISO job (generate-iso.yml, manual) builds an ISO for a published edition and uploads it as an artifact, passing our cert/password explicitly (not the BlueBuild/UBlue defaults). Uses only public data — no signing key.

Required before CI is green

Add the signing key as a repo secret (the build guards on it):

base64 -w0 MOK.priv | gh secret set KERNEL_SIGNING_SECRET

Caveats

  • CI proves the image builds and signs; a physical Secure-Boot boot test on real hardware is the remaining unknown.
  • The ISO job's privileged Anaconda build is the finickiest part of the toolchain and may need iteration on first run.
  • The cert --secure-boot-url resolves only once the .der is on main.
Makes the GNOME editions Secure Boot capable with a self-managed MOK key, and adds a manual ISO-generation job that auto-enrolls it. ## What this does - **Mint a MOK keypair** — `openssl.cnf` + `just generate-secureboot-key`. Private key (`MOK.priv`) is build-only (gitignored, lives in the `KERNEL_SIGNING_SECRET` repo secret); the public `.der` is committed and baked into the image. - **Sign the CachyOS `vmlinuz`** (`sign-kernel.sh`, `sbsign`) in `gnome-base.yml`, so *both* GNOME editions boot under Secure Boot. Unlike ublue/BlueBuild base images, we swap in the unsigned CachyOS kernel, so shim/GRUB reject it until it's signed by an enrolled key. - **Sign the nvidia module** (`sign-modules.sh` + `sign-check.sh`, adapted from `blue-build/base-images` with zstd support) in `nvidia.yml`, with the same key. One enrolled MOK covers the whole boot+driver chain. - **CI** materializes `MOK.priv` from `KERNEL_SIGNING_SECRET` (base64) and mounts it via the recipe `secrets`; `skip_checkout` preserves it. - **Auto-enrollment** — the ISO installer pre-stages MOK enrollment of our public cert with the password `monolith`, so users get the MokManager screen on first boot and just type the password. A `ujust enroll-secure-boot-key` fallback covers rebased systems. - **ISO job** (`generate-iso.yml`, manual) builds an ISO for a published edition and uploads it as an artifact, passing our cert/password explicitly (not the BlueBuild/UBlue defaults). Uses only public data — no signing key. ## Required before CI is green Add the signing key as a repo secret (the build guards on it): ``` base64 -w0 MOK.priv | gh secret set KERNEL_SIGNING_SECRET ``` ## Caveats - CI proves the image **builds and signs**; a physical **Secure-Boot boot test** on real hardware is the remaining unknown. - The ISO job's privileged Anaconda build is the finickiest part of the toolchain and may need iteration on first run. - The cert `--secure-boot-url` resolves only once the `.der` is on `main`.
github-actions[bot] commented 2026-06-27 05:37:22 +00:00 (Migrated from github.com)

🧪 Test this PR on a real install

Once the build check on this PR passes, a signed test image is published to ghcr.io/mondrethos/monolith-gnome:pr-13-44. From an existing monolith install (which already has the signing policy), rebase onto it:

rpm-ostree rebase ostree-image-signed:docker://ghcr.io/mondrethos/monolith-gnome:pr-13-44
systemctl reboot

The tag is rebuilt on every new commit here, so rpm-ostree upgrade pulls the latest build. When you're done testing, return to the released image:

rpm-ostree rebase ostree-image-signed:docker://ghcr.io/mondrethos/monolith-gnome:latest

The test tag stops updating once this PR is merged or closed.

### 🧪 Test this PR on a real install **Once the build check on this PR passes**, a signed test image is published to `ghcr.io/mondrethos/monolith-gnome:pr-13-44`. From an existing monolith install (which already has the signing policy), rebase onto it: ```bash rpm-ostree rebase ostree-image-signed:docker://ghcr.io/mondrethos/monolith-gnome:pr-13-44 systemctl reboot ``` The tag is rebuilt on every new commit here, so `rpm-ostree upgrade` pulls the latest build. When you're done testing, return to the released image: ```bash rpm-ostree rebase ostree-image-signed:docker://ghcr.io/mondrethos/monolith-gnome:latest ``` _The test tag stops updating once this PR is merged or closed._
Sign in to join this conversation.
No description provided.