security(apt): sign the published APT repository - #35
Merged
Conversation
The APT repo shipped no InRelease and no Release.gpg, so the install instructions needed [trusted=yes] -- which tells apt to skip signature verification entirely. That is worse than average here: the package installs a root-invoked fan helper plus a polkit rule, and dpkg maintainer scripts run as root. HTTPS authenticates the host during the transfer; it says nothing about whether the bytes on gh-pages, or in any cache in front of it, are the ones CI built. Signs Release into InRelease and Release.gpg when APT_GPG_PRIVATE_KEY is configured, publishes the public half, and switches the generated index.html to signed-by= instructions. With no key set it publishes unsigned as before but warns -- and deletes any previously published signature, because a stale InRelease beside a regenerated Release breaks apt update outright, which is worse for users than unsigned. Also declares apt-utils: the step calls apt-ftparchive but installed only dpkg-dev, working by luck of the runner image preinstalling it. Verified by extracting the step from the YAML and running it against a throwaway key: signatures verify against the published public key alone, a tampered Release is rejected, and removing the key deletes the stale signature files and reverts the index. docs/development/apt-signing.md covers key generation and the two secrets.
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
thinkutils | 27e6064 | Jul 20 2026, 02:58 AM |
vietanhdev
added a commit
that referenced
this pull request
Jul 20, 2026
The install instructions hand users a flag that disables apt's signature verification, next to a package that installs a root-invoked helper, with no indication that either fact is true. States what the flag does, offers the manual .deb path for anyone not willing to take that trade, and points at the signing doc. Also adds apt-signing to the Development sidebar -- it shipped in #35 but was reachable only by knowing the URL. These instructions revert to signed-by= automatically once a signing key is configured; the release workflow generates the page from whichever form it actually published.
vietanhdev
added a commit
that referenced
this pull request
Jul 20, 2026
The install instructions hand users a flag that disables apt's signature verification, next to a package that installs a root-invoked helper, with no indication that either fact is true. States what the flag does, offers the manual .deb path for anyone not willing to take that trade, and points at the signing doc. Also adds apt-signing to the Development sidebar -- it shipped in #35 but was reachable only by knowing the URL. These instructions revert to signed-by= automatically once a signing key is configured; the release workflow generates the page from whichever form it actually published.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
The APT repo at
gh.vietanh.dev/ThinkUtils/aptpublishesRelease,Packages, andPackages.gz— but noInReleaseand noRelease.gpg. It is entirely unsigned, which is why the install instructions need[trusted=yes], a flag that disables apt's signature checking outright.That matters more here than for a typical repo: this package installs a root-invoked fan helper plus a polkit rule, and dpkg maintainer scripts run as root. HTTPS authenticates the host for the duration of the transfer; it says nothing about whether the bytes sitting on
gh-pages, or in any cache in front of it, are the ones CI built.The change
ReleaseintoInRelease+Release.gpgwhenAPT_GPG_PRIVATE_KEYis configured, and publishes the public half asthinkutils-archive-keyring.ascindex.htmlswitches tosigned-by=instructions when signed::warning::— releases keep working todayInReleasenext to a regeneratedReleasebreaksapt updateoutright, which is worse for users than being unsignedapt-utils: the step callsapt-ftparchivebut installed onlydpkg-dev, working purely by luck of the runner image preinstalling itVerification
The step's shell was extracted from the YAML and run against a throwaway key, so the logic under test is the shipped logic, not a paraphrase:
Releaseis rejectedtrusted=yesformAction required to actually turn this on
This needs a signing key, which is yours to create — see
docs/development/apt-signing.md. UntilAPT_GPG_PRIVATE_KEYandAPT_GPG_PASSPHRASEare set as repo secrets, releases stay unsigned (with a warning). Nothing breaks in the meantime.