veilor-os/README.md
veilor-org 21c0bbd120 docs: refine strategy — ostreecontainer install + mesh stack + browser stack
Refines docs/STRATEGY.md per parent-operator handoff (2026-05-05).
Locks in five things the original draft didn't cover, and corrects
one mistake.

## Refinement: ostreecontainer install path

The original draft proposed a two-step install: Anaconda partitions
+ kickstart, then on first boot a `veilor-firstboot-rebase.service`
runs `bootc rebase ghcr.io/veilor/veilor-os:43`. This commit drops
that step.

Anaconda's `ostreecontainer --url=... --transport=registry`
directive populates the root filesystem directly from the OCI image
during the install pass. No first-boot rebase, no transition
window, no second reboot. Same end state, simpler path.

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. Do NOT use `bootc-image-builder
anaconda-iso` output — deprecated in image-builder v44+. Produce
the OCI image and the bootstrap ISO as separate artifacts.

This compresses the v0.7 BlueBuild spike from 2 days → 1 day.

## Correction: keep Trivalent as default

The original strategy.md treated Trivalent (secureblue's hardened
Chromium) as an override-and-remove. That was wrong: Trivalent's
COPR tracks upstream M147+ within hours, ships hardened_malloc +
JIT-less + Drumbrake WASM. Default browser pick.

Mullvad Browser layered alongside for anti-fingerprint. Thorium
remains opt-in via `ujust install-thorium` only — its CVE lag is
months and contradicts the threat model. Never default.

## Mesh stack baked in

Three-layer warm-stack documented in STRATEGY.md:
- L3a Tailscale + Headscale (Day 1, daily driver)
- L3b Yggdrasil-go (Day 1, idle warm-fallback, AllowedPublicKeys mode)
- L3c Reticulum/RetiNet AGPL fork (opt-in via ujust install-reticulum)

Threat floor table: ISP-DNS-block (i, Day 1), ISP-Tailscale-block
(ii, Phase 2 promote Yggdrasil), internet-down (iii, opt-in RetiNet
+ RNode).

Tier model: tag:admin / tag:infra / tag:guest with failsafe pre-auth
key on yubikey + paper + Authentik OIDC group.

## Onboarding

Token paste / QR (user picks). Misskey signup mints reusable
24h-TTL pre-auth key. NOT auto-OIDC at first boot.

## Iroh seeding daemon stub (v0.8 / Phase 2)

`veilor-seed.service` documented but NOT implemented until Iroh hits
1.0 (current 0.96–0.98 RC, Q1 2026 target slipped). BLAKE3 +
iroh-gossip per-service topic. Static media only — DEFER DB
replication forever.

## External dependency tracked

nullstone Traefik `no-guest@file` ACL is currently 0.0.0.0/0
allow-all (XFF chain breakage 2026-05-03). 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; explicitly out of veilor-os scope.

## Files

- docs/STRATEGY.md — full refinement
- docs/ROADMAP.md — v0.7 spike entry now reflects ostreecontainer
  + mesh stack + 1-day spike target
- README.md — drops the "v0.2.5 pre-release" badge + status box
  (out of date), adds bootc/atomic trajectory paragraph

## What did NOT change

- v0.5.x main branch is untouched. The ostreecontainer swap belongs
  in the v0.7 spike branch, NOT v0.5.32.
- nullstone Traefik config is untouched. Out of scope.
- The kickstart and overlay code is untouched.
2026-05-05 15:15:52 +01:00

163 lines
7.5 KiB
Markdown

# veilor-os
> **Hardened minimal Fedora KDE spin. Black-on-black. Locked down by default.**
[![Build veilor-os ISO](https://github.com/veilor-org/veilor-os/actions/workflows/build-iso.yml/badge.svg)](https://github.com/veilor-org/veilor-os/actions/workflows/build-iso.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
veilor-os is a Fedora 43 KDE Plasma remix for operators who want a clean,
fast, opinionated desktop with serious hardening already wired in. Boot the
ISO, set an admin password, work. No installer wizard. No initial-setup
screen. No telemetry. No "would you like to enable X" prompts.
The current install path is an Anaconda kickstart with a custom gum TUI
on top. v0.7+ ships a hybrid path: the kickstart ISO becomes the bootstrap
installer (Anaconda's LUKS UX is mature), but the root filesystem is
populated directly from a cosign-signed bootc OCI image built via BlueBuild
on top of [secureblue](https://github.com/secureblue/secureblue)'s
hardened Kinoite variant. Updates from there flow through `bootc upgrade`
— atomic A/B, instant rollback. v1.0 is bootc-only.
See [docs/STRATEGY.md](docs/STRATEGY.md) for the full trajectory.
---
## Status
Active development on the install path. Three bug classes have been
worked through (LUKS unlock cmdline, anaconda RPM-6.0 cmdline-mode
brittleness, bootloader install via `gen_grub_cfgstub`); current focus
is the v0.5.32 blocker list from the
[2026-05-05 9-agent research wave](docs/research/2026-05-05-agent-wave/README.md).
What is **shipping**: hardening (SELinux, sysctl, USBGuard, fail2ban,
firewalld), KDE black theme, Fira Code system font, 3-mode power
management, single-prompt LUKS install, first-boot admin password flow,
reproducible CI build, EFI+BIOS bootable live ISO.
What is **planned** (see [docs/ROADMAP.md](docs/ROADMAP.md)): Plymouth
+ SDDM polish, signed ISOs (own MOK + GPG, sigstore/cosign on OCI),
AppArmor + nftables stack, `veilor-update` / `veilor-doctor` /
`veilor-postinstall` helpers, public docs site, **bootc OCI hybrid
spike at v0.7**, **bootc-only at v1.0**.
---
## Quick install
```bash
# 1. Download the ISO (after public release; CI artifact for now)
sha256sum -c veilor-os-43-*.iso.sha256
# 2. Flash to USB. Replace /dev/sdX with your USB device — triple-check.
sudo dd if=veilor-os-43-*.iso of=/dev/sdX bs=4M status=progress conv=fsync
sync
# 3. Boot from USB, pick "Install veilor-os" from the menu.
# 4. Set a strong LUKS passphrase — the only prompt during install.
# 5. Reboot, remove USB.
# 6. On first boot: TTY prompts for an admin password (≥14 chars, mixed case,
# digit, symbol). Once accepted, SDDM starts. Log in as `admin`.
```
Full install + first-boot walkthrough: [docs/INSTALL.md](docs/INSTALL.md).
---
## What veilor-os ships
| Layer | Hardening |
|-------|-----------|
| Boot | Secure Boot, `lockdown=integrity`, `slab_nomerge`, `randomize_kstack_offset=on`, `vsyscall=none`. LUKS2 (aes-xts-plain64, argon2id, mem=1GB). zram swap (no disk swap, no cold-boot leak). |
| Kernel | Locked sysctls: ptrace=2, kptr_restrict=2, dmesg_restrict=1, perf_event_paranoid=3, BPF JIT hardening, full ASLR, no SUID core dumps. |
| MAC | SELinux **enforcing**, targeted policy + custom `veilor-systemd` module. |
| Network | firewalld zone = `drop`, ssh only inbound. systemd-resolved with DNS-over-TLS (Cloudflare/Quad9 fallback), LLMNR off. NTS-authenticated chrony time. |
| SSH | password auth off, root login off, single `admin` user, X11 forwarding off, MaxAuthTries 3. |
| Auth | root **locked**, single `admin` user with sudo. pwquality minlen=14, 4 character classes. First-boot password forced via `chage -d 0`. |
| Audit | `auditd` rules covering passwd/shadow/sudoers/ssh/cron/sysctl/kernel modules and all privileged binaries. |
| IDS | `fail2ban` with sshd + pam-generic jails, journal backend, firewalld rich-rule action. |
| USB | `USBGuard` daemon, **default-block**, empty allowlist on first boot. |
| Services off | `abrt*`, `cups`, `geoclue`, `avahi-daemon`, `bluetooth`, `ModemManager`, `gssproxy`, `atd`, `pcscd`, `kdeconnectd`, `PackageKit`. |
| UX | KDE Plasma minimal, `BreezeBlackPure` colour scheme, Fira Code system font, `veilor-power save \| mid \| perf` with udev AC/battery auto-switch. |
Full reference: [docs/HARDENING.md](docs/HARDENING.md).
---
## 60-second tour — what's different from stock Fedora KDE
- **No Anaconda Initial Setup** wizard after first boot. Single LUKS
passphrase prompt is the entire install interaction. Admin user is
pre-created; password is set once on TTY1, then SDDM starts.
- **Root is locked.** `passwd -S root` reports `L`. There is no `su -`
to root, ever. Use `sudo`.
- **No PackageKit, no Flatpak by default.** Updates happen with
`sudo dnf upgrade` on your terms, not in the background.
- **Default firewall zone is `drop`**, not `FedoraWorkstation`. The only
thing your machine answers is sshd on its assigned port.
- **USBGuard blocks every USB device by default.** First-boot procedure:
plug in everything you trust, run `usbguard generate-policy`,
done.
- **Black-on-black KDE.** Wallpaper, panel, Konsole all match. No "white
flash" anywhere in the session.
- **`veilor-power save | mid | perf`** swaps the full tuned profile,
CPU governor, EPP, battery threshold, and screen-dim policy in one
command. Wired to AC/battery udev events too — laptop drops to `save`
when unplugged automatically.
---
## How veilor-os compares
| Feature | veilor-os | Stock Fedora KDE | Kicksecure |
|---|:-:|:-:|:-:|
| SELinux enforcing OOTB | yes | yes | yes |
| AppArmor | planned (v0.5) | no | yes |
| Secure Boot | yes (Fedora keys) | yes (Fedora keys) | configurable |
| LUKS2 with argon2id | default | optional | default |
| Single-prompt install (LUKS only) | yes | no | no |
| Root account locked by default | yes | no | yes |
| firewalld default zone = drop | yes | no | n/a (uses nftables) |
| USBGuard default-block | yes | no | yes |
| fail2ban + auditd OOTB | yes | no | partial |
| DNS-over-TLS by default | yes | no | yes |
| NTS-authenticated NTP | yes | no | yes |
| `init_on_alloc/free` (post-install) | yes (planned re-enable) | no | yes |
| Telemetry / phone-home | none | minimal | none |
| KDE Plasma branded theme | yes (black) | Breeze | n/a (XFCE) |
| Power-profile CLI | yes (3-mode) | partial | no |
| Reproducible kickstart-built ISO | yes | yes | yes (from Debian) |
| Base distro | Fedora 43 | Fedora 43 | Debian |
veilor-os is **not** trying to compete with Whonix-style anonymity or
Qubes-style isolation. It is a **hardened daily-driver desktop** — fast,
clean, locked down, with no manual post-install hardening required.
---
## Repo layout
```
kickstart/ veilor-os.ks full kickstart definition
build/ Containerfile + build-iso.sh reproducible ISO builder
overlay/ files dropped into installed root via %post
scripts/ hardening, SELinux policy, theme apply, firstboot
assets/ fonts, KDE colour scheme, branding, plymouth (planned)
docs/ BUILD / INSTALL / HARDENING / POWER / ROADMAP
test/ boot-checklist + KVM runner
.github/ CI workflows + PR template + CODEOWNERS
```
Build instructions: [docs/BUILD.md](docs/BUILD.md).
Roadmap: [docs/ROADMAP.md](docs/ROADMAP.md).
Contributing: [CONTRIBUTING.md](CONTRIBUTING.md).
Changelog: [CHANGELOG.md](CHANGELOG.md).
---
## License
MIT — see [LICENSE](LICENSE). Fira Code ships from Fedora's
`fira-code-fonts` package under SIL OFL 1.1. Fedora packages remain
under their respective licences. Kickstart, overlay, scripts, and
docs in this repo are MIT.