Wheelhouse docs

sign.sh#

Three verbs: build a manifest of what you are about to ship, sign a file, and verify one. verify is the half that matters and the half that works today — it runs everywhere, needs no key material of ours, and is what a customer runs. sign refuses rather than inventing a key.

bash
install/sign.sh manifest agent/wheelhouse-agent ui/dist
install/sign.sh verify SHA256SUMS

Usage#

sign.sh manifest <binary> [ui_dist_dir]   build wheelhouse.manifest beside <binary>
sign.sh sign <file>...                    write a detached <file>.asc for each
sign.sh verify <checksum-file> [sig]      check the sums, then the signature
sign.sh <binary> [ui_dist_dir]            same as `manifest` (older callers)

Environment#

VariableUsed byMeaning
RELEASE_SIGNING_KEYsignThe GPG key id, fingerprint or user id to sign with.
GPG_PASSPHRASEsignOptional; enables batch signing on a runner.
WHEELHOUSE_PUBKEYverifyAn armoured public key file to verify against. Without it, the caller's own keyring is used.
REQUIRE_SIGNATUREverifySet to 1 to make verify fail when nothing is signed.

manifest#

Writes wheelhouse.manifest beside the binary: a header line with a UTC timestamp, then one sha256sum-format line per file.

Wheelhouse manifest 2026-09-02T21:03:11Z
5c1f…  agent
9a02…  ui/index.html
1d77…  ui/assets/index-4f2a1c.js

The paths name the shipped layoutagent beside ui/ — not where the inputs sat when the manifest was built, so sha256sum -c works inside the bundle you distribute rather than only on the machine that made it.

sign#

A detached, armoured signature per file: <file>.asc. An existing one is removed first rather than appended to.

verify#

Two steps, in this order, and the first one is not optional:

  1. The sums. If the file holds lines matching ^[0-9a-f]{64} , they are checked with sha256sum -c from the file's own directory — so a manifest's relative paths resolve. A mismatch is fatal: checksums do not match — do not install this build. A file with no such lines is treated as a plain artefact to verify a signature over.
  2. The signature. Given explicitly, or found automatically as <file>.asc then <file>.sig.
SituationResult
No signature found, REQUIRE_SIGNATURE unsetSays so, and says plainly that checksums proved the download survived the network, not who built it. Exit 0.
No signature found, REQUIRE_SIGNATURE=1Fatal.
Signature found, WHEELHOUSE_PUBKEY setImported into a throwaway keyring in a temporary directory, verified there, and the keyring is deleted — so verifying a download never touches the caller's own keyring.
Signature found, no WHEELHOUSE_PUBKEYVerified against the caller's keyring, with a message naming both fixes if it fails.

Verifying a release download#

bash
curl -fsSLO https://releases.rhymelikedi.me/latest/SHA256SUMS
curl -fsSLO https://releases.rhymelikedi.me/latest/wheelhouse-0.5.1-amd64.iso
install/sign.sh verify SHA256SUMS

Or without this script at all:

bash
sha256sum --ignore-missing -c SHA256SUMS

Both are checksum verification. Neither is a signature, and neither will be until a key exists.

See also#

Checked against#

install/sign.sh (build_manifest, sign_files, verify_file, usage), .forgejo/workflows/publish.sh, .forgejo/workflows/release-index.py, docs/deploy.md "Releases and update channels", docs/security.md "Verifying what you downloaded".

Updated 2026-09-02 tools checksums signing verification