Verify a Breeze Installer
Every Breeze release publishes checksums.txt and a signed
release-artifact-manifest.json next to its installers. The Windows MSI that Breeze
serves from the dashboard is the release file, byte for byte (the enrollment token
travels in the download filename, not inside the file), so its SHA-256 matches
the release entry exactly. The macOS dashboard download is different: it is a
bootstrap app zip (the token lives in bootstrap.json), so verify the
breeze-agent-darwin-*.pkg release assets directly instead.
1. Check the SHA-256 against checksums.txt
Section titled “1. Check the SHA-256 against checksums.txt”Download checksums.txt from the GitHub release for the same version as your
installer, then compare.
Get-FileHash .\breeze-agent.msi -Algorithm SHA256Select-String -Path .\checksums.txt -Pattern 'breeze-agent\.msi'The two hashes must be identical (case-insensitive).
shasum -a 256 breeze-agent-darwin-arm64.pkggrep 'breeze-agent-darwin-arm64.pkg' checksums.txtOr check every file you downloaded at once: shasum -a 256 -c checksums.txt --ignore-missing.
2. Verify the signed manifest (optional, stronger)
Section titled “2. Verify the signed manifest (optional, stronger)”checksums.txt is only as trustworthy as the place you downloaded it from. The
release also contains release-artifact-manifest.json, which lists every
asset’s sha256, size, and platformTrust, plus
release-artifact-manifest.json.ed25519, a base64 Ed25519 signature over the
exact bytes of the manifest. A .minisig signature over the same file is also
published. Your Breeze API performs this same check before it serves a release.
Verify with the official manifest public key (one key, base64, raw 32-byte or
SPKI form). Get it from a source independent of the download. Your own deployment’s
RELEASE_ARTIFACT_MANIFEST_PUBLIC_KEYS setting is a comma-separated list that
you already trust; it is a convenient copy of the key, but it only proves the
release matches what your server was configured with.
KEY_B64='<manifest public key>' node -e 'const { createPublicKey, verify } = require("node:crypto");const fs = require("node:fs");const raw = Buffer.from(process.env.KEY_B64, "base64");const spki = raw.length === 32 ? Buffer.concat([Buffer.from("302a300506032b6570032100", "hex"), raw]) : raw;const key = createPublicKey({ key: spki, format: "der", type: "spki" });const manifest = fs.readFileSync("release-artifact-manifest.json");const sig = Buffer.from(fs.readFileSync("release-artifact-manifest.json.ed25519", "utf8").trim(), "base64");console.log(verify(null, manifest, key, sig) ? "manifest signature OK" : "BAD SIGNATURE");'Then compare your file’s SHA-256 with the matching entry in assets[]. A
manifest that verifies and lists your hash is proof the file is what the release
published. If you sign your own packages, the manifest is signed with
your key; see Sign Your Own Agent Packages.
3. Signature expectations per platform
Section titled “3. Signature expectations per platform”Hash and manifest checks prove the file is the published one. The platform signature checks below tell you who published it.
| Asset | Expected result |
|---|---|
Windows agent .msi and .exe (public release) |
Unsigned. Get-AuthenticodeSignature reports NotSigned. This is expected; manifest platformTrust is none. |
| Windows agent signed by you (BYO signing) | Valid, with your certificate as signer and an RFC 3161 timestamp. |
| Windows Viewer and Helper installers | Valid, signer is LanternOps. |
macOS agent .pkg |
Developer ID Installer signed and notarized. |
Get-AuthenticodeSignature .\breeze-agent.msi | Format-List Status, SignerCertificate, TimeStamperCertificatepkgutil --check-signature breeze-agent-darwin-arm64.pkgspctl --assess --type install -vv breeze-agent-darwin-arm64.pkg # expect: accepted, source=Notarized Developer IDxcrun stapler validate breeze-agent-darwin-arm64.pkg