Download the signed SHASUMS256.txt.asc file for your Node.js version, verify its signature against the release keyring with gpgv, then check your downloaded file against the verified list using shasum. If either step fails, stop the build. Pin the version so the checksums do not move.
What the Node.js project publishes
The Node.js repository README states that download directories contain a SHASUMS256.txt.asc file. It holds SHA checksums for the files, plus the releaser's PGP signature. The README says you can get a trusted keyring from the nodejs/release-keys repository, or import the releaser keys into your default keyring.
Two checks therefore stack:
- The signature proves the checksum list was signed by a Node.js releaser key.
- The checksum proves your tarball matches an entry in that list.
A checksum alone, fetched from the same place as the file, only protects against a corrupted download. The signature is what protects against a replaced one. See checksum or signature: which to trust.
The documented commands
Fetch the keyring, then verify the checksum file and check your files. The README gives this sequence, here with a version variable and an example file name:
VERSION=vX.Y.Z # set to the exact version you pin
curl -fsLo nodejs-keyring.kbx "https://github.com/nodejs/release-keys/raw/HEAD/gpg/pubring.kbx"
curl -fsO "https://nodejs.org/dist/${VERSION}/node-${VERSION}-linux-x64.tar.xz"
curl -fsO "https://nodejs.org/dist/${VERSION}/SHASUMS256.txt.asc" \
&& gpgv --keyring="./nodejs-keyring.kbx" --output SHASUMS256.txt < SHASUMS256.txt.asc \
&& shasum --check SHASUMS256.txt --ignore-missing
The ignore missing option lets shasum check only the files you downloaded, since the list covers every file in the release. The gpgv step writes out the verified checksum text, so you check against the verified content rather than a file that was not verified.
Change the platform file name to the one you use. Do not run the extraction step unless the final command prints OK for your file.
Making it durable
| Risk | What to do |
|---|---|
| The keyring is fetched at build time from a moving branch | After a person has reviewed it, keep a copy in your repository, and update it deliberately |
| The version drifts | Pin the exact version in one place, such as a version file the build reads |
| The step is skipped locally | Put the check in a script the CI job and developers both run |
| A failure is ignored | Make the job fail on any non zero exit |
The keyring link in the README points at HEAD, which means it can change. That is why vendoring a reviewed copy is worth a few minutes.
If you install Node.js through a package manager or a container base image, you are trusting that source instead. In that case pin by digest and verify at that layer. See pinning base images by digest.
Wiring it into a pipeline
Keep the verification in a small script, and call that script from the CI job, your Dockerfile build or your developer setup. One script means one place to fix when the file layout changes.
A few details help in practice:
- Run the script with strict shell options, so any failing command stops the build, including the one inside a chain.
- Download into a temporary directory, verify there, and only then move or extract the file.
- Print the version and the verified file name in the log, so a later reviewer can see what was installed.
- Use the same pinned version in the build, the tests and the runtime image, so you are not verifying one release and shipping another.
When you upgrade Node.js, treat it like any dependency change. Update the version, rerun the script, and review the diff. Releases also carry security fixes, so an old pin that never moves has its own cost. A scheduled reminder to review the pin is cheap insurance.
Quick check
Is checking only the SHA-256 enough?
It catches corruption. Without verifying the signed list, an attacker who replaced the file could replace the checksum too.
Why use the ignore missing option?
The checksum file lists every release file. The option tells shasum to check only the ones you downloaded.
Safeguard's SBOM and dependency scanning, generally available, covers the packages your application uses. The free scan at gold.safeguard.sh/scan is a quick way to try it.
Sources
Last reviewed: 19 October 2026.