Repo signing signs whatever is in the package registry #40
Labels
No labels
P0
P1
P2
P3
audio
bakery
boot
breadbug
bug
build
ci
dependencies
design
disk
docs
encryption
final
firewall
graphics
hardware
idle
installer
keybinds
nvidia
packages
phase-1
polish
recovery
reliability
reproducibility
secure-boot
security
shell
signing
snapshots
supply-chain
swap
tech-debt
theming
ux
website
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Breadway/bos#40
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
scripts/ci-publish-signed-repo.shcollect_from_registry(line 229) downloads every package from the Forgejo package registry and signs it withrepo-add -s, with no provenance check. Anyone who can write to that registry gets their package signed and pushed to all installs.Fix
pkgverper package, plus sha256 values recorded by the build workflow that produced each package (e.g. a build-provenance JSON committed or attested per package), and refuse to sign anything that doesn't match.Acceptance
Upload a tampered package to the registry, and the publish job refuses to sign it.
Source: BOS v0.6.2 source review (tag dated 2026-09-19); line numbers refer to that tree. Read AGENTS.md first. One issue per branch/PR.
Investigation found no trusted package provenance source to validate against.
scripts/ci-publish-signed-repo.shparses name/filename from the registry database, then signs the downloaded registry bytes. The five BOS package workflows (calamares, bibata, powerlevel10k, yay-bin, python-pywal) only PUT the package and do not emit a checksum attestation.breadlockandzen-browser-binare also in the signer allowlist but have no package build workflow in this repository. The registry metadata and.PKGINFOare supplied by the same upload, so checking name/version there cannot detect a same-version tampered package.A checked-in
pkgver/SHA256 allowlist would reject the tampered upload, but there is no trusted digest update path today and it would need to be refreshed for every rebuilt package. Forgejo v15 also does not support retrieving artifacts from other workflow runs, so the existingworkflow_runtrigger cannot safely collect prior run artifacts directly.Recommended direction: establish a trusted per-package provenance channel for all seven packages (including breadlock and zen-browser-bin), bound to the producing workflow/ref, then make the signer fail closed unless both the expected package name/version and SHA256 match that attestation. The provenance must be outside the attacker-writable Arch package registry or cryptographically authenticated with a separate trust anchor. I left BOS-40 in TODO pending that design/configuration decision, without opening a speculative PR.
PR: #78
Implemented protected exact-version/SHA256 allowlisting and build-candidate provenance, stacked on BOS-39 PR #75. Registry metadata no longer chooses signed packages. Same-version tampered registry downloads, local overrides and offline sign-only input fail before signatures; valid packages get real throwaway-key pacman package/database signatures. The prior published tree remains intact on failure.
Verified the committed bootstrap database/signature against pinned repository key 56203B86A110695AE7F310934AF3323D678EB5E2. Tests independently recheck that evidence, strict file/identity/policy validation, provenance recording, YAML/shell blocks, Python compilation and diff checks. New build entries require reviewed protected-main policy advancement, including the separate breadlock producer. No production registry tampering, live configs, desktop or keys were used.
Independent review of PR #78 at
7716e35247c8bcc910cec5bb39f50006ac0c6958Acceptance interpretation: an archive replaced in the Forgejo registry under the same package name/version must be rejected before the signer creates a signature or changes the published repository.
scripts/package-provenance.py:34-60,89-106requires an exact protected name, version, architecture, filename and SHA-256 set.scripts/ci-publish-signed-repo.sh:88-98,140-160checks those bytes before signing and requests approved filenames directly.scripts/test-package-provenance.py:74-94exercises a same-version payload replacement against a loopback registry and checks the prior tree and lack of signatures. The bootstrap database and detached signature are checked against the pinned repository identity in the same test. These are behavioral checks, not just structure assertions.The code is ready for the BOS release maintainer's review. PR #78 is mergeable but stacked on BOS-39 PR #75, so #75 must land first and #78 should then target main. Forgejo reports no CI statuses on this head. The offline signing key migration and protected policy approval remain activation gates; this review does not imply those have happened. No merge attempted.