Skip to content

ci(security): harden CI/CD supply chain and bump pnpm to 11.1.1#436

Merged
AlemTuzlak merged 4 commits into
mainfrom
worktree-cozy-dancing-pebble
May 12, 2026
Merged

ci(security): harden CI/CD supply chain and bump pnpm to 11.1.1#436
AlemTuzlak merged 4 commits into
mainfrom
worktree-cozy-dancing-pebble

Conversation

@AlemTuzlak
Copy link
Copy Markdown
Collaborator

Summary

Two related changes bundled together because the pnpm 11 bump is itself a supply-chain hardening (postinstall scripts are denied by default and require an explicit allowlist).

chore(deps): upgrade pnpm to 11.1.1

  • Bumps packageManager in the root + the four Angular example package.jsons.
  • Adds a minimal allowBuilds: allowlist in pnpm-workspace.yaml — only esbuild and nx are permitted to run postinstall scripts. The other eight transitively-pulled scripts (sharp, lmdb, workerd, @parcel/watcher, msgpackr-extract, protobufjs, unrs-resolver, vue-demi) are explicitly denied; verified that build / test / typecheck all still pass without them.
  • Pins the preinstall guard to only-allow@1.2.2 (was floating via npx -y only-allow).

ci(security): pin actions to SHAs and harden CI/CD supply chain

The most impactful issue: TanStack/config/.github/setup@main was used in three workflows including release.yml (which carries id-token: write for npm OIDC). A force-push or compromise there would have meant control of the npm publishing identity on the next merge to main. All composite-action and third-party-action refs are now SHA-pinned with # version comments so Renovate can keep them current.

Issue Fix
TanStack/config/.github/*@main (3 workflows) SHA-pinned
actions/checkout, setup-node, nrwl/nx-set-shas, danielroe/provenance-action, changesets/action, peter-evans/repository-dispatch, warpdotdev/warp-agent-action SHA-pinned
release.yml cancel-in-progress: true false so a re-push cannot abort changesets/action mid-publish
release.yml no human gate Added environment: release — configure required reviewers in repo settings to actually enforce
triage-agent.yml prompt injection via issue body Added "SECURITY: Untrusted input" preamble; agent now treats issue text strictly as data
triage-agent.yml template path typo bug-report.ymlbug_report.yml (pre-existing functional bug found while hardening)
npm install -g @tanstack/intent floating Pinned to @0.0.41
pnpx pkg-pr-new floating Pinned to @0.0.71
Renovate :automergeMinor + floating versions :automergeMinor removed; updates now require human review
No CODEOWNERS gating workflow edits Added .github/CODEOWNERS covering workflows, manifests, lockfile, .npmrc, renovate config
No automated check for vulnerable transitive deps Added .github/workflows/dependency-review.yml (fail-on-severity: high)

Not done in this PR — require GitHub UI configuration

  1. Configure required reviewers + wait timer on the release Environment.
  2. Audit & rotate the INTENT_NOTIFY_TOKEN PAT scopes to the minimum needed.
  3. Enable branch protection on main requiring CODEOWNERS review.
  4. Enable "Require approval for first-time contributors" in repo Actions settings (mitigates the NX_CLOUD_ACCESS_TOKEN-during-untrusted-install risk).
  5. Adjust the CODEOWNERS handle from @tannerlinsley to a team once one exists.
  6. Optional: enable OpenSSF Scorecard + CodeQL workflows.

Test plan

  • pnpm --version reports 11.1.1
  • pnpm install completes clean with the minimal allowBuilds allowlist
  • pnpm run build:all succeeds for all 32 projects, size-limit checks pass
  • pnpm run test:ci — every Nx target passes (test:eslint, test:sherif, test:lib, test:types, test:build, build) except root:test:knip, which I verified is a pre-existing failure on main (stashed all my changes, ran knip, same 6 unused files + 3 unused devDeps reported)
  • CI green on this PR
  • Maintainer review the allowBuilds denylist for any package they actually want to run scripts (current minimum is intentionally aggressive)
  • Maintainer configure required reviewers on the new release Environment for the gating to take effect

Bumps the corepack-managed pnpm version across the root and the four
Angular example workspaces. pnpm 11 refuses to run install scripts by
default; declare a minimal allowBuilds allowlist in pnpm-workspace.yaml
so only the two packages whose postinstalls the build actually needs
(esbuild, nx) are permitted. The other eight transitively-pulled
postinstalls (sharp, lmdb, workerd, etc.) all fall back to JS paths
or are unused during build, and are explicitly denied.

Also pin the preinstall guard to only-allow@1.2.2 so it no longer
resolves a floating tag from npm on every install.
Replaces every mutable workflow reference (@main, @v1, @V3, @v4,
@v6.0.2) with a 40-char commit SHA + version comment so Renovate can
keep them current. Composite actions in TanStack/config — previously
pinned to @main — are the highest-impact change: a force-push or
compromised commit there would have given an attacker the npm OIDC
publishing identity plus contents/issues/PR write tokens on the next
push to main.

Other changes in this commit:

- release.yml: set cancel-in-progress: false so a re-push cannot abort
  changesets/action mid-publish and leave partial versions on npm.
  Add environment: release so required reviewers can be configured in
  repo settings for an explicit human gate before publish.

- triage-agent.yml: add a "SECURITY: Untrusted input" preamble to the
  Warp agent prompt. The agent reads attacker-controlled issue text,
  so it must treat that text strictly as data and refuse instructions
  embedded inside it. Also corrected the bug-report template path
  (bug-report.yml -> bug_report.yml) that the agent was failing to
  load.

- check-skills.yml / validate-skills.yml: pin @tanstack/intent to a
  specific version; npm install -g without a version was floating.

- pr.yml preview job: pin pkg-pr-new to a specific version; pnpx
  without a version was floating.

- .github/renovate.json: drop :automergeMinor. Combined with floating
  versions this could have landed a malicious patch without review.

- .github/CODEOWNERS (new): require owner review on workflows, package
  manifests, lockfile, .npmrc, and renovate config. Adjust the owner
  handle to a team once one exists.

- .github/workflows/dependency-review.yml (new): runs
  actions/dependency-review-action on every PR with
  fail-on-severity: high to block PRs that introduce known-vulnerable
  transitive dependencies.
The original `||`-chained preinstall printed "Skipping preinstall..." in
CI but then ran only-allow anyway because `process.exit(1)` triggers
the `||` operator. CI happened to pass when only-allow was unpinned
(npx resolved it differently), but pinning to @1.2.2 forced a fresh
registry resolve in which only-allow strictly checks
npm_config_user_agent — which, when invoked via npx-inside-pnpm, is
npm's, not pnpm's — and rejects.

The fix matches the script's stated intent: when CI=true, exit 0 so
the `||` does not trigger and only-allow is genuinely skipped. Local
installs continue to fall through and enforce pnpm via only-allow as
before.
@github-actions
Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

3 package(s) bumped directly, 11 bumped as dependents.

🟨 Minor bumps

Package Version Reason
@tanstack/devtools-utils 0.4.0 → 0.5.0 Changeset

🟩 Patch bumps

Package Version Reason
@tanstack/devtools-ui 0.5.1 → 0.5.2 Changeset
@tanstack/devtools-vite 0.6.0 → 0.6.1 Changeset
@tanstack/angular-devtools 0.0.3 → 0.0.4 Dependent
@tanstack/devtools 0.12.1 → 0.12.2 Dependent
@tanstack/devtools-a11y 0.1.2 → 0.1.3 Dependent
@tanstack/devtools-example-angular-a11y-devtools 0.0.2 → 0.0.3 Dependent
@tanstack/devtools-example-angular-basic 0.0.2 → 0.0.3 Dependent
@tanstack/devtools-example-angular-panel 0.0.2 → 0.0.3 Dependent
@tanstack/devtools-example-angular-with-devtools 0.0.2 → 0.0.3 Dependent
@tanstack/preact-devtools 0.10.4 → 0.10.5 Dependent
@tanstack/react-devtools 0.10.4 → 0.10.5 Dependent
@tanstack/solid-devtools 0.8.4 → 0.8.5 Dependent
@tanstack/vue-devtools 0.2.18 → 0.2.19 Dependent

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 12, 2026

More templates

@tanstack/angular-devtools

npm i https://pkg.pr.new/@tanstack/angular-devtools@436

@tanstack/devtools

npm i https://pkg.pr.new/@tanstack/devtools@436

@tanstack/devtools-a11y

npm i https://pkg.pr.new/@tanstack/devtools-a11y@436

@tanstack/devtools-client

npm i https://pkg.pr.new/@tanstack/devtools-client@436

@tanstack/devtools-ui

npm i https://pkg.pr.new/@tanstack/devtools-ui@436

@tanstack/devtools-utils

npm i https://pkg.pr.new/@tanstack/devtools-utils@436

@tanstack/devtools-vite

npm i https://pkg.pr.new/@tanstack/devtools-vite@436

@tanstack/devtools-event-bus

npm i https://pkg.pr.new/@tanstack/devtools-event-bus@436

@tanstack/devtools-event-client

npm i https://pkg.pr.new/@tanstack/devtools-event-client@436

@tanstack/preact-devtools

npm i https://pkg.pr.new/@tanstack/preact-devtools@436

@tanstack/react-devtools

npm i https://pkg.pr.new/@tanstack/react-devtools@436

@tanstack/solid-devtools

npm i https://pkg.pr.new/@tanstack/solid-devtools@436

@tanstack/vue-devtools

npm i https://pkg.pr.new/@tanstack/vue-devtools@436

commit: f9e93f0

@AlemTuzlak AlemTuzlak merged commit 31c194e into main May 12, 2026
7 checks passed
@AlemTuzlak AlemTuzlak deleted the worktree-cozy-dancing-pebble branch May 12, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant