Skip to the content
Back to Nymchat

Knowledge base Under the hood

Verifying the build

Open source only helps if the code you are running is the code that was published. Nymchat is built deterministically so you can check that yourself, from inside the app or from a terminal.

Reproducible builds

Building the app emits a build-manifest.json containing the source commit, a SHA-256 hash of every served HTML, JavaScript and CSS asset, and a single bundleHash over that whole asset set.

The output depends only on the source content — even the recorded build time is the commit's timestamp rather than the moment the build ran — so anyone rebuilding the same commit gets byte-identical files and the same bundleHash.

A GitHub Action then rebuilds each commit independently and signs build-provenance attestations for the hash and the manifest, so there is a signed record tying a bundleHash to a commit in the repository, produced by something other than the deployment.

What the About dialog checks

About in the header runs the check live, in your browser.

The Nymchat About dialog, showing the version, build integrity and warrant canary status.
The About dialog: version, build integrity, warrant canary and a direct line to the developer.

It re-fetches each asset the page is actually running, hashes it with the Web Crypto API, and compares against the manifest. Then — and this is the part that matters — it recomputes the bundleHash from the hashes it just calculated, not from anything the manifest claims, and looks that up in the repository's signed attestations through the GitHub API.

That is what stops a deployment from vouching for itself: serving modified files together with a matching manifest still fails, because the recomputed hash has no attestation.

StatusMeans
✓ Verified official app (n/n)Every asset matches, the recomputed bundle hash is attested by the repository, and the page is served from the official domain.
⚠ Verified build · not the official appThe code is genuine and attested, but this is a mirror on another domain. A mirror cannot remove this warning without failing verification.
✗ MismatchAn asset does not hash to what the manifest says.
✗ Unofficial buildThe recomputed bundle hash has no attestation from the repository — a self-made manifest.
⚠ Provenance unreachableThe GitHub API could not be reached, so the attestation could not be checked either way.

Verifying it yourself

Rebuild the commit the About dialog names and compare:

git clone https://github.com/Spl0itable/NYM
cd NYM
git checkout <commit shown in the About dialog>
npm ci
npm run build   # prints "Build hash: <bundleHash>"

The printed hash should match both the one in the About dialog and the one in that commit's build-provenance run summary. You can also check the signature directly with the GitHub CLI:

gh attestation verify dist/build-manifest.json --repo Spl0itable/NYM

The warrant canary

A warrant canary is a statement, published on a fixed schedule, that the developer has not received a secret government order they are forbidden to disclose — a National Security Letter, a FISA order. The developer can be compelled to stay silent about such an order, but cannot be compelled to lie, so the canary going stale or disappearing is itself the signal.

It lives in canary.json at the root of the repository and is fetched directly from GitHub, so its history is auditable independently of whatever the deployed site says. The About dialog colour-codes it:

ColourMeans
Green — all clearSigned, current, and the signature matches the developer's key. No secret order has been received.
Yellow — overdue, or not all clearIt was not refreshed by its stated date, or its allClear flag is false. A silenced order cannot be ruled out.
Red — invalid signature, or goneThe signature does not match the developer's key, or the file has been removed entirely. Treat this as a serious warning.

The freshness anchor

The signed canary embeds the latest Bitcoin block height and hash at the moment of signing. That hash could not have been known before the block existed, which proves the canary was signed after a specific point in time rather than pre-signed in bulk months earlier. The About dialog links the anchor to a block explorer so you can check it.