Verify latest release
pnpm version
No response
Which area(s) of pnpm are affected? (leave empty if unsure)
No response
Link to the code that reproduces this issue or a replay of the bug
No response
Reproduction steps
Background / how to reach this state
pnpm's content-addressable store can accumulate com.apple.quarantine xattrs on file blobs when packages are first installed under a Gatekeeper-enabled application (e.g. a terminal inside Sourcetree, a Git client with LSFileQuarantineEnabled=YES). Once quarantine is on a store blob, every subsequent pnpm install — including after deleting node_modules and reinstalling from scratch — propagates the xattr into the project because macOS preserves extended attributes during file copy.
Reproduce from a clean state (manual)
# 1. Install a package containing a native addon
mkdir /tmp/pnpm-quarantine-repro && cd /tmp/pnpm-quarantine-repro
echo '{"name":"repro","private":true,"devDependencies":{"rollup":"4.59.0"}}' > package.json
pnpm install
# 2. Find the native binary in node_modules and the corresponding store blob
BIN=$(find node_modules -name 'rollup.darwin-arm64.node' | head -1)
echo "node_modules binary: $BIN"
STORE_BLOB=$(pnpm store path)/files/2f/$(ls "$(pnpm store path)/files/2f/" | grep "^de" | head -1)
echo "store blob: $STORE_BLOB"
# 3. Check both are clean (no quarantine yet)
xattr -l "$BIN"
xattr -l "$STORE_BLOB"
# 4. Simulate quarantine on the store blob (as macOS would apply it when downloaded
# via a Gatekeeper-enabled app such as a Git client or browser):
xattr -w com.apple.quarantine "0083;$(printf '%x' $(date +%s));Sourcetree;" "$STORE_BLOB"
# 5. Delete node_modules and reinstall — pnpm pulls from its store
rm -rf node_modules
pnpm install
# 6. Observe: binary in node_modules now has quarantine despite a fresh install
BIN=$(find node_modules -name 'rollup.darwin-arm64.node' | head -1)
xattr -l "$BIN"
# OUTPUT: com.apple.quarantine: 0083;...;Sourcetree;
# 7. Observe: running rollup now triggers Gatekeeper
pnpm exec rollup --version
# Apple dialog: "Apple could not verify rollup.darwin-arm64.node is free of malware"
Describe the Bug
Environment
macOS 26.3.1 arm64 (Darwin 25.3.0)
pnpm 10.32.1
Node 22.16.0
Root cause analysis
- The native binary
rollup.darwin-arm64.node is ad-hoc signed only (no Team ID, not notarized), so Gatekeeper cannot automatically approve it.
- pnpm copies (not hardlinks across volumes) store file blobs into
node_modules, and cp on macOS preserves all xattrs including com.apple.quarantine.
- After pnpm verifies the file's integrity against the lockfile hash (sha512-L97TFX...), there is no security reason to retain the quarantine xattr.
Expected Behavior
After pnpm writes a file from its store and verifies its integrity hash matches pnpm-lock.yaml, it should strip com.apple.quarantine from the file:
xattr -d com.apple.quarantine <path> 2>/dev/null || true
This is the same strategy Homebrew uses for downloaded artifacts after checksum verification.
Workaround
find node_modules -name '*.node' -exec xattr -d com.apple.quarantine {} \; 2>/dev/null
Which Node.js version are you using?
22.16.0
Which operating systems have you used?
If your OS is a Linux based, which one it is? (Include the version if relevant)
No response
Verify latest release
pnpm version
No response
Which area(s) of pnpm are affected? (leave empty if unsure)
No response
Link to the code that reproduces this issue or a replay of the bug
No response
Reproduction steps
Background / how to reach this state
pnpm's content-addressable store can accumulate
com.apple.quarantinexattrs on file blobs when packages are first installed under a Gatekeeper-enabled application (e.g. a terminal inside Sourcetree, a Git client withLSFileQuarantineEnabled=YES). Once quarantine is on a store blob, every subsequentpnpm install— including after deletingnode_modulesand reinstalling from scratch — propagates the xattr into the project because macOS preserves extended attributes during file copy.Reproduce from a clean state (manual)
Describe the Bug
Environment
macOS 26.3.1 arm64 (Darwin 25.3.0)
pnpm 10.32.1
Node 22.16.0
Root cause analysis
rollup.darwin-arm64.nodeis ad-hoc signed only (no Team ID, not notarized), so Gatekeeper cannot automatically approve it.node_modules, andcpon macOS preserves all xattrs includingcom.apple.quarantine.Expected Behavior
After pnpm writes a file from its store and verifies its integrity hash matches
pnpm-lock.yaml, it should stripcom.apple.quarantinefrom the file:This is the same strategy Homebrew uses for downloaded artifacts after checksum verification.
Workaround
Which Node.js version are you using?
22.16.0
Which operating systems have you used?
If your OS is a Linux based, which one it is? (Include the version if relevant)
No response