docs: clarify store trust boundary (#12268)

This commit is contained in:
Zoltan Kochan
2026-06-08 21:03:28 +02:00
committed by GitHub
parent c74d4e161a
commit e4d2fe025e
6 changed files with 24 additions and 5 deletions

View File

@@ -0,0 +1,7 @@
---
"@pnpm/cli.common-cli-options-help": patch
"@pnpm/installing.commands": patch
"pnpm": patch
---
Clarified in CLI help that the pnpm store is trusted shared state and store integrity checks are corruption detection, not a tamper boundary for untrusted store writers.

View File

@@ -16,7 +16,7 @@ export const OPTIONS = {
name: '--prefer-offline',
},
storeDir: {
description: 'The directory in which all the packages are saved on the disk',
description: 'The directory in which all packages are saved on disk. Use a shared store only with trusted users and jobs',
name: '--store-dir <dir>',
},
virtualStoreDir: {

View File

@@ -218,7 +218,7 @@ by any dependencies, so it is an emulation of a flat node_modules',
name: '--ignore-workspace',
},
{
description: "If false, doesn't check whether packages in the store were mutated",
description: 'If false, skips store integrity checks. These checks detect accidental corruption, not tampering by untrusted users with write access to the store',
name: '--[no-]verify-store-integrity',
},
{

View File

@@ -387,7 +387,9 @@ pub struct Config {
/// true to hoist them for you.
pub shamefully_hoist: bool,
/// The location where all the packages are saved on the disk.
/// The location where all packages are saved on disk. Share a
/// writable store only between mutually trusted users, jobs, and
/// processes.
#[default(_code = "default_store_dir::<Host>()")]
pub store_dir: StoreDir,
@@ -792,6 +794,9 @@ pub struct Config {
/// lookup skips that verification entirely and trusts the index — a
/// missing blob is discovered lazily at link time instead.
///
/// This is corruption detection for a trusted store, not a tamper
/// boundary for a store writable by untrusted users or jobs.
///
/// Matches pnpm's `verifyStoreIntegrity` camelCase key in
/// `pnpm-workspace.yaml` (same `true` default as pnpm's
/// `installing/deps-installer/src/install/extendInstallOptions.ts`).
@@ -1152,6 +1157,8 @@ pub struct Config {
/// verification gate to memoize past results in
/// `<cache_dir>/lockfile-verified.jsonl`, and by the npm verifier
/// to mirror full-metadata responses for conditional GETs.
/// Share a writable cache only between mutually trusted users,
/// jobs, and processes.
///
/// Mirrors pnpm's
/// [`cacheDir`](https://github.com/pnpm/pnpm/blob/2a9bd897bf/config/reader/src/Config.ts#L159);

View File

@@ -270,6 +270,10 @@ fn build_side_effects_maps(
/// fails, so operators can see *which* package file invalidated the
/// store-index row in the log.
///
/// **Trust boundary.** This verification is for corruption detection
/// in a trusted local store. It is not a tamper boundary for a store
/// writable by untrusted users or jobs.
///
/// **Locking discipline.** The fast path (`is_modified == false`, i.e.
/// the file's mtime is within 100 ms of the recorded `checked_at`)
/// runs lock-free — it never touches the file's bytes and never

View File

@@ -168,8 +168,9 @@ function verifyFile (
}
return passed
}
// If a file was not edited, we are skipping integrity check.
// We assume that nobody will manually remove a file in the store and create a new one.
// Fast path for trusted stores: if metadata says the file is unchanged, skip the
// digest read. Store integrity verification detects corruption; it does not make
// a store writable by untrusted users safe.
return true
}