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/
|
2026-05-08 04:27:44 +01:00
|
|
|
|
#
|
|
|
|
|
|
# ── Module collapse history ──────────────────────────────────────
|
|
|
|
|
|
# Run 183 (2026-05-08) ate 3h10min before runner timeout: each RUN/COPY
|
|
|
|
|
|
# layer COMMIT under fuse-overlayfs over secureblue's 130-layer hardened
|
|
|
|
|
|
# base costs ~40min wallclock (STEP 10..13 each 38–43min). Ergo: every
|
|
|
|
|
|
# saved module = ~40min saved. Collapsed:
|
|
|
|
|
|
# - 5× rpm-ostree → 1× (-4 layers)
|
|
|
|
|
|
# - 2× containerfile (brand sed + systemctl enable) → 1× (-1 layer)
|
|
|
|
|
|
# - 4× copy left as-is — BlueBuild copy module is one src/dest per
|
|
|
|
|
|
# entry per https://blue-build.org/reference/modules/copy/
|
|
|
|
|
|
# Net: 12 → 7 modules, ~5×40min ≈ 3h20min off wallclock budget.
|
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
|
|
|
|
---
|
|
|
|
|
|
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.
|
2026-05-06 17:15:54 +01:00
|
|
|
|
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 ──────────────────────────────────
|
2026-05-07 01:55:08 +01:00
|
|
|
|
# `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.
|
2026-05-08 04:27:44 +01:00
|
|
|
|
#
|
|
|
|
|
|
# NOTE: Each copy module = one COPY layer (~40min commit on our
|
|
|
|
|
|
# runner). BlueBuild's copy module accepts a single src/dest pair
|
|
|
|
|
|
# only, so these four entries are the floor unless we move to a
|
|
|
|
|
|
# hand-rolled Containerfile.
|
2026-05-07 01:55:08 +01:00
|
|
|
|
- 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
|
|
|
|
|
2026-05-07 01:55:08 +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
|
|
|
|
|
2026-05-07 01:55:08 +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
|
|
|
|
|
2026-05-08 04:27:44 +01:00
|
|
|
|
- type: copy
|
|
|
|
|
|
source: config/just
|
|
|
|
|
|
destination: /usr/share/ublue-os/just
|
|
|
|
|
|
|
|
|
|
|
|
# ── 2. All package layering in one rpm-ostree pass ──────────────
|
|
|
|
|
|
# secureblue removes sudo + replaces with run0 (too disruptive for
|
|
|
|
|
|
# daily-driver) — restore. Xwayland was disabled for attack-surface
|
|
|
|
|
|
# reduction — restore for Element/Slack/Qt5 apps. Mullvad Browser
|
|
|
|
|
|
# layered alongside Trivalent (Trivalent default per STRATEGY.md;
|
|
|
|
|
|
# Mullvad for pseudonymous browsing). Mesh stack: Tailscale (Layer
|
|
|
|
|
|
# 1, daily driver, pre-disabled), Yggdrasil-go (Layer 2, idle warm-
|
|
|
|
|
|
# fallback). Reticulum/RetiNet stays opt-in via ujust. Memory
|
|
|
|
|
|
# hygiene + ergonomic deps for veilor-postinstall + veilor-doctor.
|
|
|
|
|
|
#
|
|
|
|
|
|
# Collapsed from 5 rpm-ostree modules → 1 to drop 4 layer commits
|
|
|
|
|
|
# (~160min wallclock on our buildah+fuse-overlayfs runner).
|
|
|
|
|
|
- type: rpm-ostree
|
|
|
|
|
|
install:
|
|
|
|
|
|
- sudo
|
|
|
|
|
|
- xorg-x11-server-Xwayland
|
|
|
|
|
|
- mullvad-browser
|
|
|
|
|
|
- tailscale
|
|
|
|
|
|
- yggdrasil
|
|
|
|
|
|
- zram-generator
|
|
|
|
|
|
- jq
|
|
|
|
|
|
- vim-enhanced
|
|
|
|
|
|
- tmux
|
|
|
|
|
|
- htop
|
|
|
|
|
|
|
|
|
|
|
|
# ── 3. Branding overrides + systemd unit toggles in one RUN ─────
|
2026-05-07 04:54:09 +01:00
|
|
|
|
# Use raw `type: containerfile` (RUN line) instead of `type: script`
|
2026-05-08 04:27:44 +01:00
|
|
|
|
# / `type: systemd` — bluebuild's helper scripts fail 'chmod:
|
|
|
|
|
|
# Operation not permitted' on their own bind-mounted layer under
|
2026-05-07 04:54:09 +01:00
|
|
|
|
# podman/buildah privileged. Raw RUN bypasses the helper.
|
2026-05-08 04:27:44 +01:00
|
|
|
|
#
|
|
|
|
|
|
# Single snippet (= single layer) merges:
|
|
|
|
|
|
# - brand sed of /etc/os-release + GRUB_DISTRIBUTOR
|
|
|
|
|
|
# - kde-theme + v03-theme apply scripts
|
|
|
|
|
|
# - plymouth default-theme
|
|
|
|
|
|
# - chmod +x on shipped veilor-* scripts/binaries
|
|
|
|
|
|
# - fc-cache rebuild
|
|
|
|
|
|
# - systemctl enable yggdrasil + veilor-{firstboot,modules-lock,
|
|
|
|
|
|
# postinstall}.service + veilor-doctor.timer
|
|
|
|
|
|
# - systemctl disable tailscaled (Day-1-disabled per threat model)
|
|
|
|
|
|
#
|
|
|
|
|
|
# brand-leak grep moved to CI smoke-test in build-bluebuild.yml
|
|
|
|
|
|
# (STEP 14 hung under buildah overlayfs, run 171 2026-05-07).
|
2026-05-07 04:54:09 +01:00
|
|
|
|
- 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:
|
|
|
|
|
|
- |
|
2026-05-07 04:54:09 +01:00
|
|
|
|
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 ; \
|
2026-05-08 04:27:44 +01:00
|
|
|
|
fi ; \
|
|
|
|
|
|
systemctl enable yggdrasil.service 2>/dev/null || true ; \
|
2026-05-07 04:54:09 +01:00
|
|
|
|
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
|
|
|
|
|
2026-05-08 04:27:44 +01:00
|
|
|
|
# ── 4. signing config ───────────────────────────────────────────
|
2026-05-06 17:48:58 +01:00
|
|
|
|
# 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.
|
2026-05-08 04:27:44 +01:00
|
|
|
|
- type: signing
|