# Threat Model > **Status:** Final for v0.7 public launch. Honest scope. veilor-os is a hardened daily-driver desktop. Not a paranoia OS, not an anonymity OS, not an isolation OS. This document exists so that security-conscious developers, journalists, and activists can decide whether the threat model fits their actual adversary before they trust the system. If your adversary is on the "out of scope" list below, **use a different tool**. veilor-os will not save you, and we will not pretend otherwise. --- ## In scope — what veilor-os defends against Every row cites the file or setting that implements the mitigation, so the claim is auditable from a clean checkout. | Adversary / scenario | veilor-os mitigation | |---|---| | Lost or stolen laptop, powered off | LUKS2 `aes-xts-plain64` + `argon2id` (`mem=1 GiB`, `time=9`) on root LV; swap is `zram` only — no persistent key material on disk. Defined in `kickstart/veilor-os.ks` `part pv.veilor` block. | | Generic browser / email malware (drive-by RCE, malicious attachment) | SELinux `enforcing` + targeted policy + custom `veilor-systemd.te` module (`scripts/selinux/`); sysctl knobs in `/etc/sysctl.d/99-veilor-hardening.conf`: `kernel.kptr_restrict=2`, `kernel.yama.ptrace_scope=2`, `kernel.perf_event_paranoid=3`, `net.core.bpf_jit_harden=2`, `kernel.randomize_va_space=2`, `fs.suid_dumpable=0`, `dev.tty.ldisc_autoload=0`. AppArmor profile skeletons in `scripts/apparmor/` for Trivalent/Thorium/lm-studio (opt-in, complain mode, hardens to enforce per profile). | | Console-side USB attack (BadUSB, rubber ducky, juice-jack) | USBGuard daemon, `ImplicitPolicyTarget=block`, **id-based** rules in `/etc/usbguard/rules.conf` (vendor:product, not hash — survives dock replug). Empty allowlist on first boot; operator runs `usbguard generate-policy` after plugging trusted devices. | | SSH brute-force / credential-stuffing | `/etc/ssh/sshd_config.d/10-veilor-hardening.conf`: `PasswordAuthentication no`, `PermitRootLogin no`, `AllowUsers admin`, `MaxAuthTries 3`, `X11Forwarding no`, `LogLevel VERBOSE`. `fail2ban` `sshd` + `pam-generic` jails (journald backend) ban via firewalld `rich-rule` action. | | Post-incident forensics ("what happened?") | `auditd` rules in `/etc/audit/rules.d/99-veilor-hardening.rules` watch `/etc/{passwd,shadow,group,sudoers,sudoers.d,ssh/sshd_config*,selinux,firewalld,cron.*,sysctl.*,systemd/system}`, every privileged binary (`sudo`, `su`, `passwd`, `mount`, `pkexec`, …), `init_module`/`finit_module`/`delete_module` syscalls, and uid≥1000 perm/owner changes. Logs persist across reboot. | | Supply-chain on the OS image itself | Secure Boot enforced (Fedora signed shim → GRUB → kernel). v0.7 adds cosign-signed OCI image at `ghcr.io/veilor/veilor-os:43`, GPG-signed ISO + sha256 + .asc, plus our own MOK for out-of-tree module signing. | | Unprivileged local user attempting LPE | Root account locked (`passwd -l root`; `passwd -S root` → `L`); single `admin` user in `wheel`; `pwquality.conf` `minlen=14`, `minclass=4`, dictcheck on. Kernel `lockdown=integrity`, `slab_nomerge`, `init_on_alloc=1`, `init_on_free=1`, `randomize_kstack_offset=on`, `vsyscall=none` set in bootloader args. Module loading frozen 30 s after graphical boot via `veilor-modules-lock.service`. | | Network-listening services as attack surface | `firewalld` default zone = `drop`; only `sshd` answers. `abrt*`, `cups`, `cups-browsed`, `geoclue`, `avahi-daemon`, `bluetooth`, `ModemManager`, `gssproxy`, `atd`, `pcscd.{socket,service}` are masked; `kdeconnectd` and `PackageKit` are removed at the package level. | | Time-based MITM (back-dated certs, replay) | `chrony` with NTS authentication against `time.cloudflare.com` and `nts.sth1/2.ntp.se` (pool fallback only). `systemd-resolved` with DNS-over-TLS opportunistic, DNSSEC `allow-downgrade`, LLMNR off; resolvers Cloudflare 1.1.1.1 / 1.0.0.1, fallback Quad9 9.9.9.9 / 149.112.112.112. | --- ## Out of scope — what veilor-os does NOT defend against These adversaries are unambiguously outside our scope. Pretending otherwise gets people hurt. **If your adversary is on this list, pick a different tool.** | Adversary / scenario | Why veilor-os doesn't help | Use instead | |---|---|---| | Firmware-level implant (UEFI, Intel ME, BMC, EC) | veilor-os does not protect against firmware implants. Secure Boot validates the OS chain only; we do not flash, audit, or sign firmware below GRUB. | Heads / coreboot on supported hardware. | | Evil-maid attack on a running, unlocked system | LUKS master keys live in RAM while the system is up. A physically present attacker can dump RAM (cold-boot, Thunderbolt DMA, debug header) and recover them. | Power off when unattended. Disable Thunderbolt DMA in firmware. Qubes-in-a-Faraday-bag if you are that target. | | Hardware keylogger / interposer between keyboard and machine | veilor-os is software. Software cannot detect a passive hardware tap. | Physical custody of the device. Tamper-evident seals. | | Targeted RCE on the user session (browser 0-day, messenger exploit) | KDE Plasma is not sandboxed. A logged-in compromise owns the user's data and tokens. SELinux confines daemons; it does not confine the desktop session. | Qubes OS (per-app Xen VM isolation). | | Side-channel attacks on AES (timing, cache, power, EM) | veilor-os ships stock kernel crypto. We provide no constant-time or power-analysis guarantees beyond what the kernel and CPU deliver. | Threat-specific HSM, air-gap. | | Physical attack on a TPM2 chip (bus probe, glitch, decap) | veilor-os does not bind keys to TPM2 in v0.7. Even when binding lands post-v1.0, TPM2 is not anti-tamper hardware. | Off-device key custody (smartcard / YubiKey / OnlyKey). | | Network-level traffic correlation / traffic analysis | All packets leave the box on the local IP. veilor-os does not onion-route. | Tails, Whonix, Tor. | | Trust-on-first-use attacks (operator accepts a bad cert) | veilor-os cannot override the operator's explicit decisions. Bad SSL or SSH host-key acceptance is out of scope. | Enrolment policy, MDM, certificate pinning. | | Adversary with sustained physical access and time | Given unlimited physical time and tools, any laptop falls. | Operational security, not OS choice. | --- ## Hardening tradeoffs (what you give up) Hardening that breaks ordinary work gets called out, not hidden. - **SELinux enforcing** — some apps (proprietary, out-of-tree) ship without policy. Symptom: `EACCES` despite correct file perms. Workaround: write a local policy module; do not switch to permissive. - **LUKS2 argon2id (mem=1 GB / time=9)** — boot 5–30 s slower on older CPUs. The cost of a passphrase that survives a GPU attacker. - **USBGuard default-block** — every new device needs an explicit allow. First-boot: plug trusted devices in, run `usbguard generate-policy`. Forget this and your USB-C dock looks broken. - **Module lockdown 30 s after graphical boot** — out-of-tree drivers (NVIDIA proprietary, VirtualBox, out-of-tree wireguard) will fail. Load early via initramfs or use the in-tree alternative. - **firewalld zone = drop** — KDE Connect, mDNS printer discovery, SMB browsing don't work until explicitly opened. This is the point. - **No PackageKit / no Flatpak by default** — updates happen on your terms via `dnf upgrade`. --- ## Where veilor-os IS like Tails / Whonix / Qubes - Threat model published. Transparency about scope is the price of being taken seriously. - Default-deny firewall (`drop` zone, ssh inbound only). - Encrypted at rest by default — LUKS2 + argon2id, no-disk-swap (zram). ## Where veilor-os DIFFERS - **Daily-driver target.** Boot it once, install it, use it for years. Not a session-only / amnesia OS. - **Single-VM / single-kernel.** No per-app compartmentalisation. A browser RCE owns your session. (See "out of scope".) - **Persistent identity by design.** Your `~`, your keys, your shell history persist. This is a feature for an operator, a misfeature for an activist evading correlation. --- ## Comparison matrix Scoring legend: `✓` shipped & on by default, `~` partial / opt-in, `✗` not provided, `n/a` not applicable to that distro's model. Project metrics are GitHub / Codeberg figures as of 2026-05. | Axis | veilor-os | Stock Fedora KDE | Kicksecure | Tails | Qubes OS | secureblue | Athena OS | |---|:---:|:---:|:---:|:---:|:---:|:---:|:---:| | **Encrypted at rest by default** | ✓ (LUKS2 argon2id, mem=1 GiB) | ~ (optional in Anaconda) | ✓ | n/a (amnesic, session-only) | ✓ | ✓ | ~ (optional) | | **MAC enforcing OOTB** | ✓ (SELinux + opt-in AppArmor) | ✓ (SELinux) | ✓ (AppArmor) | ✓ (AppArmor) | ✓ (per-VM) | ✓ (SELinux) | ✓ (AppArmor) | | **Default-deny firewall** | ✓ (firewalld zone=drop) | ✗ | ✓ | ✓ (Tor-only) | ✓ | ✓ | ✓ | | **USB default-block** | ✓ (USBGuard, id-rules) | ✗ | ✓ | ✓ | ✓ (sys-usb) | ✓ (USBGuard) | ✗ | | **Per-app isolation (VM/sandbox)** | ✗ | ✗ | ✗ | ~ (AppArmor) | ✓ (Xen VMs) | ~ (Flatpak/bwrap) | ✗ | | **Anonymity / Tor by default** | ✗ | ✗ | ✗ | ✓ | ~ (Whonix VMs) | ✗ | ✗ | | **Daily driver target (persistent)** | ✓ | ✓ | ✓ | ✗ (amnesic) | ✓ (heavy, hardware-partitioning) | ✓ | ✓ | | **Signed releases (cosign + GPG)** | ✓ (v0.7) | ✓ | ✓ | ✓ | ✓ | ✓ (cosign on OCI) | ~ (sha256 only) | | **Threat model published** | ✓ (this doc) | ✗ | ✓ | ✓ | ✓ | ✗ | ✓ | | **Hardware compatibility (laptops)** | ✓ (Fedora kernel) | ✓ | ~ | ~ (live USB) | ~ (Xen-pinned HCL) | ✓ | ✓ (Arch kernel) | | **Project size (contributors / stars, 2026-05)** | solo / pre-public | n/a (Fedora-wide) | small team / ~600 | ~30 / ~3k | large / ~5k | ~30 / ~940, active monthly cadence | ~8 / ~1.4k | --- ## Where veilor-os fits Pick veilor-os if your job is to write code, edit docs, manage infrastructure, read mail, browse — and you want a desktop that won't quietly betray you to a generic adversary while you do it. **You are the user, not the target of a state.** Pick **Tails** for amnesia and Tor by default. **Qubes** if you must assume any app could be compromised. **Kicksecure** for similar hardening on Debian. **secureblue** for a hardened atomic Fedora. **Stock Fedora KDE** if you just want Fedora with no opinions. --- ## v0.7 public-launch checklist These are the items that gate flipping the repo public and posting: - [ ] Threat model finalised and published (this document). - [ ] GPG-signed releases working (v0.4 dependency — ISO + sha256 + .asc). - [ ] Reproducible build verifiable from clean checkout (v0.4). - [ ] mkdocs-material (or Hugo) site live on `veilor.org`, generated from `docs/`. INSTALL, HARDENING, BUILD, ROADMAP, RELEASE, THREAT-MODEL, CONTRIBUTING all rendered. - [ ] Comparison + benchmark numbers published (cold boot, idle RAM, idle egress, suspend/resume) vs stock Fedora KDE. - [ ] Press kit page: wallpapers, logo SVG, screenshots, feature one-liner, signed quotes from early users. - [ ] **"What veilor-os is not"** preempt page — direct link from launch post. Answers "why not Qubes?", "why not Tails?", "why not just stock Fedora?" so the first hundred comments don't have to. - [ ] Comparison post drafted for **r/linux**, **r/Fedora**, **HN**. Same body, three formats. Lead with the threat model link, not the black wallpaper. - [ ] CHANGELOG.md tagged at v0.7.0 release commit; GitHub Release created with ISO + sha256 + .asc artefacts attached. - [ ] Repo flipped to public, `veilor.org` DNS pointed at the docs site, Mastodon / Matrix / SimpleX announcement queued. --- *Last reviewed: v0.7 draft. Update every minor release.*