veilor-os/bluebuild/recipe.yml

137 lines
6.4 KiB
YAML
Raw Normal View History

v0.7 spike: BlueBuild recipe + ostreecontainer kickstart + cosign workflow Initial scaffold for the v0.7 hybrid path. Spike branch only — does NOT land in main until success criteria pass (see bluebuild/README.md). ## What this commits - bluebuild/recipe.yml — BlueBuild recipe extending ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with: * veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os) * sudo restored (revert secureblue's run0-only) * Xwayland restored (some apps still need it) * mullvad-browser layered alongside Trivalent (default browser kept) * tailscale + yggdrasil packages (mesh stack layers 1 + 2) * tailscaled.service pre-disabled (awaits first-boot prompt) * yggdrasil.service enabled (idle warm-fallback per STRATEGY.md) * veilor-firstboot.service + veilor-modules-lock.service enabled * cosign signing module configured - bluebuild/config/just/60-veilor.just — ujust recipes: * install-reticulum (RetiNet AGPL fork — mesh layer 3) * install-reticulum-rnode (LoRa hardware) * install-thorium (opt-in browser with explicit CVE-lag warning) * veilor-mesh-join (token paste / QR for tailscale onboarding) - bluebuild/README.md — spike doc + smoke-test commands + 5-item success criteria checklist - kickstart/install-ostreecontainer.ks — install kickstart template for the v0.7 path. No %packages block; uses `ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry` to populate / from the OCI image directly during anaconda's install pass. No first-boot rebase, no transition window. Keeps existing LUKS+btrfs partitioning verbatim. - .github/workflows/build-bluebuild.yml — GH Actions workflow: * Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch * Uses blue-build/github-action@v1 (TODO: pin to commit SHA per CI hardening agent 8 follow-up) * Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR * Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil, tailscale all present) * Generates SBOM (SPDX) via anchore/sbom-action * Publishes SLSA build provenance attestation ## What this does NOT change - main branch is untouched. v0.5.x kickstart path keeps shipping. - kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7 hybrid uses the existing live-ISO build path; only the install-time ks (install-ostreecontainer.ks) is new. - overlay/, scripts/, assets/ are untouched on this branch — the recipe pulls them in via `type: files` modules at build time. ## Spike success criteria (reproduced from bluebuild/README.md) - [ ] `bluebuild build recipe.yml` exits 0 - [ ] `bootc container lint` exits 0 on resulting image - [ ] `podman run` smoke-test passes - [ ] CI workflow builds + cosign-signs + pushes to GHCR - [ ] Installer ISO using `ostreecontainer` against this OCI reaches SDDM with admin login on first boot If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0. ## Reference - docs/STRATEGY.md (full plan) - docs/ROADMAP.md v0.7 (schedule) - docs/THREAT-MODEL.md (publish before v0.7 ship) - secureblue: https://github.com/secureblue/secureblue - BlueBuild: https://blue-build.org - ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
2026-05-05 15:30:04 +01:00
# veilor-os — BlueBuild recipe (v0.7 spike, 1-day target)
#
# Extends secureblue's hardened Kinoite OCI image with veilor branding,
# threat-model-driven UX choices, and the three-layer mesh stack
# (Tailscale + Yggdrasil + opt-in Reticulum). This is the OCI image
# that the v0.7+ kickstart's `ostreecontainer` directive pulls into
# the target root during the install pass.
#
# Build: bluebuild build recipe.yml
# Test: podman run --rm -it ghcr.io/veilor-org/veilor-os:43 /bin/bash
# CI: .github/workflows/build-bluebuild.yml signs + pushes to GHCR.
#
# Reference: https://blue-build.org/reference/recipe/
---
name: veilor-os
description: Hardened security-branded Fedora KDE on top of secureblue.
# Base image: secureblue's hardened Kinoite variant with userns sandboxing.
# That brings in: sysctl + kargs + custom SELinux policy + USBGuard +
# hardened-malloc + Unbound DoT + chronyd NTS + Trivalent browser.
base-image: ghcr.io/secureblue/kinoite-main-hardened
v0.7 spike: BlueBuild recipe + ostreecontainer kickstart + cosign workflow Initial scaffold for the v0.7 hybrid path. Spike branch only — does NOT land in main until success criteria pass (see bluebuild/README.md). ## What this commits - bluebuild/recipe.yml — BlueBuild recipe extending ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with: * veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os) * sudo restored (revert secureblue's run0-only) * Xwayland restored (some apps still need it) * mullvad-browser layered alongside Trivalent (default browser kept) * tailscale + yggdrasil packages (mesh stack layers 1 + 2) * tailscaled.service pre-disabled (awaits first-boot prompt) * yggdrasil.service enabled (idle warm-fallback per STRATEGY.md) * veilor-firstboot.service + veilor-modules-lock.service enabled * cosign signing module configured - bluebuild/config/just/60-veilor.just — ujust recipes: * install-reticulum (RetiNet AGPL fork — mesh layer 3) * install-reticulum-rnode (LoRa hardware) * install-thorium (opt-in browser with explicit CVE-lag warning) * veilor-mesh-join (token paste / QR for tailscale onboarding) - bluebuild/README.md — spike doc + smoke-test commands + 5-item success criteria checklist - kickstart/install-ostreecontainer.ks — install kickstart template for the v0.7 path. No %packages block; uses `ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry` to populate / from the OCI image directly during anaconda's install pass. No first-boot rebase, no transition window. Keeps existing LUKS+btrfs partitioning verbatim. - .github/workflows/build-bluebuild.yml — GH Actions workflow: * Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch * Uses blue-build/github-action@v1 (TODO: pin to commit SHA per CI hardening agent 8 follow-up) * Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR * Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil, tailscale all present) * Generates SBOM (SPDX) via anchore/sbom-action * Publishes SLSA build provenance attestation ## What this does NOT change - main branch is untouched. v0.5.x kickstart path keeps shipping. - kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7 hybrid uses the existing live-ISO build path; only the install-time ks (install-ostreecontainer.ks) is new. - overlay/, scripts/, assets/ are untouched on this branch — the recipe pulls them in via `type: files` modules at build time. ## Spike success criteria (reproduced from bluebuild/README.md) - [ ] `bluebuild build recipe.yml` exits 0 - [ ] `bootc container lint` exits 0 on resulting image - [ ] `podman run` smoke-test passes - [ ] CI workflow builds + cosign-signs + pushes to GHCR - [ ] Installer ISO using `ostreecontainer` against this OCI reaches SDDM with admin login on first boot If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0. ## Reference - docs/STRATEGY.md (full plan) - docs/ROADMAP.md v0.7 (schedule) - docs/THREAT-MODEL.md (publish before v0.7 ship) - secureblue: https://github.com/secureblue/secureblue - BlueBuild: https://blue-build.org - ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
2026-05-05 15:30:04 +01:00
image-version: latest
modules:
# ── 1. veilor branding overlay ──────────────────────────────────
# `type: copy` is a low-level direct COPY (no chmod, no script).
# `type: files` was failing with `chmod: Operation not permitted` on
# the BlueBuild-shipped /tmp/modules/files/files.sh under buildah +
# podman privileged in our runner — the script tries to make itself
# executable inside its own bind-mounted layer.
- type: copy
source: ../overlay
destination: /
v0.7 spike: BlueBuild recipe + ostreecontainer kickstart + cosign workflow Initial scaffold for the v0.7 hybrid path. Spike branch only — does NOT land in main until success criteria pass (see bluebuild/README.md). ## What this commits - bluebuild/recipe.yml — BlueBuild recipe extending ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with: * veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os) * sudo restored (revert secureblue's run0-only) * Xwayland restored (some apps still need it) * mullvad-browser layered alongside Trivalent (default browser kept) * tailscale + yggdrasil packages (mesh stack layers 1 + 2) * tailscaled.service pre-disabled (awaits first-boot prompt) * yggdrasil.service enabled (idle warm-fallback per STRATEGY.md) * veilor-firstboot.service + veilor-modules-lock.service enabled * cosign signing module configured - bluebuild/config/just/60-veilor.just — ujust recipes: * install-reticulum (RetiNet AGPL fork — mesh layer 3) * install-reticulum-rnode (LoRa hardware) * install-thorium (opt-in browser with explicit CVE-lag warning) * veilor-mesh-join (token paste / QR for tailscale onboarding) - bluebuild/README.md — spike doc + smoke-test commands + 5-item success criteria checklist - kickstart/install-ostreecontainer.ks — install kickstart template for the v0.7 path. No %packages block; uses `ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry` to populate / from the OCI image directly during anaconda's install pass. No first-boot rebase, no transition window. Keeps existing LUKS+btrfs partitioning verbatim. - .github/workflows/build-bluebuild.yml — GH Actions workflow: * Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch * Uses blue-build/github-action@v1 (TODO: pin to commit SHA per CI hardening agent 8 follow-up) * Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR * Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil, tailscale all present) * Generates SBOM (SPDX) via anchore/sbom-action * Publishes SLSA build provenance attestation ## What this does NOT change - main branch is untouched. v0.5.x kickstart path keeps shipping. - kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7 hybrid uses the existing live-ISO build path; only the install-time ks (install-ostreecontainer.ks) is new. - overlay/, scripts/, assets/ are untouched on this branch — the recipe pulls them in via `type: files` modules at build time. ## Spike success criteria (reproduced from bluebuild/README.md) - [ ] `bluebuild build recipe.yml` exits 0 - [ ] `bootc container lint` exits 0 on resulting image - [ ] `podman run` smoke-test passes - [ ] CI workflow builds + cosign-signs + pushes to GHCR - [ ] Installer ISO using `ostreecontainer` against this OCI reaches SDDM with admin login on first boot If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0. ## Reference - docs/STRATEGY.md (full plan) - docs/ROADMAP.md v0.7 (schedule) - docs/THREAT-MODEL.md (publish before v0.7 ship) - secureblue: https://github.com/secureblue/secureblue - BlueBuild: https://blue-build.org - ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
2026-05-05 15:30:04 +01:00
- type: copy
source: ../assets
destination: /usr/share/veilor-os/assets
v0.7 spike: BlueBuild recipe + ostreecontainer kickstart + cosign workflow Initial scaffold for the v0.7 hybrid path. Spike branch only — does NOT land in main until success criteria pass (see bluebuild/README.md). ## What this commits - bluebuild/recipe.yml — BlueBuild recipe extending ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with: * veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os) * sudo restored (revert secureblue's run0-only) * Xwayland restored (some apps still need it) * mullvad-browser layered alongside Trivalent (default browser kept) * tailscale + yggdrasil packages (mesh stack layers 1 + 2) * tailscaled.service pre-disabled (awaits first-boot prompt) * yggdrasil.service enabled (idle warm-fallback per STRATEGY.md) * veilor-firstboot.service + veilor-modules-lock.service enabled * cosign signing module configured - bluebuild/config/just/60-veilor.just — ujust recipes: * install-reticulum (RetiNet AGPL fork — mesh layer 3) * install-reticulum-rnode (LoRa hardware) * install-thorium (opt-in browser with explicit CVE-lag warning) * veilor-mesh-join (token paste / QR for tailscale onboarding) - bluebuild/README.md — spike doc + smoke-test commands + 5-item success criteria checklist - kickstart/install-ostreecontainer.ks — install kickstart template for the v0.7 path. No %packages block; uses `ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry` to populate / from the OCI image directly during anaconda's install pass. No first-boot rebase, no transition window. Keeps existing LUKS+btrfs partitioning verbatim. - .github/workflows/build-bluebuild.yml — GH Actions workflow: * Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch * Uses blue-build/github-action@v1 (TODO: pin to commit SHA per CI hardening agent 8 follow-up) * Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR * Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil, tailscale all present) * Generates SBOM (SPDX) via anchore/sbom-action * Publishes SLSA build provenance attestation ## What this does NOT change - main branch is untouched. v0.5.x kickstart path keeps shipping. - kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7 hybrid uses the existing live-ISO build path; only the install-time ks (install-ostreecontainer.ks) is new. - overlay/, scripts/, assets/ are untouched on this branch — the recipe pulls them in via `type: files` modules at build time. ## Spike success criteria (reproduced from bluebuild/README.md) - [ ] `bluebuild build recipe.yml` exits 0 - [ ] `bootc container lint` exits 0 on resulting image - [ ] `podman run` smoke-test passes - [ ] CI workflow builds + cosign-signs + pushes to GHCR - [ ] Installer ISO using `ostreecontainer` against this OCI reaches SDDM with admin login on first boot If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0. ## Reference - docs/STRATEGY.md (full plan) - docs/ROADMAP.md v0.7 (schedule) - docs/THREAT-MODEL.md (publish before v0.7 ship) - secureblue: https://github.com/secureblue/secureblue - BlueBuild: https://blue-build.org - ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
2026-05-05 15:30:04 +01:00
- type: copy
source: ../scripts
destination: /usr/share/veilor-os/scripts
v0.7 spike: BlueBuild recipe + ostreecontainer kickstart + cosign workflow Initial scaffold for the v0.7 hybrid path. Spike branch only — does NOT land in main until success criteria pass (see bluebuild/README.md). ## What this commits - bluebuild/recipe.yml — BlueBuild recipe extending ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with: * veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os) * sudo restored (revert secureblue's run0-only) * Xwayland restored (some apps still need it) * mullvad-browser layered alongside Trivalent (default browser kept) * tailscale + yggdrasil packages (mesh stack layers 1 + 2) * tailscaled.service pre-disabled (awaits first-boot prompt) * yggdrasil.service enabled (idle warm-fallback per STRATEGY.md) * veilor-firstboot.service + veilor-modules-lock.service enabled * cosign signing module configured - bluebuild/config/just/60-veilor.just — ujust recipes: * install-reticulum (RetiNet AGPL fork — mesh layer 3) * install-reticulum-rnode (LoRa hardware) * install-thorium (opt-in browser with explicit CVE-lag warning) * veilor-mesh-join (token paste / QR for tailscale onboarding) - bluebuild/README.md — spike doc + smoke-test commands + 5-item success criteria checklist - kickstart/install-ostreecontainer.ks — install kickstart template for the v0.7 path. No %packages block; uses `ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry` to populate / from the OCI image directly during anaconda's install pass. No first-boot rebase, no transition window. Keeps existing LUKS+btrfs partitioning verbatim. - .github/workflows/build-bluebuild.yml — GH Actions workflow: * Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch * Uses blue-build/github-action@v1 (TODO: pin to commit SHA per CI hardening agent 8 follow-up) * Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR * Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil, tailscale all present) * Generates SBOM (SPDX) via anchore/sbom-action * Publishes SLSA build provenance attestation ## What this does NOT change - main branch is untouched. v0.5.x kickstart path keeps shipping. - kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7 hybrid uses the existing live-ISO build path; only the install-time ks (install-ostreecontainer.ks) is new. - overlay/, scripts/, assets/ are untouched on this branch — the recipe pulls them in via `type: files` modules at build time. ## Spike success criteria (reproduced from bluebuild/README.md) - [ ] `bluebuild build recipe.yml` exits 0 - [ ] `bootc container lint` exits 0 on resulting image - [ ] `podman run` smoke-test passes - [ ] CI workflow builds + cosign-signs + pushes to GHCR - [ ] Installer ISO using `ostreecontainer` against this OCI reaches SDDM with admin login on first boot If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0. ## Reference - docs/STRATEGY.md (full plan) - docs/ROADMAP.md v0.7 (schedule) - docs/THREAT-MODEL.md (publish before v0.7 ship) - secureblue: https://github.com/secureblue/secureblue - BlueBuild: https://blue-build.org - ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
2026-05-05 15:30:04 +01:00
# ── 2. Branding overrides at build time ─────────────────────────
# Use raw `type: containerfile` (RUN line) instead of `type: script`
# — bluebuild's script-module helper script.nu fails 'chmod:
# Operation not permitted' on its own bind-mounted layer under
# podman/buildah privileged. Raw RUN bypasses the helper.
- type: containerfile
v0.7 spike: BlueBuild recipe + ostreecontainer kickstart + cosign workflow Initial scaffold for the v0.7 hybrid path. Spike branch only — does NOT land in main until success criteria pass (see bluebuild/README.md). ## What this commits - bluebuild/recipe.yml — BlueBuild recipe extending ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with: * veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os) * sudo restored (revert secureblue's run0-only) * Xwayland restored (some apps still need it) * mullvad-browser layered alongside Trivalent (default browser kept) * tailscale + yggdrasil packages (mesh stack layers 1 + 2) * tailscaled.service pre-disabled (awaits first-boot prompt) * yggdrasil.service enabled (idle warm-fallback per STRATEGY.md) * veilor-firstboot.service + veilor-modules-lock.service enabled * cosign signing module configured - bluebuild/config/just/60-veilor.just — ujust recipes: * install-reticulum (RetiNet AGPL fork — mesh layer 3) * install-reticulum-rnode (LoRa hardware) * install-thorium (opt-in browser with explicit CVE-lag warning) * veilor-mesh-join (token paste / QR for tailscale onboarding) - bluebuild/README.md — spike doc + smoke-test commands + 5-item success criteria checklist - kickstart/install-ostreecontainer.ks — install kickstart template for the v0.7 path. No %packages block; uses `ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry` to populate / from the OCI image directly during anaconda's install pass. No first-boot rebase, no transition window. Keeps existing LUKS+btrfs partitioning verbatim. - .github/workflows/build-bluebuild.yml — GH Actions workflow: * Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch * Uses blue-build/github-action@v1 (TODO: pin to commit SHA per CI hardening agent 8 follow-up) * Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR * Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil, tailscale all present) * Generates SBOM (SPDX) via anchore/sbom-action * Publishes SLSA build provenance attestation ## What this does NOT change - main branch is untouched. v0.5.x kickstart path keeps shipping. - kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7 hybrid uses the existing live-ISO build path; only the install-time ks (install-ostreecontainer.ks) is new. - overlay/, scripts/, assets/ are untouched on this branch — the recipe pulls them in via `type: files` modules at build time. ## Spike success criteria (reproduced from bluebuild/README.md) - [ ] `bluebuild build recipe.yml` exits 0 - [ ] `bootc container lint` exits 0 on resulting image - [ ] `podman run` smoke-test passes - [ ] CI workflow builds + cosign-signs + pushes to GHCR - [ ] Installer ISO using `ostreecontainer` against this OCI reaches SDDM with admin login on first boot If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0. ## Reference - docs/STRATEGY.md (full plan) - docs/ROADMAP.md v0.7 (schedule) - docs/THREAT-MODEL.md (publish before v0.7 ship) - secureblue: https://github.com/secureblue/secureblue - BlueBuild: https://blue-build.org - ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
2026-05-05 15:30:04 +01:00
snippets:
- |
RUN sed -i -e 's|^GRUB_DISTRIBUTOR=.*|GRUB_DISTRIBUTOR="veilor-os"|' /etc/default/grub 2>/dev/null || true ; \
bash /usr/share/veilor-os/scripts/kde-theme-apply.sh 2>/dev/null || true ; \
bash /usr/share/veilor-os/scripts/30-apply-v03-theme.sh 2>/dev/null || true ; \
plymouth-set-default-theme details 2>/dev/null || true ; \
chmod +x /usr/share/veilor-os/scripts/*.sh \
/usr/share/veilor-os/scripts/selinux/*.sh \
/usr/local/bin/veilor-* 2>/dev/null || true ; \
fc-cache -f 2>/dev/null || true ; \
if [ -f /etc/os-release ]; then \
sed -i \
-e 's|^NAME=.*|NAME="veilor-os"|' \
-e 's|^PRETTY_NAME=.*|PRETTY_NAME="veilor-os 0.7 (atomic)"|' \
-e 's|^ID=.*|ID=veilor|' \
-e 's|^ID_LIKE=.*|ID_LIKE="fedora kinoite"|' \
/etc/os-release || true ; \
fi
# brand-leak check moved to CI smoke-test (STEP 14 hang under buildah overlayfs, run 171 2026-05-07)
v0.7 spike: BlueBuild recipe + ostreecontainer kickstart + cosign workflow Initial scaffold for the v0.7 hybrid path. Spike branch only — does NOT land in main until success criteria pass (see bluebuild/README.md). ## What this commits - bluebuild/recipe.yml — BlueBuild recipe extending ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with: * veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os) * sudo restored (revert secureblue's run0-only) * Xwayland restored (some apps still need it) * mullvad-browser layered alongside Trivalent (default browser kept) * tailscale + yggdrasil packages (mesh stack layers 1 + 2) * tailscaled.service pre-disabled (awaits first-boot prompt) * yggdrasil.service enabled (idle warm-fallback per STRATEGY.md) * veilor-firstboot.service + veilor-modules-lock.service enabled * cosign signing module configured - bluebuild/config/just/60-veilor.just — ujust recipes: * install-reticulum (RetiNet AGPL fork — mesh layer 3) * install-reticulum-rnode (LoRa hardware) * install-thorium (opt-in browser with explicit CVE-lag warning) * veilor-mesh-join (token paste / QR for tailscale onboarding) - bluebuild/README.md — spike doc + smoke-test commands + 5-item success criteria checklist - kickstart/install-ostreecontainer.ks — install kickstart template for the v0.7 path. No %packages block; uses `ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry` to populate / from the OCI image directly during anaconda's install pass. No first-boot rebase, no transition window. Keeps existing LUKS+btrfs partitioning verbatim. - .github/workflows/build-bluebuild.yml — GH Actions workflow: * Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch * Uses blue-build/github-action@v1 (TODO: pin to commit SHA per CI hardening agent 8 follow-up) * Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR * Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil, tailscale all present) * Generates SBOM (SPDX) via anchore/sbom-action * Publishes SLSA build provenance attestation ## What this does NOT change - main branch is untouched. v0.5.x kickstart path keeps shipping. - kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7 hybrid uses the existing live-ISO build path; only the install-time ks (install-ostreecontainer.ks) is new. - overlay/, scripts/, assets/ are untouched on this branch — the recipe pulls them in via `type: files` modules at build time. ## Spike success criteria (reproduced from bluebuild/README.md) - [ ] `bluebuild build recipe.yml` exits 0 - [ ] `bootc container lint` exits 0 on resulting image - [ ] `podman run` smoke-test passes - [ ] CI workflow builds + cosign-signs + pushes to GHCR - [ ] Installer ISO using `ostreecontainer` against this OCI reaches SDDM with admin login on first boot If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0. ## Reference - docs/STRATEGY.md (full plan) - docs/ROADMAP.md v0.7 (schedule) - docs/THREAT-MODEL.md (publish before v0.7 ship) - secureblue: https://github.com/secureblue/secureblue - BlueBuild: https://blue-build.org - ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
2026-05-05 15:30:04 +01:00
# ── 3. Override secureblue's run0-only — restore sudo ───────────
# secureblue removes sudo + replaces with run0. Too disruptive for
# daily-driver workflows. Restore sudo, keep run0 available.
- type: rpm-ostree
install:
- sudo
# ── 4. Re-enable Xwayland ───────────────────────────────────────
# secureblue disables Xwayland for attack-surface reduction. Some
# apps (Element, Slack-likes, older Qt5 tools) still need it.
# User who wants it removed back can `rpm-ostree override remove`.
- type: rpm-ostree
install:
- xorg-x11-server-Xwayland
# ── 5. Mullvad Browser as anti-fingerprint companion ────────────
# Layered alongside Trivalent (kept as default per STRATEGY.md).
# Trivalent for daily browsing, Mullvad for pseudonymous browsing.
# Thorium remains opt-in only via `ujust install-thorium` — see
# config/thorium.just for the warning + install logic.
- type: rpm-ostree
install:
- mullvad-browser
# ── 6. Mesh stack packages ──────────────────────────────────────
# Layer 1 (Day 1 daily driver, service pre-disabled): Tailscale
# Layer 2 (Day 1 idle warm-fallback): Yggdrasil-go
# Layer 3 (opt-in via ujust): Reticulum / RetiNet — handled in just/
- type: rpm-ostree
install:
- tailscale
- yggdrasil
# ── 6b. Memory hygiene + ergonomic deps ─────────────────────────
# zram-generator gives us zram swap (no disk swap, no cold-boot
# leak). gum is the TUI primitive used by veilor-postinstall +
# veilor-update + veilor-doctor — vendor binary at build time so
# post-install layering doesn't need it.
- type: rpm-ostree
install:
- zram-generator
- jq
- vim-enhanced
- tmux
- htop
v0.7 spike: BlueBuild recipe + ostreecontainer kickstart + cosign workflow Initial scaffold for the v0.7 hybrid path. Spike branch only — does NOT land in main until success criteria pass (see bluebuild/README.md). ## What this commits - bluebuild/recipe.yml — BlueBuild recipe extending ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with: * veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os) * sudo restored (revert secureblue's run0-only) * Xwayland restored (some apps still need it) * mullvad-browser layered alongside Trivalent (default browser kept) * tailscale + yggdrasil packages (mesh stack layers 1 + 2) * tailscaled.service pre-disabled (awaits first-boot prompt) * yggdrasil.service enabled (idle warm-fallback per STRATEGY.md) * veilor-firstboot.service + veilor-modules-lock.service enabled * cosign signing module configured - bluebuild/config/just/60-veilor.just — ujust recipes: * install-reticulum (RetiNet AGPL fork — mesh layer 3) * install-reticulum-rnode (LoRa hardware) * install-thorium (opt-in browser with explicit CVE-lag warning) * veilor-mesh-join (token paste / QR for tailscale onboarding) - bluebuild/README.md — spike doc + smoke-test commands + 5-item success criteria checklist - kickstart/install-ostreecontainer.ks — install kickstart template for the v0.7 path. No %packages block; uses `ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry` to populate / from the OCI image directly during anaconda's install pass. No first-boot rebase, no transition window. Keeps existing LUKS+btrfs partitioning verbatim. - .github/workflows/build-bluebuild.yml — GH Actions workflow: * Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch * Uses blue-build/github-action@v1 (TODO: pin to commit SHA per CI hardening agent 8 follow-up) * Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR * Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil, tailscale all present) * Generates SBOM (SPDX) via anchore/sbom-action * Publishes SLSA build provenance attestation ## What this does NOT change - main branch is untouched. v0.5.x kickstart path keeps shipping. - kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7 hybrid uses the existing live-ISO build path; only the install-time ks (install-ostreecontainer.ks) is new. - overlay/, scripts/, assets/ are untouched on this branch — the recipe pulls them in via `type: files` modules at build time. ## Spike success criteria (reproduced from bluebuild/README.md) - [ ] `bluebuild build recipe.yml` exits 0 - [ ] `bootc container lint` exits 0 on resulting image - [ ] `podman run` smoke-test passes - [ ] CI workflow builds + cosign-signs + pushes to GHCR - [ ] Installer ISO using `ostreecontainer` against this OCI reaches SDDM with admin login on first boot If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0. ## Reference - docs/STRATEGY.md (full plan) - docs/ROADMAP.md v0.7 (schedule) - docs/THREAT-MODEL.md (publish before v0.7 ship) - secureblue: https://github.com/secureblue/secureblue - BlueBuild: https://blue-build.org - ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
2026-05-05 15:30:04 +01:00
# ── 7. ujust recipes for opt-in components ──────────────────────
- type: copy
source: config/just
destination: /usr/share/ublue-os/just
v0.7 spike: BlueBuild recipe + ostreecontainer kickstart + cosign workflow Initial scaffold for the v0.7 hybrid path. Spike branch only — does NOT land in main until success criteria pass (see bluebuild/README.md). ## What this commits - bluebuild/recipe.yml — BlueBuild recipe extending ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with: * veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os) * sudo restored (revert secureblue's run0-only) * Xwayland restored (some apps still need it) * mullvad-browser layered alongside Trivalent (default browser kept) * tailscale + yggdrasil packages (mesh stack layers 1 + 2) * tailscaled.service pre-disabled (awaits first-boot prompt) * yggdrasil.service enabled (idle warm-fallback per STRATEGY.md) * veilor-firstboot.service + veilor-modules-lock.service enabled * cosign signing module configured - bluebuild/config/just/60-veilor.just — ujust recipes: * install-reticulum (RetiNet AGPL fork — mesh layer 3) * install-reticulum-rnode (LoRa hardware) * install-thorium (opt-in browser with explicit CVE-lag warning) * veilor-mesh-join (token paste / QR for tailscale onboarding) - bluebuild/README.md — spike doc + smoke-test commands + 5-item success criteria checklist - kickstart/install-ostreecontainer.ks — install kickstart template for the v0.7 path. No %packages block; uses `ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry` to populate / from the OCI image directly during anaconda's install pass. No first-boot rebase, no transition window. Keeps existing LUKS+btrfs partitioning verbatim. - .github/workflows/build-bluebuild.yml — GH Actions workflow: * Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch * Uses blue-build/github-action@v1 (TODO: pin to commit SHA per CI hardening agent 8 follow-up) * Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR * Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil, tailscale all present) * Generates SBOM (SPDX) via anchore/sbom-action * Publishes SLSA build provenance attestation ## What this does NOT change - main branch is untouched. v0.5.x kickstart path keeps shipping. - kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7 hybrid uses the existing live-ISO build path; only the install-time ks (install-ostreecontainer.ks) is new. - overlay/, scripts/, assets/ are untouched on this branch — the recipe pulls them in via `type: files` modules at build time. ## Spike success criteria (reproduced from bluebuild/README.md) - [ ] `bluebuild build recipe.yml` exits 0 - [ ] `bootc container lint` exits 0 on resulting image - [ ] `podman run` smoke-test passes - [ ] CI workflow builds + cosign-signs + pushes to GHCR - [ ] Installer ISO using `ostreecontainer` against this OCI reaches SDDM with admin login on first boot If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0. ## Reference - docs/STRATEGY.md (full plan) - docs/ROADMAP.md v0.7 (schedule) - docs/THREAT-MODEL.md (publish before v0.7 ship) - secureblue: https://github.com/secureblue/secureblue - BlueBuild: https://blue-build.org - ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
2026-05-05 15:30:04 +01:00
# ── 8 + 9. systemd unit enables/disables ────────────────────────
# Same chmod-permitted blocker on `type: systemd` helper. Use raw
# RUN systemctl preset/enable/disable instead.
- type: containerfile
snippets:
- |
RUN systemctl enable yggdrasil.service 2>/dev/null || true ; \
systemctl disable tailscaled.service 2>/dev/null || true ; \
systemctl enable veilor-firstboot.service 2>/dev/null || true ; \
systemctl enable veilor-modules-lock.service 2>/dev/null || true ; \
systemctl enable veilor-postinstall.service 2>/dev/null || true ; \
systemctl enable veilor-doctor.timer 2>/dev/null || true
v0.7 spike: BlueBuild recipe + ostreecontainer kickstart + cosign workflow Initial scaffold for the v0.7 hybrid path. Spike branch only — does NOT land in main until success criteria pass (see bluebuild/README.md). ## What this commits - bluebuild/recipe.yml — BlueBuild recipe extending ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with: * veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os) * sudo restored (revert secureblue's run0-only) * Xwayland restored (some apps still need it) * mullvad-browser layered alongside Trivalent (default browser kept) * tailscale + yggdrasil packages (mesh stack layers 1 + 2) * tailscaled.service pre-disabled (awaits first-boot prompt) * yggdrasil.service enabled (idle warm-fallback per STRATEGY.md) * veilor-firstboot.service + veilor-modules-lock.service enabled * cosign signing module configured - bluebuild/config/just/60-veilor.just — ujust recipes: * install-reticulum (RetiNet AGPL fork — mesh layer 3) * install-reticulum-rnode (LoRa hardware) * install-thorium (opt-in browser with explicit CVE-lag warning) * veilor-mesh-join (token paste / QR for tailscale onboarding) - bluebuild/README.md — spike doc + smoke-test commands + 5-item success criteria checklist - kickstart/install-ostreecontainer.ks — install kickstart template for the v0.7 path. No %packages block; uses `ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry` to populate / from the OCI image directly during anaconda's install pass. No first-boot rebase, no transition window. Keeps existing LUKS+btrfs partitioning verbatim. - .github/workflows/build-bluebuild.yml — GH Actions workflow: * Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch * Uses blue-build/github-action@v1 (TODO: pin to commit SHA per CI hardening agent 8 follow-up) * Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR * Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil, tailscale all present) * Generates SBOM (SPDX) via anchore/sbom-action * Publishes SLSA build provenance attestation ## What this does NOT change - main branch is untouched. v0.5.x kickstart path keeps shipping. - kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7 hybrid uses the existing live-ISO build path; only the install-time ks (install-ostreecontainer.ks) is new. - overlay/, scripts/, assets/ are untouched on this branch — the recipe pulls them in via `type: files` modules at build time. ## Spike success criteria (reproduced from bluebuild/README.md) - [ ] `bluebuild build recipe.yml` exits 0 - [ ] `bootc container lint` exits 0 on resulting image - [ ] `podman run` smoke-test passes - [ ] CI workflow builds + cosign-signs + pushes to GHCR - [ ] Installer ISO using `ostreecontainer` against this OCI reaches SDDM with admin login on first boot If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0. ## Reference - docs/STRATEGY.md (full plan) - docs/ROADMAP.md v0.7 (schedule) - docs/THREAT-MODEL.md (publish before v0.7 ship) - secureblue: https://github.com/secureblue/secureblue - BlueBuild: https://blue-build.org - ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
2026-05-05 15:30:04 +01:00
# ── 10. signing config ──────────────────────────────────────────
# cosign.pub committed alongside this recipe; cosign.key kept off
# repo and provided to CI as Forgejo secret COSIGN_PRIVATE_KEY.
# The action exports it to /tmp at build time.
- type: signing