From 7addeb691a31b59d2c287a8c532b327af4576885 Mon Sep 17 00:00:00 2001 From: Douglas Teles Date: Tue, 23 Jun 2026 23:27:27 -0300 Subject: [PATCH] pacman: drop per-package signing, sign only the repo db First repo-dev release uploaded 1000/1078 assets before hitting GitHub's documented per-release limit of 1000 assets. The cap is hit because every package shipped a paired .sig, doubling the count without adding meaningful security. The trust path now flows entirely through the database: - archr-keyring ships the master public key. - archr.db.sig proves the db came from the maintainer. - The db records the SHA256 of every package; pacman re-hashes after download and refuses mismatches. To compromise a package the attacker would have to publish a modified db that lists their hash, which requires the signing subkey. The per-package .sig was redundant against this attack. This is the same model Arch Linux ARM, EndeavourOS and SteamOS use in production. pacman.conf SigLevel flips from "Required DatabaseOptional" to "PackageOptional DatabaseRequired"; comment expanded so a future reader sees the why. gen-pacman-repo drops the `gpg --detach-sign` step inside build_one_pkg(); repo-add --sign still signs the db at the end. Asset count shrinks from 1078 to 543 (535 packages + 8 db artifacts), which fits comfortably in a single GitHub Release. Co-Authored-By: Claude Opus 4.7 --- .../packages/sysutils/pacman/config/pacman.conf | 14 ++++++++++---- scripts/repo/gen-pacman-repo | 9 ++++++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/projects/ArchR/packages/sysutils/pacman/config/pacman.conf b/projects/ArchR/packages/sysutils/pacman/config/pacman.conf index 24a84d17ed..6869965ee3 100644 --- a/projects/ArchR/packages/sysutils/pacman/config/pacman.conf +++ b/projects/ArchR/packages/sysutils/pacman/config/pacman.conf @@ -17,10 +17,16 @@ HookDir = /etc/pacman.d/hooks/ HoldPkg = pacman glibc bash linux archr-keyring Architecture = aarch64 -# Signature checking. Required is the target once archr-keyring ships -# the production master key; DatabaseOptional during bootstrap because -# the .db files in the first releases may not be signed yet. -SigLevel = Required DatabaseOptional +# Signature checking. The archr repo signs the database (.db) with the +# production master subkey; individual packages are unsigned because +# GitHub Releases caps a single release at 1000 assets and the per-pkg +# .sig files double the count past that limit. The trust path is: +# 1. archr-keyring ships the master public key. +# 2. archr.db.sig proves the db came from us. +# 3. The db lists SHA256 of every package; pacman re-hashes after +# download and refuses mismatches. +# This is the same model Arch Linux ARM, EndeavourOS and SteamOS use. +SigLevel = PackageOptional DatabaseRequired LocalFileSigLevel = Optional CheckSpace diff --git a/scripts/repo/gen-pacman-repo b/scripts/repo/gen-pacman-repo index 63fe6564a9..4cef162cda 100755 --- a/scripts/repo/gen-pacman-repo +++ b/scripts/repo/gen-pacman-repo @@ -123,9 +123,12 @@ EOF ) rm -f "${pkginfo}" - if [ -n "${SIGNER}" ]; then - gpg --batch --yes --detach-sign --use-agent --local-user "${SIGNER}" "${outfile}" - fi + # Per-package signing is intentionally NOT done here. The repo db + # carries the SHA256 of every pkg.tar.zst and is itself GPG-signed, + # which gives pacman an unbroken trust chain without doubling the + # asset count on GitHub Releases (1000-per-release cap). + # The signer is still passed to repo-add below so the db gets its + # own .sig and trust flows from there. echo " + ${name} ${version}-${pkgrel}" }