Install & OS Management via bootc with UKIs, LUKS, TPMs, systemd-boot, and custom SecureBoot
Find a file
2026-04-13 17:22:23 -05:00
.idea initial 2026-03-23 13:20:01 -05:00
tree initial 2026-03-23 13:20:01 -05:00
.gitignore initial 2026-03-23 13:20:01 -05:00
bootc-install-config.toml initial 2026-03-23 13:20:01 -05:00
build.sh disable SELinux security labels in podman builds 2026-04-13 17:22:23 -05:00
config.sh refactor installation and build scripts, improve variable handling and image processing 2026-03-24 09:46:05 -05:00
Containerfile-base initial 2026-03-23 13:20:01 -05:00
Containerfile-bootc initial 2026-03-23 13:20:01 -05:00
Containerfile-crypto initial 2026-03-23 13:20:01 -05:00
Containerfile-final refactor installation and build scripts, improve variable handling and image processing 2026-03-24 09:46:05 -05:00
Containerfile-iso initial 2026-03-23 13:20:01 -05:00
create-installer-media-for.sh refactor installation and build scripts, improve variable handling and image processing 2026-03-24 09:46:05 -05:00
crypto.sh update crypto init process 2026-03-23 16:59:52 -05:00
grub.cfg initial 2026-03-23 13:20:01 -05:00
init.sh initial 2026-03-23 13:20:01 -05:00
install.sh refactor installation and build scripts, improve variable handling and image processing 2026-03-24 09:46:05 -05:00
override.conf initial 2026-03-23 13:20:01 -05:00
README.md revise README for clarity, expand usage instructions, and improve project details 2026-03-25 12:02:22 -05:00

Create a Secure "Bare-Metal" bootc OS Deployment

This repo contains the automations and scripts to enable deploying RHEL with:

  • Custom SecureBoot PKI
  • Custom OCI image signature PKI
  • ComposeFS verified image
  • Immutable operating system deployment
  • Declarative configuration of RHEL (using container build tools to manage software/OS configuration)
  • signed systemd-boot
  • signed Universal Kernel Image (UKI)
  • TPM2 based LUKS decryption by default, out of the box
  • A minimal exposed surface area between installation time and a secure deployed config

Requirements

  • Have a quay.io account and image registry with all the access set up. Public registry is fine. All private material is kept out of the registry and the image is signed. But if you want private repo's, you can sign up for a Quay developer account.
  • podman

Usage & Deployment TLDR

  1. Modify config.sh with the values you need (Be sure to set the registry and hostname)
  2. bash init.sh
    • Generate the crypto for SecureBoot and cosign to sign UKI's, Systemd-Boot and OCI image signatures, etc.
  3. bash build.sh (and bash build.sh --push to push to the configured registry)
    • Build the OS to bootc-image.tar
    • The --push flag pushes the image update to the registry instead (for OS updates)
  4. bash create-installation-media-for.sh ./bootc-image.tar
    • Create a offline ISO installer for the OS that deploys the OS defined in ./bootc-image.tar
  5. After boot, login and run:
    • tpm2-luks-auto-upgrade.sh
      • This will lock down the TPM2 to using PCR7. Then, if the host is booted with different SecureBoot keys or a bootable ESP PE binaries that aren't signed by your SecureBoot keys, a UEFI Security Violation will propagate and the TPM2 will also fail to yield the LUKS key. If you were to sign an interactive live-boot image, it's possible that an adversary could retrieve the LUKS key from the TPM2.
    • bootc switch --enforce-container-sigpolicy your-quay.io-repository-ref-and-tag
      • This will switch bootc to pulling updates from your configured registry. See bootc's documentation for more details

Informational details about the project in no particular order

  • Containerfile-iso builds bootable ISO media. It's executed by the create-install-media-for.sh script which accepts ./bootc-image.tar (a local path) to your bootc container image to throw onto the ISO media for shipping to your bare metal server.
  • The repository is designed so you can use the scripts to automate building, creating media, pushing, deploying, signing, etc.
  • Building this type of OS deployment is a multi-stage process. I've left sane defaults for everything so you can just go customize Containerfile-base to add your software & configurations. If you refrain from changing boot things, it'll "just work".
  • init.sh builds & runs Containerfile-crypto to generate your PKI
  • Containerfile-crypto's only use is to generate the PKI directory and all the keys. YOU NEED THIS to sign systemd-boot and the UKI that is built for your RHEL instance. YOU NEED THIS to sign the OCI image artifacts before being pushed to the registry.
  • All of this is built to use RHEL/Fedora. There is not a Debian based, maintained, bootc image currently. Though you can build one!
  • I've "upgraded" RHEL in certain ways, like to use the latest bootc binary (for feature reasons). But otherwise it's pretty stock. I normally wouldn't touch it like this (because I'm sure under normal circumstances it'd break) but because this is declarative, it lends itself to major customization.
  • Containerfile-bootc just builds a specific revision of bootc on RHEL. It's designed to emit a RPM that can just in-place upgrade the bootc RPM on RHEL.
  • install.sh is the installer executed by the ISO installation media that Containefile-iso builds. You can modify this to customize the live-boot install time flow.
  • tree/ is intended for you to map out the root filesystem declaratively. It get's copied (and chowned to 0:0) right to the root of the RHEL filesystem.
  • tree/ includes a NetworkManager system-connections configuration to automatically map a en* device to a bridge interface. If you have multiple en* interfaces, this will likely break.
  • tpm2-luks-auto-upgrade.sh is there to change the installers deconfined TPM setting to be secure on boot. This was done so you only have to sign your UKI and systemd-boot with your SecureBoot keys making a substantially more secure setup.
  • build.sh does all the heavy lifting of actually making a real bootable bootc container.
  • override.conf and grub.cfg are just for the liveboot ISO. They get used to customize it to be usable as a installation environment.