FIDO2-first immutable OS — YubiKey is the root of trust
No TPM. No OEM. No trust anchors you don't control.
yubiOS fuses four lineages:
| Layer | Inspiration | What it gives us |
|---|---|---|
| particleos ethos | systemd/particleos | Immutable rootfs, UKI, dm-verity, composefs, systemd-boot |
| bootc design | bootc-dev/bootc | OCI image as OS delivery unit, day-2 upgrades via registry pull |
| Amutable vision | Lennart Poettering + systemd team | "Integrity should be built into every critical infrastructure project" — image-based OS, verifiable integrity, determinism as a default |
| YubiKey root of trust | FIDO2 / PIV / OATH | Hardware-bound trust replacing TPM at every boundary |
In January 2026 the core systemd team and the engineers behind, composefs, runc, Flatcar, ParticleOS, and Ubuntu Core — founded Amutable with the mission:
“Deliver determinism and verifiable integrity to Linux workloads everywhere.”
yubiOS is independently building toward the same architecture, with one additional constraint: the YubiKey replaces the TPM as the hardware root of trust at every layer. The "Fitting Everything Together" essay at 0pointer.net is the primary design reference for yubiOS — hermetic /usr, DPS partitions, systemd-repart first-boot, A/B sysupdate, systemd-homed per-user encryption, and UKI + dm-verity trust chain.
┌───────────────────────────────────────────┐
│ YubiKey 5 │
├───────────────────────────────────────────┤
│ PIV slot 9c (CCID) Secure Boot signing │
│ FIDO2 HMAC-secret Disk unlock (hidraw) │
│ FIDO2 ed25519-sk SSH keys (hidraw) │
│ FIDO2 U2F sudo/login (hidraw) │
│ OATH TOTP App 2FA (hidraw) │
└───────────────────────────────────────────┘
ADR-002 note: Secure Boot signing uses PIV/CCID (via
systemd-sbsign+ PKCS#11), not hidraw. All other operations run on FIDO2 via/dev/hidraw*. Full rationale: ADR.md
yubiOS ships as a multi-arch bootc OCI image on Docker Hub — this is the primary download.
Pull (auto-selects amd64 / arm64):
docker pull 0mniteck/yubios:latestPin by digest (reproducible — recommended for installs):
docker pull 0mniteck/yubios@sha256:c965a816b9173cf6f227e6b5b09e321e841ab5f8a49075c112657a0a40b5e761Install / upgrade with bootc:
sudo bootc install to-disk --source-imgref docker://0mniteck/yubios:latest /dev/nvme0n1
sudo bootc switch 0mniteck/yubios:latest && sudo bootc upgrade| Registry | docker.io/0mniteck/yubios |
| Tags | :latest + immutable :<commit-sha> per build |
| Platforms | linux/amd64, linux/arm64 |
| Supply chain | SLSA build provenance + SBOM attestations attached |
| Published by | yubiOS-ci.yml merge-manifest job (current: run #113, bfbc38f) |
Building from source instead? See Quick start below.
# Build the OCI image (per ADR-014: Docker Buildx, not Podman)
docker buildx build --policy reset=true,strict=true,filename=yubiOS.rego -t yubiOS .
# Install to disk (disable Secure Boot in UEFI first)
docker run --rm --privileged --pid=host \
-v /dev:/dev -v /var/lib/containers:/var/lib/containers \
yubiOS bootc install to-disk /dev/nvme0n1
# First boot: the enrollment wizard runs automatically
# Or launch it manually:
yubiOS-enrollOn first boot yubiOS-enroll.service fires on tty1 and walks through:
─── Step 1/4: Secure Boot Signing ───
─── Step 2/4: Disk Encryption (FIDO2 hidraw) ───
─── Step 3/4: SSH Key (ed25519-sk resident) ───
─── Step 4/4: sudo / Login Auth (U2F pam-u2f) ───
Each step is skippable. Each script is independently re-runnable. See ONBOARDING.md.
yubiOS/
├── .github/workflows/ # CI: main build, ARM64 fTPM integration lanes, dhi manifest fetch
│ ├── yubiOS-ci.yml # primary build+test+publish pipeline (merge-manifest -> Docker Hub)
│ ├── ci_test-vm.yml # bcvk VM test suite (swtpm, swu2f)
│ ├── ci_test-int.yml # ARM64 secure-world integration orchestrator
│ ├── ci_int_stmm.yml # StandaloneMM (F1) lane
│ ├── ci_int_optee_fip.yml # OP-TEE + TF-A FIP fold (F2) lane
│ ├── ci_int_qemu.yml # QEMU e2e (F4) lane
│ └── fetch-dhi-manifest.yml # resolves dhi.io/debian-base INDEX digest
├── assets/
│ ├── logo.png # you're looking at it
│ └── ci/vm-swtpm.conf # swtpm drop-in for bcvk CI VMs
├── mkosi.conf # mkosi build (particleos-style UKI + verity)
├── mkosi.conf.d/
│ ├── desktop/mkosi.conf # GNOME desktop profile
│ ├── minimal/mkosi.conf # minimal profile
│ ├── surface-x86/mkosi.conf # Surface x86 profile
│ ├── surface-arm64/mkosi.conf # Surface ARM64 profile
│ └── test/ # TEST-only profile: swu2f in-guest CTAP2 authenticator
│ ├── mkosi.conf
│ └── install-swu2f-authenticator.sh
├── Containerfile # OCI image (bootc, Fedora base)
├── yubiOS.rego # OPA/Rego supply-chain Build Policy
├── renovate.json # digest-tracking automation (ADR-015)
├── refs/ # per-PR test/implementation specs
│ ├── v261-base-image.md
│ ├── sbsign-pkcs11-validate.md
│ ├── luks-fido2-e2e-test.md
│ ├── bcvk-swtpm-ci.md
│ └── arm64-ftpm-phase-f0.md
├── tests/
│ ├── unit/ # bats unit tests (enroll-*, pam-u2f stack, lib)
│ ├── fixtures/ # lsblk fixtures for LUKS detection tests
│ ├── vm/ # bcvk VM test scripts (LUKS2 e2e, TPM PCR verify, ARM64 fTPM QEMU)
│ ├── validate-pkcs11-uri.sh # PKCS#11 URI validation for PIV slot 9c
│ └── verify-uki-signature.sh # UKI signature verification
├── usr/lib/
│ ├── bootc/install/ # bootc install config (systemd-boot, DPS)
│ ├── bootc/kargs.d/ # persistent kernel args
│ ├── dracut.conf.d/ # fido2 + composefs dracut modules for boot-time unlock
│ ├── udev/rules.d/ # YubiKey hidraw + CCID uaccess rules
│ ├── pam.d/ # PAM U2F sudo + system-auth config
│ ├── repart/ # systemd-repart first-boot partition definitions
│ ├── systemd/system/ # enrollment service unit
│ ├── systemd/system-preset/ # enrollment service preset
│ ├── systemd/homed.conf.d/ # homed FIDO2 defaults
│ └── yubiOS/ # enrollment scripts (sb, luks, homed, ssh, pam, totp, gpg, largeblob, backup) + lib.sh
├── ADR.md # architecture decision records
├── ARCHITECTURE.md # trust chain + build pipeline diagrams
├── SPEC.md # consolidated architecture + use-case specification
├── MISSION.md # project mission
├── MITIGATE.md # attack-surface -> control mapping (Faux Phy threat model)
├── FUTURE.md # post-launch ARM64-owned root of trust plan
├── ONBOARDING.md # step-by-step onboarding guide
├── PINNED.md # single source of truth for pinned digests/SHAs
├── BLOCKERS.md # open issue dependency map
├── TODO.md # known gaps + future work
├── AGENTS.md # guidance for AI coding agents working on this org
├── MAINTAINER.md # maintainer contact
└── CITATION.md # citation + primary-source references
| Minimum | |
|---|---|
| YubiKey firmware | 5.2.3 (ed25519-sk) |
| systemd | 261 (systemd-sbsign, systemd-cryptenroll FIDO2; v261 adds ConditionSecurity=measured-os, RestrictFileSystems=) |
| OpenSSH | 8.2 (FIDO2 key types) |
| pam-u2f | 1.3.1 (CVE-2025-23013 fix) |
| Platform | x86-64 (primary); arm64/aarch64 (in development — see ADR-017) |
graph TD
BASE["quay.io/fedora/fedora-bootc:45\n@sha256 (pinned base — ADR-015)\ndigest in PINNED.md"]
CF["Containerfile\nrootless docker buildx\n--policy yubiOS.rego\n(supply-chain gate)"]
MKOSI["mkosi --profile yubios\nUKI + dm-verity, signed via\nYubiKey PIV slot 9c (PKCS#11)"]
OCI["multi-arch OCI image\nlinux/amd64 + linux/arm64"]
CI["yubiOS-ci.yml . merge-manifest\nSLSA provenance + SBOM attested"]
REG["docker.io/0mniteck/yubios:latest\n+ immutable :<commit-sha> per build"]
INSTALL["bootc install to-disk\n(bare metal)"]
UPGRADE["bootc switch + upgrade\nday-2 atomic update"]
BCVK["bcvk\nephemeral VM / native-to-disk\n(test loop, USB YubiKey passthrough)"]
ENROLL["first boot\nyubiOS-enroll.service\nYubiKey tap"]
PIV["PIV slot 9c (CCID)\nSecure Boot signing\n(systemd-sbsign / PKCS#11)"]
FIDO["FIDO2 (hidraw)\nLUKS2 disk unlock\nSSH ed25519-sk, pam-u2f"]
HOMED["systemd-homed\nLUKS2 /home\nSLOT 0 FIDO2 unlock\nSLOT 1 recovery key"]
BASE --> CF
BASE --> MKOSI
CF --> OCI
MKOSI --> OCI
OCI --> CI
CI -->|docker push| REG
REG -->|pull| INSTALL
REG -->|pull| UPGRADE
REG -->|pull| BCVK
INSTALL --> ENROLL
ENROLL --> PIV
ENROLL --> FIDO
ENROLL --> HOMED
style REG fill:#ff1493,color:#fff
style ENROLL fill:#ff1493,color:#fff
style PIV fill:#0d6e0d,color:#fff
style FIDO fill:#0d6e0d,color:#fff
style HOMED fill:#0d6e0d,color:#fff
style CI fill:#8b4513,color:#fff
All decisions are recorded in ADR.md with sources. The short version: TPM replaced by YubiKey everywhere it can be.