Reference
Verifying the kit
The kit is published as a signed release. The signature is Sigstore keyless: there is no Metergrade key to trust, and the signing identity is the release workflow itself, recorded in the certificate.
The trust chain, in the only direction it works
Sigstore identity authenticates manifest.json
manifest.json authenticates the verifier and every kit artifact
the verifier checks the complete kit policy
The bundled verifier is convenience. Sigstore and the signed manifest are the authority.
Normal use
./verify (macOS, Linux)
verify.cmd (Windows)
Needs Node 18+ and cosign.
| Exit | Meaning |
|---|---|
0 |
Verified. Signed by the Metergrade release, and the files match the signed manifest. |
1 |
Do not run this kit. It is not what it claims to be. |
3 |
Contents are internally consistent, but the signature was not checked. Nothing shows Metergrade produced it. |
A missing cosign is a failure, not a skip. A check that turns "could not run" into success is how a green result comes to mean nothing.
High assurance: do not start by running our code
Establish the manifest first, then use it to establish the verifier, then run it.
1. cosign authenticates the manifest.
cosign verify-blob \
--signature manifest.json.sig \
--certificate manifest.json.pem \
--certificate-identity-regexp '^https://github\.com/Metergrade/metergrade-platform/\.github/workflows/release-setup-kit\.yml@refs/' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
manifest.json
Do not relax the identity to a wildcard. That accepts a signature from anyone, and proves only that a signature exists.
2. The authenticated manifest establishes the verifier. Compare the
metergrade-verify.mjs entry in manifest.json with the file on disk:
sha256sum metergrade-verify.mjs
3. Now run it.
node metergrade-verify.mjs .
Or skip step 3 entirely — manifest.json lists every artifact with its
sha256, and checksums.sha256 is the same data in sha256sum -c form. Two
things that shortcut does not do, and the verifier does: confirm that no file
is present which the manifest does not list, and recompute content_hash
from the files rather than reading it back out of the manifest.
Two digests, two different claims
| Digest | What it proves |
|---|---|
content_hash |
The kit's identity. A digest over sorted path and hash pairs, so it reproduces on any machine from the contents alone. This is what the signature binds. |
archive_sha256 |
Only that the download arrived intact. A ZIP embeds timestamps and ordering, so two honest builds of the same contents differ. |
Conflating them would let a correct-looking checksum vouch for the wrong contents.
What the signature covers is what this site serves
Every file offered on /setup is covered by the signed manifest at
the same sha256. The publishing step refuses to ship a release whose
manifest disagrees with the queries the site renders, and a test asserts the
same thing against the live site — because a signature over something other
than what you just read would be worse than no signature at all.