Skip to content
andrew.dunn.dev

Cairn

Site Group base pipeline whetstone

immutable answered whether a homelab OS could be built like software: FROM-scratch bootc images, source-built kernel modules, every byte traceable to a source we control. The trust chain at boot stayed borrowed, though. shim trusts Microsoft’s keys, GRUB reads a config nothing measures, and module trust hangs off a MOK enrollment. Cairn is the successor estate that owns that chain end to end.

BORROWED TRUSTimmutableOWNED TRUSTcairnPRE-BOOTshim to GRUBvendor keys, config unmeasuredMODULESMOK enrollmenttrust enrolled by handBOOTsigned UKIestate db keysROOTcomposefsdigest pinnedUNLOCKTPM2signed PCR11
Cairn replaces the borrowed shim, GRUB and MOK boot chain with one the estate owns: a db-signed UKI, a composefs-pinned root, and a TPM2 unlock bound to signed PCR11.

A cairn image boots as a db-signed UKI via systemd-boot; there is no shim and no GRUB. The Secure Boot keys are minted in an offline ceremony and enrolled alongside the platform’s existing keys, with fingerprints published at cairn.dunn.dev. The root filesystem is pinned by a composefs digest carried on the measured kernel command line, and the TPM2 releases the LUKS key only when a signed PCR11 policy matches the UKI that actually booted.

Promotion is earned the way it was in immutable, with the bar moved up: :stable-sealed moves only after the exact candidate completes a real boot in a nested-KVM CI gate, under enforcing Secure Boot with the estate’s own db, and its measured PCR11 value matches the anchor committed in git. A red gate freezes the whole estate. The hosts here still run immutable‘s basef, not a sealed cairn image: the CI gate proves the chain in a VM, not on the estate’s own metal.

The estate

candidatepromotesforkpipelineCI component catalogbaseFROM-scratch Fedora bootcUKI · composefs · ZFS · NVIDIAinstancesPrivate host imagesRebuilt by the cascadewhetstoneRunner imagesDecision logsealed gatesCI boot under enforcing SBPCR11 anchorexamplesFour forkable postures
Pipeline components and whetstone runner images feed base, which promotes to the private host instances only after a candidate passes the sealed gates, and the example repos are the postures you fork to start one.

base builds the OS layer: FROM-scratch Fedora bootc images with source-built ZFS and NVIDIA kernel modules, composed into variants that instances layer on. It also carries the boot-gate harness the whole estate reuses.

pipeline is the GitLab CI/CD component catalog: image build and promotion, the seal lane, supply-chain jobs, and validation, consumed by every repo in the group at pinned releases.

whetstone builds the runner VM golden images: the estate’s CI executors run the estate’s own OS, built to qcow2 from base. Its docs also carry the estate’s running decision log, where every load-bearing choice (why no shim, why composefs, why the keys enroll additively, why promotion requires a real boot) is a numbered decision with its reasoning and its receipts.

site publishes the estate documentation and the ceremony key fingerprints at cairn.dunn.dev.

The examples (plain, attended, edge, evidence) are forkable instance postures, from open verified boot up to fully sealed with evidence collection. Fork the posture that matches your threat model and point it at base.

The private repos in the estate are the host instances, plus lab, which holds trust-chain experiments and their receipts. Everything that explains how the estate works is public; the private repos hold what identifies the machines or hasn’t left the lab yet.

Enrollment is additive, not a swap: adding the estate’s PK, KEK, and db alongside the platform’s existing keys means firmware and option ROMs keep verifying while cairn’s own images verify under their own db too. When base promotes a new :stable, CI triggers a rebuild of every instance automatically, authenticated by the job’s own ephemeral token against an allowlist so no standing credential exists anywhere in the chain, and a red gate in base holds the cascade before it starts.

From immutable to cairn

What carried over: the FROM-scratch discipline, source-built and signed kernel modules, an SBOM per image, and the conviction that a tag is earned by a boot, not a build. What changed: shim, GRUB, and MOK gave way to the estate’s own db keys, systemd-boot, and UKIs; a validated image became a sealed one; and one base with one instance became an estate, with variants, a cascade, forkable example postures, and a public decision log. The immutable estate stays published as the reference it grew into.