composefs backend
Experimental features are subject to change or removal. Please do provide feedback on them.
Overview
The composefs backend is an experimental alternative storage backend that uses composefs-rs instead of ostree for storing and managing bootc system deployments.
Status: Experimental. The composefs backend is under active development and not yet suitable for production use. The feature is always compiled in as of bootc v1.10.1.
A key goal is custom "sealed" images, signed with your own Secure Boot keys. This is based on Unified Kernel Images that embed a digest of the target container root filesystem, typically alongside a bootloader (such as systemd-boot) also signed with your key.
How Sealed Images Work
A sealed image is a cryptographically signed and verified bootc image that provides end-to-end integrity protection. This is achieved through:
- Unified Kernel Images (UKIs): Combining kernel, initramfs, and boot parameters into a single signed binary
- Composefs integration: Using composefs with fsverity for content-addressed filesystem verification
- Secure Boot: Cryptographic signatures on both the UKI and systemd-boot loader
A sealed image includes:
- composefs digest: A SHA-512 hash of the entire root filesystem, computed at build time
- Unified Kernel Image (UKI): A single EFI binary containing the kernel, initramfs, and kernel command line with the composefs digest embedded
- Secure Boot signature: The UKI is signed with your private key
At boot time, the composefs digest in the kernel command line (e.g., composefs=<sha512-hash>) is verified against the mounted root filesystem. This creates a chain of trust from firmware to userspace, ensuring the system will only boot if the root filesystem matches exactly what was signed.
Building Sealed Images
Prerequisites
For sealed images, the container must:
- Include a kernel and initramfs in
/usr/lib/modules/<kver>/ - Have systemd-boot available (and NOT have
bootupd) - Not include a pre-built UKI (the build process generates one)
Sealed images also require:
- Secure Boot support in the target system firmware
- A filesystem with fsverity support (e.g., ext4, btrfs) for the root partition
Build Pattern: Compute Digest and Generate UKI in One Stage
The key to building sealed images is using a multi-stage Dockerfile where a separate stage mounts the target rootfs, computes its composefs digest, and generates the signed UKI in one step:
# Build your rootfs with all packages and configuration
FROM <base-image> as rootfs
RUN apt|dnf|zypper install ... && bootc container lint --fatal-warnings
# Generate the sealed UKI in a tools stage
FROM <tools-image> as sealed-uki
RUN --mount=type=bind,from=rootfs,target=/target \
--mount=type=secret,id=secureboot_key \
--mount=type=secret,id=secureboot_cert <<EORUN
set -euo pipefail
# Compute the composefs digest from the mounted rootfs
digest=$(bootc container compute-composefs-digest /target)
# Find the kernel version
kver=$(ls /target/usr/lib/modules)
# Generate and sign the UKI with the digest embedded
ukify build \
--linux "/target/usr/lib/modules/${kver}/vmlinuz" \
--initrd "/target/usr/lib/modules/${kver}/initramfs.img" \
--cmdline "composefs=${digest} rw" \
--os-release "@/target/usr/lib/os-release" \
--signtool sbsign \
--secureboot-private-key /run/secrets/secureboot_key \
--secureboot-certificate /run/secrets/secureboot_cert \
--output "/out/${kver}.efi"
EORUN
# Final image: copy the sealed UKI into place
FROM rootfs
COPY --from=sealed-uki /out/*.efi /boot/EFI/Linux/
This pattern works because:
- The
--mount=type=bind,from=rootfsprovides read-only access to the target filesystem bootc container compute-composefs-digestcomputes the SHA-512 hash of the rootfsukifycreates the UKI with that digest in the kernel command line (composefs=<digest>)- The final stage copies the signed UKI into the rootfs without modifying any files used in the digest calculation
The bootc container compute-composefs-digest Command
bootc container compute-composefs-digest [PATH]
Computes the composefs digest for a filesystem. The digest is a 128-character SHA-512 hex string that uniquely identifies the filesystem contents.
Options:
PATH: Path to the filesystem root (default:/target)--write-dumpfile-to <PATH>: Generate a dumpfile for debugging
Note: This command is currently hidden from
--helpoutput as it's part of the experimental composefs feature set.
Final Image Structure
The sealed image should have:
- The signed UKI at
/boot/EFI/Linux/<kver>.efi - A signed systemd-boot at
/boot/EFI/BOOT/BOOTX64.EFIand/boot/EFI/systemd/systemd-bootx64.efi - The raw
vmlinuzandinitramfs.imgremoved from/usr/lib/modules/<kver>/(they're now embedded in the UKI)
External Signing Workflow
For production environments with dedicated signing infrastructure:
- Build unsigned UKI: Compute digest and create an unsigned UKI (omit
--signtoolfrom ukify) - Sign externally: Take the unsigned UKI to your signing infrastructure
- Complete the seal: Inject the signed UKI into the final image
This workflow is planned for streamlining in future releases (see #1498).
Developing and Testing bootc with composefs
See CONTRIBUTING.md for information on building and testing bootc itself with composefs support.
Bootloader Support
To use sealed images, the container image must have a UKI and systemd-boot installed (and not have bootupd). If these conditions are met, bootc will automatically detect and use the composefs backend during installation.
Installation
There is a --composefs-backend option for bootc install to explicitly select a composefs backend apart from sealed images; this is not as heavily tested yet.
Known Issues
The composefs backend is experimental; on-disk formats are subject to change.
Deployment blockers
- Garbage collection: Old deployments are not cleaned up
- SELinux enforcement: Currently requires
enforcing=0 - OCI registry install: Installing from registry can fail due to config mismatch
Important
- Sealed image build UX: Streamlined tooling for building sealed images
- kargs.d: Custom kernel arguments from
/usr/lib/bootc/kargs.dnot yet included in sealed UKIs
Long-term
Additional Resources
- See filesystem.md for information about composefs in the standard ostree backend
- See bootloaders.md for bootloader configuration details
- composefs-rs - The underlying composefs implementation
- Unified Kernel Images specification
- ukify documentation - Tool for building UKIs
The Linux Foundation® (TLF) has registered trademarks and uses trademarks. For a list of TLF trademarks, see Trademark Usage.