Verify release downloads
404 currently publishes two different manifest contracts. Use an explicit release tag throughout verification so a moving latest download does not mix versions. These instructions follow the STATIC workflow and distro workflow.
| Download family | Signed material | Trust anchor | What the digest covers |
|---|---|---|---|
Linux/native STATIC binary or macOS bundle’s static_proxy | static_proxy-release-manifest.json, .sig, .pem | Sigstore trust plus the exact GitHub workflow identity and OIDC issuer. | Listed raw STATIC binaries. |
| Windows WSL distro | 404-distro-manifest.json and .sig (or public-origin manifest.json and .sig) | Separately trusted distro signing public key. | 404-distro.tar.gz. |
The current manifests do not hash the complete operator ZIP, profile catalog, or config/token files. Verify the signed binary/tarball and inspect the remaining bundle contents; do not describe the entire ZIP as authenticated by these manifests.
Prepare your tools
Install Node.js (20 or later) and obtain the verification helper. Review its source before use. distro mode authenticates a manifest and checks its tarball; hash mode only checks a binary against a manifest that you must first authenticate with Cosign. Both reject an unexpected version or hash and return a nonzero exit code on failure.
For STATIC, install a trusted, maintained Cosign build and review its verify-blob --help. The current release workflow publishes separate certificate/signature files rather than a Sigstore bundle. The commands below use that legacy file contract; do not replace it with an invented bundle filename or disable certificate/transparency checks to get a success.
STATIC: verify the signing identity
Download the manifest, signature, certificate, and binary from one selected tag on GitHub Releases. On Linux/macOS, run in the directory containing those files:
RELEASE_TAG=vX.Y.Z # replace with the exact tag you downloaded
cosign verify-blob static_proxy-release-manifest.json \
--certificate static_proxy-release-manifest.json.pem \
--signature static_proxy-release-manifest.json.sig \
--certificate-identity "https://github.com/un-nf/404/.github/workflows/static-release.yml@refs/tags/$RELEASE_TAG" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
The issuer and identity are constraints you supply; do not derive them from an untrusted downloaded certificate. The workflow normalizes the certificate to PEM; Cosign consumes the base64 signature file. Verification may need Sigstore network services for trust and transparency evidence. If your Cosign version requires a verification bundle unavailable in that release, stop and obtain compatible verification material from the publisher rather than using --insecure-ignore-tlog or another bypass. Sigstore’s verification documentation explains the current supported contracts.
On Windows PowerShell, use the same arguments with PowerShell backticks as continuation characters, or put the command on one line. The verifier helper commands below also work as single-line node commands on Windows.
STATIC: check the selected binary
After Cosign succeeds, check the raw binary against the corresponding manifest entry:
node verify-release.mjs hash \
--manifest static_proxy-release-manifest.json \
--artifact static_proxy-linux-x86_64 \
--name static_proxy-linux-x86_64 --version "$RELEASE_TAG"
| Platform / file on disk | --name in the signed manifest |
|---|---|
Linux static_proxy-linux-x86_64 | static_proxy-linux-x86_64 |
Apple Silicon bundle’s 404-runtime/static_proxy | static_proxy-macos-aarch64 |
Intel Mac bundle’s 404-runtime/static_proxy | static_proxy-macos-x86_64 |
Native Windows .exe (not the normal WSL operator path) | static_proxy-windows-x86_64.exe |
For the macOS ZIP, extract into a staging directory first and verify the manifest files and static_proxy there before installing or executing it. The binary has been renamed inside the bundle; --name selects its original release asset name. The helper checks that exactly one entry matches.
WSL distro: establish the public-key trust
The distro workflow signs the exact manifest bytes, writes a base64 detached signature, and does not publish the signing public key among the listed operator assets. The existing desktop documentation describes an embedded Ed25519 verifier key, but the private application source was unavailable for this revision. A manual operator therefore needs a separately trusted Ed25519 public key in PEM form, with its identity/fingerprint confirmed through an independent maintainer channel. Do not accept a key merely because it came alongside the tarball.
A maintainer who already controls the release signing key can export only its public half with openssl pkey -in <private-key-file> -pubout -out distro-public-key.pem and publish the public-key fingerprint through the established trust channel. This is a maintainer operation, not a reason for operators to obtain the private key. Public-key publication remains a release-infrastructure requirement; this guide cannot invent a trusted key.
WSL distro: verify signature, version, and tarball
Place 404-distro-manifest.json, 404-distro-manifest.json.sig, 404-distro.tar.gz, the helper, and your trusted public PEM in a staging directory. Do not reformat the manifest before verification.
node verify-release.mjs distro \
--manifest 404-distro-manifest.json \
--signature 404-distro-manifest.json.sig \
--key distro-public-key.pem \
--artifact 404-distro.tar.gz --version vX.Y.Z
For the public update origin, substitute the downloaded manifest.json and manifest.json.sig; fetch the tarball from the authenticated manifest’s versioned /distro/<tag>/404-distro.tar.gz path. The helper requires the expected tag and that path before accepting the digest. If signature, version, path, or hash verification fails, stop before importing the distro. A plain Get-FileHash comparison is useful for mismatch detection, but it is not this signature-verification step.
For installation after verification, return to Windows, macOS, or Linux.