Files
SilverMetal/linux
SysAdmin e260fe1c81
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / builder-image (push) Failing after 2s
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Has been skipped
ci(linux/build): self-host the builder image build + iter16 reprepro wrap (M1.1)
Two coupled changes that unblock the M1.1 iter loop. Both belong in CI;
iter1-15 was wrong to require human-in-the-loop steps to make progress.

1. **CI now builds Dockerfile.builder.**

   `.gitea/workflows/build-iso-linux.yaml` grows a `builder-image` job
   that runs ahead of `build-and-verify`. It rebuilds the silvermetal-
   builder image from `linux/build/docker/Dockerfile.builder`, pushes it
   to `docker-registry.silverlabs.uk/silvermetal-builder:m1.1-<sha>` (and
   `:latest`), reads the resulting digest off `docker inspect`, and
   feeds it forward as a job output. `build-and-verify` consumes that
   digest as the `BUILDER_IMAGE` env override that `build.sh` already
   honours (and validates is digest-form on line ~37).

   That kills the old workflow where every Dockerfile.builder change
   required a human to `docker build` + `docker push` on 10.0.0.51 by
   hand and then bump the digest in `build.sh` in lockstep. The crash
   that triggered this (exit 126 mid-iter16 build run) was a symptom of
   that off-CI step still existing.

   Both jobs run on the existing `silvermetal-builder` runner; the host
   docker daemon is shared via DooD and is already authenticated to
   `docker-registry.silverlabs.uk` (linux/build/runner/docker-compose.yml
   mounts `/root/.docker:/root/.docker:ro`), so no extra login step.

   The hardcoded `BUILDER_IMAGE` digest in `build.sh` stays as the
   local-developer / offline-rebuild fallback. Comments updated in
   `build.sh`, `Dockerfile.builder`, and `linux/build/README.md` to
   match the new flow.

2. **reprepro wrapper for the benign "No priority for X" case.**

   Pinned derivative-maker's `2100_create-debian-packages` (with
   --target iso) re-imports source packages from snapshot.debian.org
   into a local apt repo via `reprepro --basedir … includedsc local
   <foo>.dsc`. The local repo's `conf/distributions` ships no
   `DscOverride` entries, so any source package whose `.dsc` lacks an
   explicit Priority field trips:

       No priority for 'X', skipping.
       There have been errors!

   …and reprepro exits 255. dm-reprepro-wrapper bubbles that up,
   2100_create-debian-packages aborts. The current offender is
   `virtualbox_*.dsc` (key import is now fine — debian-keyring landed in
   commit 4aa59ba — but the priority field gap remains). VirtualBox is
   not in SilverMetal's `--target iso` set, so the sane behaviour is
   "log it, continue".

   New `linux/build/docker/silvermetal-reprepro-wrap.sh` shadows
   `/usr/bin/reprepro` at `/usr/local/bin/reprepro` (PATH precedence).
   It runs the real reprepro, captures merged stdout+stderr, and:
   - if rc != 0 AND every non-blank output line matches one of the
     known-benign patterns ("No priority for 'X', skipping." plus the
     trailing "There have been errors!"), emits the output, logs one
     line of explanation to stderr, and exits 0;
   - otherwise emits the output and propagates rc unchanged.

   Any *other* reprepro error path stays fatal — only the specific
   "No priority for X" pattern is neutralised. `dm-reprepro-wrapper`
   resolves `reprepro` via `\$PATH` so it picks up the wrapper
   transparently.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:30:08 +01:00
..

SilverMetal OS — Linux

Status: Phase 1 (planning) → moving to milestone 1.1 (reproducible Kicksecure fork build)

🔒 SilverMetal OS product line — we ship the operating system.

The reference SilverMetal flavour. Tier A — full kernel-level hardening, verified boot we control, Debian/Kicksecure-based.

Scope (v1)

See ../docs/roadmap.md Phase 1.

Hardening must-haves

  • Kicksecure base (Debian-derived, hardened upstream)
  • linux-hardened kernel + KSPP sysctl/build flags
  • Secure Boot with our shim/MOK
  • TPM2 PCR-bound LUKS2 unlock (Argon2id), full-disk encryption mandatory
  • AppArmor strict profiles for browsers, mail, viewers, networked daemons
  • GrapheneOS hardened_malloc as system allocator
  • bubblewrap + Flatpak primary; firejail for legacy .deb
  • nftables default-deny inbound, encrypted DNS, SilverVPN always-on default
  • Zero upstream telemetry — verified by integration test
  • SilverBrowser default (ungoogled-chromium-rebranded v1)
  • SilverVPN integrated from existing SilverLABS/SilverVPN (Linux client + tunnel service)
  • SilverSync v1 (Nextcloud-backed, client-side encryption)
  • A/B updates with rollback, signed by our keys
  • Optional amnesic session mode

Out of scope (v1)

  • Atomic / immutable root (v1.1 — ostree experiment)
  • dm-verity on / (v1.1)
  • ARM64 / Apple Silicon (v2)
  • Tor-by-default variant (sibling product later)

Directory layout

linux/
├── build/             # live-build pipeline, reproducible-build config
├── kernel/            # config fragments, linux-hardened pinning
├── overlay/           # /etc + /usr/share/silvermetal + skel hardening overlay
├── packages/
│   ├── include.list   # what's installed
│   └── exclude.list   # what's purged (snap, telemetry, etc.)
├── apparmor/          # custom strict profiles
├── nftables/          # default ruleset
├── installer/         # Calamares branding + hardened defaults
├── update-server/     # signing + repo hosting (infra-as-code)
└── tests/
    ├── lynis-baseline/
    ├── kspp-check/
    └── telemetry-leak/

Verification gates (must pass before public alpha)

  • Two clean builds from same commit → identical SHA256
  • kconfig-hardened-check passes
  • Lynis hardening score ≥ 90
  • 30-min idle telemetry capture: zero packets to MS/Google/Apple/Mozilla/Canonical/Debian/analytics
  • TPM tamper test: LUKS correctly falls back to passphrase
  • AppArmor: every networked binary confined or documented
  • Independent privacy-engineering review

Upstream we depend on

  • Kicksecure — fork base
  • linux-hardened — kernel patchset
  • GrapheneOS hardened_malloc — allocator
  • KSPP — kernel config authority
  • secureblue — reference for v1.1 immutable design
  • SilverLABS/SilverVPN — VPN client + tunnel service (existing, integrated)