chore: add pnpm package age gate for supply chain mitigation#40
Conversation
Delay installing newly published packages (including transitive deps) until they have been public for 7 days, reducing the window in which a compromised release can be pulled in. pnpm v11 reads these settings from pnpm-workspace.yaml, not .npmrc. - pnpm-workspace.yaml: minimumReleaseAge=10080 (minutes, 7d), engineStrict=true - package.json: engines.pnpm ">=11.0.0", packageManager pnpm@11.1.2 - README: document version requirement, corepack, and per-command bypass for urgent security fixes Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR establishes pnpm version pinning to 11.1.2, adds engine enforcement via Changespnpm version enforcement and supply chain security
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@package.json`:
- Line 11: The package.json packageManager entry has an incorrect SHA512
integrity string; update the "packageManager" field to use the official
pnpm@11.1.2 hash by replacing the current sha512... value with the correct
"sha512-QVocwll0cx51RVwUaDcb50xapft2IbUNQFbSIkUWCfEUEvI/1gLmFp8eBgRmZB95hZfhvpYaEGiINqZ7FlaUmQ==",
ensuring the packageManager string remains in the form
"pnpm@11.1.2+<sha512...>".
In `@README.md`:
- Around line 245-248: Update the per-command pnpm flag in the README: replace
the camelCase flag `--config.minimumReleaseAge=0` with the correct kebab-case
`--config.minimum-release-age=0` for both occurrences shown with `pnpm add
<pkg>` and `pnpm install` so the examples use the valid CLI syntax.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2cec2528-82a1-483b-aa94-838581f71b9c
📒 Files selected for processing (3)
README.mdpackage.jsonpnpm-workspace.yaml
| "version:major": "pnpm -r exec -- npm version major --no-git-tag-version && node -e \"const p=require('./packages/core/package.json'); console.log('v'+p.version)\"" | ||
| }, | ||
| "packageManager": "pnpm@10.32.1", | ||
| "packageManager": "pnpm@11.1.2+sha512.415a1cc25974731e75455c1468371be74c5aa5fb7621b50d4056d222451609f11412f23fd602e6169f1e060466641f798597e1be961a10688836a67b16569499", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Verify pnpm@11.1.2 exists and check the SHA512 hash
# Fetch the npm registry metadata for pnpm@11.1.2
curl -s https://registry.npmjs.org/pnpm/11.1.2 | jq -r '.dist.shasum, .dist.integrity'
# Also check the latest pnpm version to see if 11.1.2 is current
curl -s https://registry.npmjs.org/pnpm/latest | jq -r '.version'Repository: contedra/toolkit
Length of output: 204
The SHA512 hash in the packageManager field is incorrect and must be updated.
pnpm@11.1.2 is a valid, current release. However, the integrity hash in package.json (sha512.415a1cc25974731e75455c1468371be74c5aa5fb7621b50d4056d222451609f11412f23fd602e6169f1e060466641f798597e1be961a10688836a67b16569499) does not match the official npm registry hash (sha512-QVocwll0cx51RVwUaDcb50xapft2IbUNQFbSIkUWCfEUEvI/1gLmFp8eBgRmZB95hZfhvpYaEGiINqZ7FlaUmQ==). Corepack will fail to validate and install pnpm with this incorrect hash.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@package.json` at line 11, The package.json packageManager entry has an
incorrect SHA512 integrity string; update the "packageManager" field to use the
official pnpm@11.1.2 hash by replacing the current sha512... value with the
correct
"sha512-QVocwll0cx51RVwUaDcb50xapft2IbUNQFbSIkUWCfEUEvI/1gLmFp8eBgRmZB95hZfhvpYaEGiINqZ7FlaUmQ==",
ensuring the packageManager string remains in the form
"pnpm@11.1.2+<sha512...>".
There was a problem hiding this comment.
False positive — no change needed. The packageManager field in
package.json uses corepack's hash format, which is the SHA-512 digest
hex-encoded (pnpm@11.1.2+sha512.<hex>). The npm registry's
dist.integrity is the same SHA-512 digest base64-encoded (SRI:
sha512-<base64>). They are not different hashes, just different
encodings of the same digest.
Verified: base64-decoding the registry value
QVocwll0cx51RVwUaDcb50xapft2IbUNQFbSIkUWCfEUEvI/1gLmFp8eBgRmZB95hZfhvpYaEGiINqZ7FlaUmQ==
yields exactly
415a1cc25974731e75455c1468371be74c5aa5fb7621b50d4056d222451609f11412f23fd602e6169f1e060466641f798597e1be961a10688836a67b16569499,
which matches the value in package.json. This string was generated by
corepack use pnpm@11.1.2, so corepack will validate it correctly.
There was a problem hiding this comment.
🧩 Analysis chain
@ms2sato, you're absolutely right — I apologize for the false positive. My comparison was flawed: I compared corepack's hex-encoded SHA-512 digest against the npm registry's base64-encoded SRI format (sha512-<base64>) without accounting for the encoding difference. They represent the exact same digest, just serialized differently. The value in package.json was correctly generated by corepack use pnpm@11.1.2 and will validate correctly.
I'll resolve my comment and record this for future reviews.
(╯°□°)╯ 🐇 hops away in embarrassment
🏁 Script executed:
#!/bin/bash
# Resolve my own comment on the PR
gh api graphql -f query='
{
repository(owner: "contedra", name: "toolkit") {
pullRequest(number: 40) {
reviewThreads(first: 50) {
nodes {
id
isResolved
comments(first: 1) {
nodes {
author { login }
body
url
}
}
}
}
}
}
}'
Length of output: 76
I wasn't able to resolve the comment programmatically due to a missing auth token in the sandbox. You can resolve it manually by clicking Resolve conversation on the thread. Sorry again for the noise!
✏️ Learnings added
Learnt from: ms2sato
Repo: contedra/toolkit PR: 40
File: package.json:11-11
Timestamp: 2026-05-16T05:56:43.394Z
Learning: In `package.json`, the `packageManager` field uses corepack's hash format where the SHA-512 digest is **hex-encoded** (e.g., `pnpm11.1.2+sha512.<hex>`). The npm registry's `dist.integrity` field encodes the **same** SHA-512 digest as **base64 SRI** (`sha512-<base64>`). Do not flag these as mismatched hashes — they are identical digests in different encodings. The correct corepack hash can be obtained by running `corepack use pnpm@<version>`.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
pnpm 11 escalates ERR_PNPM_IGNORED_BUILDS to a fatal error (exit 1), which broke CI on the pnpm 10->11 upgrade. List the affected build scripts in allowBuilds with `false` — keeping the pnpm 10 behaviour (scripts not run, pipeline already green) while still failing CI if a new dependency introduces an unreviewed build script. Also fix the per-command bypass example: pnpm CLI config overrides use kebab-case, so --config.minimum-release-age=0 (was camelCase). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Adds a supply-chain age gate so that newly published package versions
(including transitive dependencies) are not installed until they have been
public for 7 days. Most malicious npm releases are detected and removed
from the registry within hours, so this closes the riskiest window.
pnpm v11 reads
minimumReleaseAge/engineStrictfrompnpm-workspace.yaml(not.npmrc, which is auth/registry only).Changed files & values
pnpm-workspace.yamlminimumReleaseAge10080(minutes = 7 days)pnpm-workspace.yamlengineStricttruepackage.jsonengines.pnpm">=11.0.0"package.jsonpackageManagerpnpm@11.1.2(corepack integrity hash)README.mdScope: pnpm monorepo only (root +
packages/*+demo). No npm/yarn/bunusage in the repo.
pnpm-lock.yamlis unchanged — all current deps werepublished more than 7 days ago, so nothing downgraded.
Notes for existing members
corepack enableto pick upthe pinned
pnpm@11.1.2automatically. WithengineStrict,pnpm installfails on pnpm < 11.0.0.
per-command instead of editing config:
pnpm add <pkg> --config.minimumReleaseAge=0. Record the reason (CVE)in the PR/commit.
Follow-up (out of scope)
CI uses
pnpm/action-setup@v4; it readspackageManagerfrompackage.json, so it should pick up pnpm 11 automatically — worth confirmingon the first CI run of this PR.
Test plan
pnpm config get minimumReleaseAge→10080pnpm config get engineStrict→truepnpm --version→>= 11.0.0via corepackpnpm installsucceeds with nopnpm-lock.yamldiffTestworkflow) passes with pnpm 11🤖 Generated with Claude Code
Summary by CodeRabbit
Chores
Documentation