The 'securecore-kinoite-hardened-userns' image we'd been targeting does not exist in the secureblue org's package list. Their KDE Plasma (Kinoite) hardened variant is published as 'kinoite-main-hardened' (or 'kinoite-nvidia-hardened' for NV boxes). Switch the recipe + all doc references.
18 KiB
Roadmap
Versioned roadmap for veilor-os. Targets are intentionally short and testable. No fluff. Items in earlier versions are blockers for later ones unless explicitly noted.
For the historical record of what landed in each release, see
../CHANGELOG.md.
⚡ STRATEGY PIVOT — 2026-05-06
Decision: skip v0.6 kickstart polish. Pivot directly to v0.7 BlueBuild OCI path.
Reasons:
- v0.5.32 produced a green ISO (2.7 GB) on the Forgejo runner. Proof point achieved.
- Continuing to debug
livecd-creator+anacondaquirks for v0.6 polish is sunk-cost work on tooling we retire at v1.0 anyway. - v0.7 spike already has a working BlueBuild recipe +
ostreecontainerkickstart directive. Layering veilor branding + installer + power CLI on top of secureblue beats re-deriving the same hardening from scratch. - Ergonomic CLI tools (
veilor-postinstall,veilor-doctor,veilor-update) translate cleanly to v0.7:bootc upgradereplacesdnf upgrade. Move them into v0.7 scope.
v0.5.0 is the final kickstart-path release. Tag, freeze, ship as proof-of-work / portfolio anchor. v0.6 cancelled as a milestone.
Active focus: v0.7-bluebuild-spike branch.
Lessons learned through v0.5.x install grind
Five things v0.5.27–31 changed about how we plan:
- Anaconda + RPM-6.0 +
--cmdlineis brittle — three install failures, kernel cmdline written to four places before one worked.--location=noneskipsCollectKernelArgumentsTask,kernel-installreads/etc/kernel/cmdlinenot/proc/cmdline, andtransaction_progress.pymasks real failures if patched too broadly. Justifies promoting the bootc-image-builder spike to v0.7. - Test procedure must gate every tag — v0.5.27 only surfaced four
bugs in one VM run because the run walked every step in order.
test/TESTING.mdandtest/test-runs/are now load-bearing. - Real hardware is not optional — VM catches install logic, not KMS / fbcon / firmware. Spare laptop + friend's laptop must run pre-tag, every time.
- Multi-agent debug waves work, but only with a verifier — the v0.5.31 four-bug fix came from a 4-agent verification wave on v0.5.30 outcome. Wave + verifier = signal; wave alone = noise.
- "We ask once, with sane defaults" is the distro UX — every
v0.5 install bug we shipped a workaround for (locale, hostname,
USBGuard policy, drivers) is something
veilor-postinstallcould ask the user about cleanly on first boot. That promotesveilor-postinstallfrom v0.6 background item to flagship.
v0.2 — green ISO + base hardening (DONE)
Reproducible CI build pipeline. UEFI+BIOS bootable live ISO from a single
kickstart. Single-prompt LUKS install. First-boot admin password flow.
Full overlay applied (sysctl, sshd, sudoers, tuned profiles, KDE black
theme, Fira Code, branded /etc/os-release). SELinux enforcing.
firewalld drop zone. fail2ban + auditd + USBGuard active. The build
chased five real bugs (DEST hardcoded, set -eu killing cp,
os-release symlink, missing admin user, LABEL= vs CDLABEL= in
livecd-tools) before greening.
Released v0.2.5 on 2026-05-01. CI on every push to main.
v0.5.27–v0.5.31 — install path stabilisation (DONE)
The bridge between v0.2 (greens at all) and v0.3 (looks polished). All
install-path bugs surfaced by the formal hybrid-VM test procedure
(test/TESTING.md). Five releases, ~hours of debug, three install
failures before greening.
- v0.5.27 (DONE) —
rd.luks.uuidviagrubby --update-kernel=ALL, GRUB rebrand,fbcon=nodefer, ASCII gum cursor. - v0.5.28 (DONE) — locale locked en_US.UTF-8, dropped updates repo,
patched anaconda
transaction_progress.pyto silenceConfiguring xxx.x86_64scroll, excluded man-db. - v0.5.29 (DONE) — narrowed anaconda patch (was masking real failures), LUKS UX, initramfs assertion. Five-fix bundle from 7-agent research wave.
- v0.5.30 (DONE) — broad error suppression, manual bootloader path, virtio log capture for post-mortem.
- v0.5.31 (DONE) —
--location=nonewas making anaconda skipCollectKernelArgumentsTask; kernel-install reads/etc/kernel/cmdlineas source of truth, veilor never wrote it, so BLS entries shipped with empty cmdline. Three-path write (/etc/kernel/cmdline+/etc/default/grub+ grubby) plus explicitkernel-install add.
v0.5.32 — next ship (active)
Outstanding from the grind, immediate priority for the next tag:
- End-to-end VM green run — v0.5.31 lands the kernel-cmdline fix
but no full hybrid-VM pass has signed it off. Run the procedure in
test/TESTING.mdto install + reboot + login, file the report intest/test-runs/, then tag. - Real-hardware run on the spare laptop — VM is necessary not sufficient. Friend's laptop is mate's-test, spare is ours. KMS, fbcon, USB controller, real-firmware Secure Boot only show up here.
- gum input render glitch — duplicate "Install", stray T in
password fields on linux fbcon. Replace
gum input --passwordwith bashread -srp; cosmetic only but visible on every install.
v0.3 — UX polish (in progress)
The visible polish layer that v0.2 deferred for build velocity.
- Plymouth black theme — boot splash matching the desktop. No Fedora
drum, no white flash.
assets/plymouth/veilor/. - SDDM theme — black login background, single-user prompt with
adminpre-filled, no userlist. - Konsole profile — black background, Fira Code, transparent panel off (no compositor cost on resume).
- Wallpaper SVG — flat black with subtle veilor wordmark, 1080p + 4K + ultrawide variants.
- Re-enable memory hygiene on installed system. v0.2.5 stripped
init_on_alloc=1 init_on_free=1from the live cmdline because they 5x'd KVM boot time. Re-add post-install viaveilor-firstbootso the installed system gets the protection without the ISO penalty. - USBGuard auto-snapshot on first boot. Currently the operator
runs
usbguard generate-policymanually. v0.3 wires this intoveilor-firstbootafter the password step (with a clear "plug in trusted devices first" prompt).
Target: this month. None of it is a kickstart change — pure overlay work.
v0.4 — distribution + signing
Get veilor-os to a state where the ISO is downloadable, verifiable, and trusted by Secure Boot without user shenanigans.
- GPG-signed releases. Tag → CI builds → CI signs ISO + sha256 with
veilor.org release key → GitHub Release artifact carries
.iso.asc. - Reproducible builds. Pin Fedora compose ID, lock package versions
via
dnf snapshotor equivalent, document how to verify two builds match. - Own MOK (Machine Owner Key) + sbsign for Secure Boot. Currently veilor-os relies on Fedora's signed shim chain. v0.4 ships our own MOK, signs the kernel + initramfs at build time, optionally enrols the MOK on first boot for users who want a cleaner trust path.
- ISO download mirror — static download page on veilor.org with current + previous release, sha256, gpg signature. Not an RPM mirror — veilor-os does not ship its own packages, only the spin configuration.
- Release process documented — tagging, CI, signing, mirror sync
in
docs/RELEASE.md.
v0.5 — hardening tier 2
Hardening that builds on v0.2's foundation. Each item is opt-in unless specified — defaults stay sane for a daily driver.
- AppArmor profiles in addition to SELinux. Stack-not-replace. Targeted at the browser, the mail client, and anything that touches attacker-controlled data. SELinux remains the primary MAC.
- systemd-homed — encrypted-per-user
~, suspend-aware, key unlocked at PAM login. Optional, opt-in via post-install helper. - nftables ruleset alongside firewalld defaults. Default firewalld policy stays drop; nftables provides advanced filtering for users who want it.
- Audit log shipping — opt-in
auditd-> remote syslog over TLS, for users running a central log aggregator. - Installer kickstart split — separate
veilor-os-install.ksfor installer ISO (real LUKS partitioning, not the live-rootfs simplification used in v0.2). Lets users install veilor-os as the primary OS without going through the live boot first. - Audit baseline — re-run the security audit (template in
security/audit-template.md) and target a lower risk score than v0.2.
v0.6 — CANCELLED 2026-05-06 (folded into v0.7)
Per the strategy pivot at the top of this file: v0.6 kickstart polish
will not ship. Continuing on the kickstart path means more
livecd-creator + anaconda debugging on tooling that's retired at v1.0.
The flagship v0.6 deliverables (veilor-postinstall, veilor-doctor,
veilor-update, opt-in installer ISO, first-boot Plymouth dialog,
Bluetooth helper) move into v0.7 scope with bootc upgrade
replacing dnf upgrade in the update path.
The original v0.6 plan is preserved below for reference but is not the active roadmap.
v0.6 — ergonomics (HISTORICAL — superseded by v0.7)
Smooth the operator experience so day-to-day work doesn't fight the
hardening. veilor-postinstall and veilor-doctor were v0.6 background
items — promoted to headline features after v0.5.27–31 made it
clear that "we ask once, with sane defaults" is what separates a
distro from a kickstart.
veilor-postinstall(PROMOTED — flagship of v0.6) — first-login welcome menu, EndeavourOS-style but cleaner. Single TUI screen: keyboard layout, locale (deferred from install per v0.5.28), hostname override, package presets (dev / media / homelab), drivers (NVIDIA / Intel / AMD), Bluetooth opt-in, USBGuard snapshot, audit baseline run,veilor-doctorfirst run. Each step skippable, runs once on first SDDM login, self-deletes the autostart after. This is the only UX feature that ships in v0.6 day one — everything else builds on it.veilor-doctor(PROMOTED — user-facing, not just dev tool) — the post-install audit. Walksgetenforce,mokutil --sb-state,firewall-cmd, fail2ban, USBGuard policy, sysctl drift, and reports drift from baseline. Runs fromveilor-postinstallon day one, then weekly viasystemd --usertimer. Plain-English output ("your firewall is OK", "USBGuard policy has 3 unknown devices"); not a JSON dump. Stretch: machine-readable mode forveilor-serverlater.veilor-update— wrapsdnf upgradeANDflatpak updatein one command. Perfeedback_system_update.md, partial-update is a recurring trap; veilor's update tool covers both by default. Adds pre-check (snapshot available?), auditd pause, post-update SELinux validation.- Opt-in installer ISO — flip from live-only to live + installer, user picks at boot menu. Installer uses the v0.5 kickstart with full LUKS + btrfs subvols + zram.
- First-boot UX — replace TTY password prompt with a small Plymouth-rendered dialog. Less raw.
- Bluetooth opt-in helper — single command to enable + bring up the daemon + add the user to the right group.
v0.7 — BlueBuild OCI mainline (ACTIVE — primary focus 2026-05-06+)
This was originally planned as "public flex + bootc spike". Post-pivot, v0.7 is now the primary active milestone — it absorbs all v0.6 ergonomic work and becomes the next ship target.
Scope:
- BlueBuild recipe (
bluebuild/recipe.yml) layering onghcr.io/secureblue/kinoite-main-hardened kickstart/install-ostreecontainer.ks— 10-line kickstart that callsostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registryand lets Anaconda's LUKS UX drive the install- veilor brand layer: KDE black theme, gum installer assets, custom
Konsole profile, branded
os-release veilor-power3-mode CLI (lifted as-is from v0.5.x overlay)veilor-postinstall(formerly v0.6 flagship) — first-login TUIveilor-doctor(formerly v0.6) — boot-time + weekly drift checkveilor-updaterewritten onbootc upgrade(wasdnf upgrade)- Forgejo registry as primary OCI publish target; GHCR mirror optional
- cosign key-pair signing of OCI image (replaces broken keyless flow)
Public-flex items kept from original v0.7 entry:
Take veilor-os out of "private repo, contained audience" mode. Order matters: people demand threat model FIRST when a security distro goes public, benchmarks come after.
- Threat model published (FIRST — gating item) — what veilor-os defends against, what it does not. Honest scope. No claim of anti-state-actor; concrete on lost-laptop, USB-attack, browser compromise, supply-chain. Reviewers will demand this before reading anything else.
- Public docs site — Hugo or mdBook on
veilor.org, generated fromdocs/. Single source of truth. - Repo public — flip GitHub visibility, announce.
- Comparison + benchmarks — published numbers vs stock Fedora KDE on cold boot, idle RAM, idle network egress, suspend/resume time. After threat model, not before.
- Press kit — wallpapers, logo, screenshots, feature one-liner.
Hybrid bootc spike — layer on secureblue, install via ostreecontainer (REVISED 2026-05-05)
The original v0.7 entry called for a Containerfile-from-scratch
spike on quay.io/fedora/fedora-bootc:43. Research on 2026-05-05
(see docs/STRATEGY.md and
docs/research/2026-05-05-agent-wave/), then a parent-operator
refinement same day, locked the path: layer veilor's branding +
threat model + UX on top of secureblue's already-shipping
kinoite-main-hardened OCI image via a BlueBuild
recipe, and install it directly during the Anaconda pass via the
ostreecontainer kickstart directive (no first-boot rebase).
Reasoning:
- secureblue has 30 active contributors, 940 stars, 56 commits in the last 5 weeks. They've already implemented the hardening surface we'd need to build alone (sysctl + kargs + SELinux custom policy + USBGuard + hardened-malloc + Unbound DoT + cosign-signed OCI build pipeline).
- Containerfile-from-scratch spike: 1 week to first ISO. BlueBuild
recipe extending secureblue: ~2 days. With the
ostreecontainerswap (noveilor-firstboot-rebase.service, no transition window): ~1 day. - secureblue does NOT publish a threat model. Athena OS does
(their main differentiator, only public threat model in
hardened-Linux 2026). Our
docs/THREAT-MODEL.md(drafted) gets us ahead of both on the one axis that matters most for a security-branded distro.
Hybrid path locked:
- Kickstart ISO stays as the bootstrap installer (Anaconda's LUKS UX is mature).
%packagesis replaced withostreecontainer --url=ghcr.io/veilor/veilor-os:43 --transport=registryso the install pass populates/directly from the OCI image — no first-boot rebase, no second reboot.- From boot one onward,
bootc upgradeis the update channel. - v1.0 deprecates the kickstart entirely.
Stay on ostreecontainer through v0.8. Do NOT migrate to the new
bootc kickstart command until v1.0 — it blocks multi-disk and
authenticated registries (likely needed eventually). Do NOT use
bootc-image-builder anaconda-iso output — deprecated in
image-builder v44+. Produce OCI image and bootstrap ISO as
separate artifacts.
Overrides over secureblue: keep Trivalent as default (their COPR
tracks upstream M147+ within hours; reverses earlier draft that
treated it as override-and-remove); add Mullvad Browser alongside;
gate Thorium behind ujust install-thorium with CVE-lag warning;
restore sudo (revert run0-only); re-enable Xwayland.
Mesh stack baked in: Tailscale (Day 1, daily driver), Yggdrasil-go
(Day 1, idle warm-fallback), Reticulum/RetiNet AGPL fork (opt-in
via ujust install-reticulum). See docs/STRATEGY.md mesh stack
section for the layer breakdown and threat-floor table.
Full plan: docs/STRATEGY.md. Spike will land in
bluebuild/recipe.yml plus .github/workflows/build-bluebuild.yml,
on a separate branch — does NOT land in v0.5.x main.
External dependency tracked: Traefik no-guest@file ACL on
nullstone is currently an 0.0.0.0/0 allow-all stub. Must be
fixed before veilor-os first-public-ISO ships, otherwise
tag:guest provisioning leaks the full vhost surface to every
veilor user. Parent operator owns the fix; not in veilor-os
scope.
v1.0 — production
The line where veilor-os is recommended for a non-author user as a daily driver.
- Multi-arch. x86_64 today; v1.0 ships aarch64 ISO too (laptops on ARM are real now). Build matrix in CI.
- LTS commitment — major versions tied to Fedora's release cadence, patch releases for security only, documented EOL per major.
- Recovery ISO — minimal rescue image with veilor tools (LUKS unlock, btrfs scrub, sysctl reset, fail2ban unban) for "I cannot log in to my system" days.
- TPM2 integration — sealed LUKS unlock against TPM2 PCRs (opt-in, default stays password). Ships as helper script, not silent default.
- Signed update channel — beyond GPG-signed ISOs, a signed metadata
repo so
veilor-doctorcan detect available updates without trusting Fedora's mirrorlists alone.
Stretch goals — not on the v0.x → v1.0 critical path
These are spin variants that share veilor-os DNA but need their own kickstart or build tool.
veilor-server— no KDE, no GUI, hardened headless Fedora for homelab / VPS (e.g. nullstone). Same overlay, different package set. Not blocked, but waits onveilor-doctormachine-readable mode (v0.6) so headless installs have a way to report drift without a TUI.veilor-kiosk— single-app Plasma session, locked-down user, read-only root. Not blocked.veilor-atomic— rpm-ostree / bootc-image-builder rebase. Status now depends on the v0.7 bootc spike: if the spike shows bootc fixes the anaconda-grind class of bugs,veilor-atomicbecomes the v1.0+ mainline rather than a stretch variant. If not, it stays a parallel track.