Prevent cache poisoning vuln in GitHub Actions sample workflows (#1935)

The PR https://github.com/npm/documentation/pull/1917 bumped the `actions/setup-node` action from v4 to v6. This made the publishing GitHub Actions sample workflows potentially vulnerable to cache poisoning, because v5 and later enable caching by default (see https://github.com/actions/setup-node/blob/53b83947a5a98c8d113130e565377fae1a50d02f/README.md#breaking-changes-in-v5). v6 only enables automatic caching if the `packageManager` field in package.json is set to `npm`. Consuming GitHub Actions cache in publishing workflows is discouraged, because the cache may be poisoned by compromising any low-privileged workflow in the same repository. Normally, a code injection vulnerability in a low-privileged workflow (for example `permissions: {contents: read}` and no secrets) is not a big deal, because the attacker cannot do much more than poison the repository cache (which requires no permissions). If caching is only used in other low-privileged workflows, the impact is limited. However, if a high-privileged workflow like the release build consumes the cache, then it becomes a real problem. As @AdnaneKhan concludes in his blog posts about GitHub Actions cache poisoning, such as https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/#dont-use-actions-caching-in-release-builds: "the best way to protect the integrity of releases is to avoid using GitHub Actions caching entirely for release workflows." The README of `actions/setup-node` also recommends `package-manager-cache: false` for privileged workflows (see https://github.com/actions/setup-node/blob/53b83947a5a98c8d113130e565377fae1a50d02f/README.md#breaking-changes-in-v5): > For workflows with elevated privileges or access to sensitive information, we recommend disabling automatic caching by setting `package-manager-cache: false` when caching is not needed for secure operation. ## References Related to #1917

Petr Pučil committed May 4, 2026 at 18:39 UTC cad232f06f4f28a24f0d1b7943fd381edb7287d0
2 files changed +7 -4
content/packages-and-modules/securing-your-code/generating-provenance-statements.mdx
+4 -3
@@ -91,11 +91,12 @@ jobs:
91 contents: read
92 id-token: write
93 steps:
94 - - uses: actions/checkout@v4
95 - - uses: actions/setup-node@v4
94 + - uses: actions/checkout@v6
95 + - uses: actions/setup-node@v6
96 with:
97 - node-version: '20.x'
97 + node-version: '24.x'
98 registry-url: 'https://registry.npmjs.org'
99 + package-manager-cache: false # never use caching in release builds
100 - run: npm ci
101 - run: npm publish --provenance --access public
102 env:
content/packages-and-modules/securing-your-code/trusted-publishers.mdx
+3 -1
@@ -106,6 +106,7 @@ jobs:
106 with:
107 node-version: '24'
108 registry-url: 'https://registry.npmjs.org'
109 + package-manager-cache: false # never use caching in release builds
110 - run: npm ci
111 - run: npm run build --if-present
112 - run: npm test
@@ -298,10 +299,11 @@ While trusted publishing handles the publish operation, you may still need authe
299
300 ```yaml
301 # GitHub Actions example
301 -- uses: actions/setup-node@v4
302 +- uses: actions/setup-node@v6
303 with:
304 node-version: '24'
305 registry-url: 'https://registry.npmjs.org'
306 + package-manager-cache: false # never use caching in release builds
307 # Use a read-only token for installing dependencies
308 - run: npm ci
309 env: