Uh oh!
There was an error while loading. Please reload this page.
feat(runtime): verify Node.js downloads with PGP signatures - #1848
Conversation
…Node Download the clearsigned SHASUMS256.txt.asc and verify it against the embedded Node.js release keys before trusting any checksum, so a tampered SHASUMS file cannot pass off a malicious archive whose hash it controls. Falls back to the plain SHASUMS256.txt for musl unofficial builds, which publish no signature. Closes#1807
✅ Deploy Preview for viteplus-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
The base64 armor in the vendored Node release keys trips crate-ci/typos; exclude the .asc assets and fix the real "unparseable" typo in code.
- Scope the ShasumsSignature import to non-musl so musl builds don't emit an unused-import warning (the symbol is only referenced under the same cfg). - Return String from verify_signed_shasums instead of Str so the caller can borrow it directly for parse_shasums, dropping two needless allocations and simplifying the error mapping to map_err.
fengmk2
commented
Jun 15, 2026
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:b0a3fad1dd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
…ature Requiring SHASUMS256.txt.asc on every non-musl source regressed VP_NODE_DIST_MIRROR users whose mirror ships only the archives plus the plain SHASUMS256.txt. Make signature verification mandatory only for the official nodejs.org source; for custom mirrors it is best-effort, falling back to the plain SHASUMS when the .asc is unavailable. A downloaded but invalid signature still fails everywhere.
fengmk2
commented
Jun 15, 2026
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:48df9085b1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Address two Codex review findings: - pgp_verify: a raw cryptographic match no longer suffices. Reject revoked signing keys, and require the signature's creation time to fall within the signing key/subkey validity window. This mirrors gpgv and stops a compromised, long-expired release key from signing a fresh SHASUMS for a current release, while genuine old signatures made when the key was valid still verify. - node: base whether the signature is required on the resolved host (nodejs.org) rather than merely whether VP_NODE_DIST_MIRROR is set, so a mirror pointed back at the official host still requires verification.
fengmk2
commented
Jun 15, 2026
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:1ed93d29e2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Address two Codex review findings on the PGP key-policy checks: - Subkey signing path now rejects non-signing or revoked subkeys: a matched subkey must carry a signing-capable binding signature (with a valid embedded primary-key back-signature) and must not be revoked, so a leaked encryption-only or revoked subkey secret can no longer pass the release- signing check. - Expiry is now evaluated against the self/binding signature effective at the release signature's creation time, not the loosest expiration across all self-signatures, matching gpgv when a key's expiry changes over time. Adds a regression fixture (v18.14.0, signed by a since-expired key) proving a genuine old signature still verifies.
fengmk2
commented
Jun 15, 2026
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:c967de5572
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Address Codex review findings: - Primary-key path now only lets the key's own self-issued certifications and direct signatures define its policy (third-party certifications are ignored), and rejects a primary marked certify-only, matching the rigor of the subkey path. - Document the two intentional limitations of the gpgv-style curated-keyring model: expiry is checked against the signature's self-asserted creation time (so it is defense-in-depth, not protection against a leaked key that backdates a forgery; revocation plus the curated keyring is the real boundary), and the vendored keyring is a snapshot that must be refreshed as Node's releaser set changes (a brand-new releaser's release fails closed until then).
fengmk2
commented
Jun 15, 2026
@codex review |
Codex Review: Didn't find any major issues. Keep them coming! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
The Round-3 change selected the self-signature "effective at the release signature time" (created on or before it), but a release key is often re-certified later (e.g. to extend its expiry). For such keys the only self-signature in the vendored keyring postdates older release signatures, so no self-signature was found and verification rejected legitimate releases (e.g. node-v20.18.0, whose signing key was re-certified after the release). Use the current (latest) self/binding signature to determine the effective expiry, as gpgv does. Adds a regression fixture for the re-certified-key case.
Enforcing key expiry diverged from the reference (gpgv) and rejected legitimate Node releases: gpgv reports such signatures good (exit 0) even when made after the signing key's expiry (e.g. node-v16.20.0, signed days after its key expired), and when the key was re-certified after the release (node-v20.18.0). The earlier expiry checks broke `vp env exec`/install and the CLI snap tests for those versions. Verification now mirrors gpgv against the curated release keyring: accept a cryptographically valid signature from a trusted, non-revoked key; a subkey signature additionally requires a signing-capable, validly-bound subkey so a leaked encryption-only subkey cannot sign. Expiry is not enforced (it is advisory in gpgv and is defeatable by backdating anyway); revocation and the curated keyring remain the trust boundary. Adds regression fixtures for the expired-at-signing and re-certified-key releases.
Document the design, gpgv-matching verification policy, mirror handling, and the intentional trust-model limitations (expiry not enforced, vendored keyring currency, rsa advisory).
Add a weekly workflow (update-node-release-keys.yml) that regenerates the embedded Node.js release keyring from nodejs/release-keys via a reproducible script and opens a PR for human review. The PR body includes a before/after diff of added/removed/modified keys (by fingerprint and user id). The keyring is never auto-merged, since it is the trust anchor for SHASUMS verification. Also relax the block-count test to be self-consistent with the vendored file (keeping a >=28 floor) so adding keys upstream needs no test edit, document the automation in the RFC, and allow the "fpr" gpg colon-record term in typos.
- update-node-release-keys.sh: decode gpg \xHH-escaped uids in the PR body (so e.g. "http\x3a//" renders as "http://"), clean up the temporary gpg homedirs instead of leaking them, and normalize CRLF/CR to LF before concatenation for deterministic output. - is_official_dist_host: strip userinfo, port, and a trailing dot so an official nodejs.org URL reached through those forms still requires the signature; add look-alike negative tests. - Document that primary_key_revoked honors self-revocations (Node release keys use no designated revokers).
- Extract resolve_shasums_content() to flatten the nested match in download_runtime_with_provider: an early return for the no-signature case and a single match (verify / propagate-if-required / warn-and-fallback), with identical behavior. - Remove the embedded_keys_parse test, which is subsumed by every_vendored_key_parses plus the >=28 floor in split_armored_blocks_finds_every_key.
Update HashVerification (signature/ShasumsSignature), the integrity section (now PGP-verifies the clearsigned SHASUMS256.txt.asc against the Node release keys, with mandatory/best-effort/musl-fallback behavior), the download-flow diagram, and the success criteria. Cross-link verify-node-shasums-signature.md.
The unofficial musl builds, and custom mirrors that publish only SHASUMS256.txt, have no PGP signature, so verification falls back to the SHA-256 checksum. Emit a user-facing warning on that path so users know the download was not signature-verified. The previous tracing::warn was invisible unless VITE_LOG was set, and the musl (no-signature) path warned nothing at all.
Uh oh!
There was an error while loading. Please reload this page.
…p in CI Print the no-signature/checksum-only warning via the shared vite_shared::output::warn helper (consistent styled "warn:" output) instead of a raw eprintln, and suppress it when running in CI where it is just noise.
The no-signature path (unofficial musl builds, or a mirror that publishes only SHASUMS256.txt) is an expected, non-actionable condition for those sources, not an anomaly: on musl it would fire on every install. Record it with tracing::debug! (visible via VITE_LOG) instead of a user-facing warning, which also makes the CI suppression unnecessary.
fengmk2
commented
Jun 16, 2026
@codex review |
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Add a "Prior art" section to the SHASUMS signature RFC comparing download verification across nvm, fnm, Volta, asdf-nodejs, mise, and nodenv. Most stop at SHA-256 checksums (or, for fnm, HTTPS only); only asdf-nodejs and mise also verify the PGP signature, and both require an external gpg. Documents why a built-in, dependency-free verifier justifies bundling rPGP and the keyring.
Allow skipping PGP signature verification of SHASUMS256.txt via the VP_NODE_SKIP_SIGNATURE_VERIFY env var, so a future keyring or certificate issue can be temporarily bypassed without blocking installs. The SHA-256 checksum is still verified (integrity preserved, only authenticity dropped), and a warning is printed on every skipped install. Mirrors asdf's NODEJS_CHECK_SIGNATURES and mise's signature opt-out; env-var only, no config or CI flag, so the secure path stays the unconditional default.
✅ Staging deployment successful! Preview: https://viteplus-staging.void.app/ |
…ry fix TEMP verification only: point at fengmk2/security-action@a2a9a4b (head of oxc-project/security-action#22, which ignores RUSTSEC-2023-0071). Revert to the upstream oxc-project pin once #22 is merged and released.
Reverts the temporary fork pin used to verify oxc-project/security-action#22. Re-pin to a released oxc-project version that includes the RUSTSEC-2023-0071 ignore once #22 is merged and tagged.
fengmk2
commented
Jun 23, 2026
deps on #1918 |
Uh oh!
There was an error while loading. Please reload this page.
Release vite-plus v0.2.2: the Vite+ Beta release. **Vite+ is now in Beta**: stable and ready for production adoption, fully open source under MIT. Read the announcement to see what Vite+ is about and where it is headed: [Announcing Vite+ Beta](https://voidzero.dev/posts/announcing-vite-plus-beta). On top of the Beta milestone, this release brings cross-version upgrades via `vp migrate`, an official Docker toolchain image on GHCR, zero-config runner-aware `vp build` caching, and PGP-verified managed Node.js downloads. ### Highlights - **`vp migrate` upgrades existing Vite+ projects across versions**: previous release notes told users not to run `vp migrate` for upgrades. It now runs from the global CLI when the local one is older, re-pins `vite-plus` and the `vite` -> `@voidzero-dev/vite-plus-core` alias across dependencies, overrides/resolutions, and catalogs in every workspace package, aligns `vitest` / `@vitest/*` by actual usage, and defaults to a version-only upgrade (pass `--full` to also run the first-time setup bucket: hooks, editor, agent files, lint migration) ([#1891](#1891)), by @fengmk2 - **Official Vite+ Docker toolchain image**: `ghcr.io/voidzero-dev/vite-plus` bundles `vp` plus a native build toolchain on `debian:bookworm-slim` (amd64/arm64, non-root). Since `vp` provisions the exact Node.js from `.node-version`, one image builds any project, and a documented multi-stage build copies the resolved Node.js into a small vp-free runtime stage ([#1944](#1944)), by @fengmk2 - **Zero-config `vp build` caching via runner-aware Vite**: Vite reports its inputs, outputs, and tracked env reads to the `vp` runner over the new `@voidzero-dev/vite-task-client` IPC ([vite#22453](vitejs/vite#22453)), so `vp build` caches correctly with no hand-written cache config: outputs are tracked and restored automatically, and a changed `VITE_*` env var invalidates the cache and is named in the cache-miss message ([#1774](#1774)), by @wan9chi - **PGP-verified Node.js downloads**: installing a managed Node.js now verifies the release's clearsigned `SHASUMS256.txt.asc` against the vendored Node.js release keyring (pure Rust, no `gpg` required) before trusting any checksum, so a tampered archive is rejected before install; unsigned sources (musl builds, custom mirrors) fall back to checksum-only verification ([#1848](#1848)), by @fengmk2 ### Features - `vp check`: a `check` block in `vite.config.ts` (`check.fmt` / `check.lint`) can make plain `vp check` skip formatting or linting by default, mirroring `--no-fmt` / `--no-lint`; standalone `vp fmt` / `vp lint` and git hooks are unaffected, and a `note:` line keeps the config-based skip discoverable ([#1981](#1981)), by @fengmk2 - `vp env list-remote`: highlight installed versions (color, or a `*` prefix when piped) and label the project-resolved `current` and global `default` versions; `--json` gains `installed` / `current` / `default` fields ([#1907](#1907)), by @semimikoh - `vpr` ships as a `vite-plus` package bin, so the `vp run` shorthand works on clean installs without global PATH shims (Vercel build image, generic CI runners) ([#1988](#1988)), by @kvnwolf - Vite Task: `dependsOn` can select tasks from dependency packages, e.g. `dependsOn: [{ "task": "build", "from": "dependencies" }]` ([vite-task#479](voidzero-dev/vite-task#479)), by @wan9chi - Vite Task: a task's `env` / `untrackedEnv` glob patterns support `!` negation (e.g. `["VITE_*", "!VITE_SECRET"]`) ([vite-task#425](voidzero-dev/vite-task#425)), and an env-caused cache miss now names the variable inline, e.g. `cache miss: env 'NODE_ENV' changed` ([vite-task#438](voidzero-dev/vite-task#438)), by @wan9chi - Upgrade upstream dependencies: vite `8.0.16 -> 8.1.2`, rolldown `1.1.1 -> 1.1.4`, oxlint `1.70.0 -> 1.72.0`, oxfmt `0.55.0 -> 0.57.0`, oxlint-tsgolint `0.23.0 -> 0.24.0`, and the oxc toolchain `0.136.0 -> 0.138.0` ([#1924](#1924), [#1989](#1989), [#2000](#2000), [#2009](#2009)), by @voidzero-guard[bot] ### Fixes & Enhancements - Windows: `vp run` no longer hangs CI when a `node_modules/.bin` `.cmd` shim is routed through PowerShell; the npm/pnpm/yarn `.ps1` wrappers read stdin and block forever on a non-TTY pipe, so the PowerShell rewrite is now skipped when stdin is not an interactive terminal ([vite-task#491](voidzero-dev/vite-task#491), via [#1973](#1973)), by @fengmk2 - Vite Task: the task cache is stored in a per-schema-version directory (e.g. `node_modules/.vite/task-cache/v13/`), so switching between branches that pin different Vite+ versions no longer fails with `Unrecognized database version` ([vite-task#433](voidzero-dev/vite-task#433)), by @fengmk2 - Vite Task: env values in cache fingerprints are stored only as SHA-256 digests and env cache-miss details report names without values ([vite-task#455](voidzero-dev/vite-task#455)); prefix env assignments like `PATH=... command` now affect executable lookup during planning ([vite-task#440](voidzero-dev/vite-task#440)); `package.json` / `pnpm-workspace.yaml` files with a UTF-8 BOM parse correctly ([vite-task#424](voidzero-dev/vite-task#424)), by @wan9chi - `vp upgrade`: run the pinned pnpm with a managed Node.js LTS directly instead of re-entering `vp install`, so an incompatible session/project/system runtime can no longer make pnpm skip optional native binaries and leave the upgraded CLI broken ([#1900](#1900)), by @liangmiQwQ - Global package installs: each install writes to an immutable `packages/<name>#<uuid>` prefix that is activated via metadata after npm succeeds, so an interrupted reinstall can no longer leave the active package unavailable ([#1906](#1906)), and stale interrupted-install directories are swept with file-lock protection for concurrent installs ([#1945](#1945)), by @liangmiQwQ - `lazyPlugins()`: skip plugin factories only while config metadata is being resolved instead of keying off `VP_COMMAND`, so builds spawned under `vp run` / `vp exec` keep the user's plugins and `vp format` no longer loads them ([#1939](#1939)), by @fengmk2 - `vp migrate` (pnpm): add a direct `vite` devDep aliased to the core override wherever `vite-plus` is depended on, so vitest's `vite` peer binds to `@voidzero-dev/vite-plus-core` instead of pulling in a second upstream vite that broke the `vp test` cache ([#1933](#1933)), by @fengmk2 - `vp pack`: bundle `@tsdown/exe` and `@tsdown/css` into core so `--exe` and CSS bundling work without a resolvable top-level `tsdown`; the native `lightningcss` becomes an optional peer loaded lazily with an actionable error ([#1919](#1919)), by @fengmk2 - `vp env`: invalidate stale shim resolve cache entries when the project's Node.js version source changes ([#1951](#1951)), by @jong-kyung - Node shim: when the project declares npm via `packageManager` / `devEngines.packageManager`, child processes spawned from `node` resolve the managed npm instead of the Node-bundled one ([#1938](#1938)); `vp env which` reports bins linked by an intercepted `npm install -g` (e.g. `tsc`) instead of "not found" ([#1968](#1968)); bins with uppercase names (e.g. `vitePlus`) dispatch correctly ([#1963](#1963)), by @liangmiQwQ - `vp-setup`: pass the configured npm registry to the inner pnpm install so setup works behind custom registries ([#1795](#1795)), by @daflyinbed - Native binding: declare the platform packages' true ABI floor `engines.node >=20.0.0` so engine-strict package managers (pnpm) no longer skip the optional native dependency and fail with `Cannot find native binding` when a consumer's Node floor lands in a product-policy gap ([#1993](#1993)), by @fengmk2 - `vp create`: run `git init` without creating an initial commit, so commitlint-configured templates no longer reject the hardcoded message and template placeholders are not baked into history ([#2008](#2008)), by @forehalo - `vp staged --debug`: inline the bundled lint-staged version so debug logging no longer crashes reading a `package.json` that does not exist in the bundle ([#1925](#1925)), by @rokuosan - Installer: retry downloads truncated mid-body in `HttpClient::get_bytes` (the platform-tarball path for `vp upgrade` and the standalone installer) ([#1940](#1940)), and clean up the temp dir when a package-manager install fails instead of leaking `.tmpXXXX` directories ([#1949](#1949)), by @shulaoda - Windows/msys: normalize backslashes in the `env.fish` fallback path ([#1954](#1954)), by @Aalivexy - `install.ps1`: detect the missing VC++ runtime (`0xC0000135`) and print VC++ Redistributable guidance instead of a generic failure; interactive `irm | iex` installs keep the shell open ([#1962](#1962)), by @cheezone - `vp migrate`: preserve comments, key order, and trailing commas in existing `.vscode` / `.zed` JSONC configs by patching the original text instead of re-serializing it ([#1956](#1956)), by @fengmk2 - Migration: link the git hook warning to the migration guide ([#1902](#1902)), by @naokihaba - `vp info` / `vp view`: use package-manager-native commands (`pnpm view`, `bun info`, `yarn npm info`) instead of routing every lookup through `npm view` ([#1895](#1895)), by @jong-kyung - Correct overused `ErrorConfig` error types across the codebase ([#1934](#1934)), by @liangmiQwQ ### Refactor - `vite_install`: centralize Yarn v1/berry branching with `is_yarn_berry` ([#1897](#1897)), by @jong-kyung ### Docs - Document Vite Task automatic tracking (fs tracking and cache-reporting tools), reusing the task cache with GitHub Actions cache, and `dependsOn: [{ task, from: "dependencies" }]` ([#1992](#1992)), by @wan9chi - Rewrite the "Upgrading Vite+" guide: preview builds install through the registry bridge as ordinary `0.0.0-commit.<sha>` npm versions, and `vp migrate` is the recommended way to upgrade a project or move it onto a preview build ([#1965](#1965)), by @fengmk2 - Describe how to switch back to the release version from nightly ([#1887](#1887)), by @situ2001 - Clarify Git hook tool migration ([#1901](#1901)), by @naokihaba - Add a global installation explanation ([#1915](#1915)), update the `vp env` help output ([#1969](#1969)), and add liangmiQwQ as a team member ([#1911](#1911)), by @liangmiQwQ - Fix package manager command examples ([#1937](#1937)) and the `dependsOn` guide link ([#1883](#1883)), by @jong-kyung - Remove Fathom analytics from the uninstall docs ([#1946](#1946)), by @mdong1909 - Center the README logo and fix its size ([#1878](#1878)), by @hyf0 ### Chore - Prevent Vite beta upgrades in the upstream-deps script ([#1879](#1879)), stabilize flaky network-dependent tests ([#1923](#1923)), and bump the ecosystem-ci bun-vite-template to the oxlint jsx-a11y fix ([#1898](#1898)), by @fengmk2 - Pin snap-test install fixtures to a published `vite-plus` version so release-branch CI can pass before the new version is published ([#2017](#2017)), by @fengmk2 - Update the deprecated `VITE_PLUS_` env var prefixes to `VP_` in the RFCs ([#1984](#1984)), by @liangmiQwQ - CI: skip full CI for docs-only PRs ([#1991](#1991)) and for the docs deploy config ([#2015](#2015)), by @wan9chi - Update GitHub Actions ([#1904](#1904), [#1977](#1977)), claude-code-action to v1.0.158 ([#1979](#1979)), and pnpm to v10.34.4 ([#1996](#1996)), by @renovate[bot] - Update oxc-project/security-action to v1.0.8 ([#1918](#1918)), by @fengmk2 - Refresh trusted stack stats on the docs homepage ([#1913](#1913), [#1982](#1982)), by @voidzero-guard[bot] ### Bundled Versions | Tool | Version | Source | | --- | --- | --- | | vite | `8.1.2` | [`ba31193`](vitejs/vite@ba31193) | | rolldown | `1.1.4` | [`6cbd233`](rolldown/rolldown@6cbd233) | | tsdown | `0.22.3` | [npm](https://npmx.dev/package/tsdown/v/0.22.3) | | vitest | `4.1.9` | [npm](https://npmx.dev/package/vitest/v/4.1.9) | | oxlint | `1.72.0` | [npm](https://npmx.dev/package/oxlint/v/1.72.0) | | oxlint-tsgolint | `0.24.0` | [npm](https://npmx.dev/package/oxlint-tsgolint/v/0.24.0) | | oxfmt | `0.57.0` | [npm](https://npmx.dev/package/oxfmt/v/0.57.0) | ### Upgrade ```bash vp upgrade ``` New to Vite+? Start with the [Beta announcement](https://voidzero.dev/posts/announcing-vite-plus-beta), then create a project with `vp create` or bring an existing one over with `vp migrate`. ### New Contributors Welcome to our new contributors @rokuosan, @Aalivexy, @cheezone, @daflyinbed, @forehalo, @kvnwolf! 🎉 **Full Changelog**: v0.2.1...v0.2.2 --- Merging this PR will trigger the release workflow. --------- Co-authored-by: voidzero-guard[bot] <278573678+voidzero-guard[bot]@users.noreply.github.com> Co-authored-by: MK <fengmk2@gmail.com>
When
vpinstalls a managed Node.js version, it now verifies the release's PGP signature (the clearsignedSHASUMS256.txt.asc) against Node's release keys before trusting any checksum. Previously the plainSHASUMS256.txtwas trusted as-is, so anyone able to tamper with it could swap in a matching malicious archive.This is the same guarantee as
gpgvagainst the official keyring, built in (pure Rust, nogpgrequired). The keyring is vendored fromnodejs/release-keysand kept current by a weekly workflow.Example output
A normal install is unchanged (verification is transparent):
A tampered or untrusted SHASUMS is rejected before anything is installed:
The official
nodejs.orgsource always requires a valid signature. The unofficial musl builds, and custom mirrors that publish onlySHASUMS256.txt, have no signature to verify, so they fall back to checksum-only verification. That is an expected, documented condition for those sources, so it is recorded in the debug log (VITE_LOG) rather than warning on every install.Binary size
The
.nodeNAPI binding (vite-plus-cli) is unaffected: no size change.pgpand the vendored keyring are reachable only throughvite_js_runtime, which is linked into the globalvpbinary, not into the binding (vite_install/vite_pm_cli). Only the globalvpbinary grows, by ~1.2 MiB (rPGP plus the RustCrypto verification code and the embedded release keyring).Closes#1807