Skip to content

chore(ui): upgrade pnpm to 11 and harden supply-chain defaults#11225

Merged
pfe-nazaries merged 11 commits into
masterfrom
feature/pnpm-security-defaults
May 28, 2026
Merged

chore(ui): upgrade pnpm to 11 and harden supply-chain defaults#11225
pfe-nazaries merged 11 commits into
masterfrom
feature/pnpm-security-defaults

Conversation

@pfe-nazaries
Copy link
Copy Markdown
Contributor

@pfe-nazaries pfe-nazaries commented May 19, 2026

Context

The UI workspace was on pnpm 10.33.0 with supply-chain configuration spread across three files (ui/.npmrc, ui/package.json#pnpm, ui/pnpm-workspace.yaml). pnpm 11 dropped support for pnpm and most .npmrc keys, so the migration was needed to stay on a supported release line while consolidating the security defaults in a single place. While at it, several trustPolicyExclude entries were open-ended package names — a bump to a malicious version of those would silently pass the trust check.

Description

  • Bump pnpm 10.33.011.1.3 (Node ≥22.13 required by pnpm 11; aligned with ui/.nvmrc).
  • Migrate pnpm.overrides from package.json and the security-relevant keys from .npmrc into ui/pnpm-workspace.yaml (pnpm 11 only reads auth/registry from .npmrc, so ui/.npmrc is deleted).
  • Centralize versions: CI workflows (ui-e2e-tests-v2.yml, ui-tests.yml) read Node from ui/.nvmrc and pnpm from package.json#packageManager instead of hardcoding values.
  • Pin express-rate-limit to exact 8.5.1 in overrides — version 8.2.2 dropped provenance attestation, so without a pin pnpm 11's trustPolicy: no-downgrade rejects the transitive (@modelcontextprotocol/sdkexpress-rate-limit).
  • Tighten trustPolicyExclude: entries are now pinned to the exact resolved version (next-auth@5.0.0-beta.30, semver@6.3.1). A bump now fails until reviewed.
  • langium removed from trustPolicyExclude (no longer in the dep tree after pnpm 11 re-resolution).
  • Add corepack enable / corepack install pre-start hook in .config/wt.toml; document the Node version sync requirement in ui/Dockerfile.
  • engineStrict: true plus engines.node/engines.pnpm in package.json refuse installs outside the supported versions.

Steps to review

  1. cd ui && pnpm install — should succeed with no --trust-policy-exclude flag and resolve express-rate-limit@8.5.1, next-auth@5.0.0-beta.30, semver@6.3.1.
  2. Confirm pnpm-lock.yaml header reflects the overrides (express-rate-limit: 8.5.1).
  3. Try installing with Node <22.13 — should fail because of engineStrict (the floor required by pnpm 11). Anything ≥22.13 still installs; .nvmrc pins 24.13.0 to keep Docker and CI in lockstep with the team default, not as a strict equality requirement.
  4. Inspect ui/pnpm-workspace.yaml — all supply-chain settings (engineStrict, publicHoistPattern, saveExact, overrides, minimumReleaseAge, strictDepBuilds/allowBuilds, trustPolicy/trustPolicyExclude, blockExoticSubdeps) are now in one file.
  5. git grep -n "node-version" .github/workflows/ui-*.yml — should show only node-version-file: ui/.nvmrc (no hardcoded number).

Checklist

Community Checklist
  • This feature/issue is listed in here or roadmap.prowler.com
  • Is it assigned to me, if not, request it via the issue/feature in here or Prowler Community Slack

UI (if applicable)

  • All issue/task requirements work as expected on the UI
  • Ensure new entries are added to ui/CHANGELOG.md

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@pfe-nazaries pfe-nazaries requested review from a team as code owners May 19, 2026 11:17
@github-actions github-actions Bot added github_actions Pull requests that update GitHub Actions code component/ui labels May 19, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

✅ All necessary CHANGELOG.md files have been updated.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

Conflict Markers Resolved

All conflict markers have been successfully resolved in this pull request.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

🔒 Container Security Scan

Image: prowler-ui:5e9b0aa
Last scan: 2026-05-27 11:59:23 UTC

📊 Vulnerability Summary

Severity Count
🔴 Critical 2
Total 2

2 package(s) affected

⚠️ Action Required

Critical severity vulnerabilities detected. These should be addressed before merging:

  • Review the detailed scan results
  • Update affected packages to patched versions
  • Consider using a different base image if updates are unavailable

📋 Resources:

Copy link
Copy Markdown
Contributor

@alejandrobailo alejandrobailo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice cleanup,

A few small things I noticed:

The description says installs will fail on Node ≠ .nvmrc, but engines.node is >=22.13, so anything from 22.13 onwards will still install (Docker and CI pin 24.13.0 via .nvmrc). Either tighten engines.node or tweak the wording so future readers don't expect strict parity.
engines.pnpm: ">=11" is a bit looser than packageManager: pnpm@11.1.3. Not blocking, just a tiny drift.
In .config/wt.toml the new pre-start block has two keys (corepack-enable, corepack-install). TOML doesn't guarantee key order, so depending on the runner they could run out of order. Splitting into two [[pre-start]] blocks (or chaining with &&) would make it bulletproof.
Other than that, looks good to me.

@pfe-nazaries
Copy link
Copy Markdown
Contributor Author

Thanks @alejandrobailo — addressed all three in 2047937:

  1. engines.node vs .nvmrc parity — tweaked the wording instead of tightening, since >=22.13 is the real pnpm 11 requirement and we want forward compat. PR step 3 in the description now reads: "Try installing with Node <22.13 — should fail because of engineStrict (the floor required by pnpm 11). Anything ≥22.13 still installs; .nvmrc pins 24.13.0 to keep Docker and CI in lockstep with the team default, not as a strict equality requirement."
  2. engines.pnpm drift — tightened ">=11"">=11.1.3" so it matches the packageManager pin.
  3. .config/wt.toml pre-start ordering — split into two [[pre-start]] blocks. Confirmed in the worktrunk docs that keys within a single block run concurrently, so two blocks guarantee corepack enable finishes before corepack install starts. Added a comment explaining why the split exists.

@pfe-nazaries pfe-nazaries force-pushed the feature/pnpm-security-defaults branch from 2047937 to 9ba80b7 Compare May 21, 2026 09:49
@pfe-nazaries
Copy link
Copy Markdown
Contributor Author

pfe-nazaries commented May 21, 2026

@alejandrobailo Also let me know if you wanna go really strict and require exact node/pnpm versions instead of >=

Usually the exact version is my approach, but I wanna check here before enforcing it

@Alan-TheGentleman
Copy link
Copy Markdown
Contributor

Thanks, this looks good overall. One thing I want to clarify before approval: healthcheck drops format:check, so it now runs only typecheck and lint. Was that intentional, and is formatting still enforced somewhere else in CI?

I also checked the new publicHoistPattern entries. *@heroui/* is still needed because the UI still imports HeroUI packages directly, but I did not find active @nextui-org/* usage outside historical/docs references. If that legacy pattern is no longer needed, please remove it or explain which dependency still requires it.

@pfe-nazaries
Copy link
Copy Markdown
Contributor Author

pfe-nazaries commented May 26, 2026

Thanks for the close read @Alan-TheGentleman — both addressed in 1884ddd:

  1. healthcheck regression — not intentional. It got dropped when I resolved the ui/package.json rebase conflict against chore(ui): add prettier-plugin-packagejson to enforce key ordering #11172 (the prettier-plugin-packagejson PR that enhanced healthcheck) by taking my branch's version wholesale, which still had the old two-step script. Restored format:check so the chain is back to typecheck && lint:check && format:check. Formatting itself is also enforced in the prek hook (ui/.pre-commit-config.yaml) on staged files, but healthcheck is meant to mirror what CI runs, so keeping all three is right.
  2. *@nextui-org/* — confirmed dead: 0 source imports (grep -r "@nextui-org" ui/ --exclude-dir=node_modules returns only pnpm-workspace.yaml itself), 0 packages in the resolved tree (pnpm list | grep @nextui empty, lockfile has 0 occurrences). It's a legacy carry-over from the NextUI → HeroUI rename. Removed; *@heroui/* stays since the UI still imports HeroUI directly.

alejandrobailo
alejandrobailo previously approved these changes May 26, 2026
cesararroba
cesararroba previously approved these changes May 26, 2026
Pablo F.G added 11 commits May 27, 2026 13:49
- Bump pnpm 10.33.0 → 11.1.3 (Node ≥22.13 required by pnpm 11)
- Migrate package.json#pnpm.overrides and .npmrc settings to
  pnpm-workspace.yaml (required by pnpm 11; .npmrc deleted)
- Read Node from ui/.nvmrc and pnpm from packageManager in CI
  workflows (drop hardcoded versions)
- Add engines + engineStrict; document trustPolicyExclude for
  known false positives (next-auth, langium, semver)
- Add corepack pre-start hook to wt.toml; comment Dockerfile
  FROM to keep in sync with .nvmrc
The pnpm 11 migration in 8fa7959 removed ui/.npmrc (its settings
moved to pnpm-workspace.yaml), but the Dockerfile's deps stage still
listed .npmrc in its COPY line, breaking the ui-container build
("failed to compute cache key ... \"/.npmrc\": not found").
- Tighten engines.pnpm to ">=11.1.3" so it stops drifting below the
  exact version pinned by packageManager (pnpm@11.1.3).
- Split the corepack pre-start block in .config/wt.toml into two
  [[pre-start]] entries: worktrunk runs keys inside one block
  concurrently, so corepack-install could race ahead of
  corepack-enable. Two ordered blocks guarantee enable runs first.
Three transitive copies of uuid were present in the lockfile: 9.0.1
(@sentry/webpack-plugin), 10.0.0 (@langchain/langgraph) and 13.0.2
(streamdown/mermaid). The first two land below the 11.1.1 fix for
GHSA-w5hq-g745-h8pq (missing bounds check in v3/v5/v6 name-based
generators when buf is provided).

In practice the consumers in our tree call uuid.v4() only, so the
vulnerable code path isn't reachable, but pinning via overrides
unifies the tree on a single patched version (11.1.1) and clears the
osv-scanner finding.
…oist)

- Restore format:check in the healthcheck script. It was dropped
  inadvertently when the package.json rebase conflict from PR #11172
  (prettier-plugin-packagejson) was resolved with --theirs, losing
  master's healthcheck enhancement. Format enforcement is meant to
  run together with typecheck and lint, not somewhere else.
- Drop the `*@nextui-org/*` publicHoistPattern entry. It was a legacy
  carry-over from the NextUI -> HeroUI rename: zero source imports
  and zero packages in the resolved tree. The `*@heroui/*` entry
  stays because the UI still imports HeroUI directly.
@pfe-nazaries pfe-nazaries force-pushed the feature/pnpm-security-defaults branch from 6be5b2a to f498250 Compare May 27, 2026 11:51
@pfe-nazaries pfe-nazaries merged commit 8f745cd into master May 28, 2026
29 checks passed
@pfe-nazaries pfe-nazaries deleted the feature/pnpm-security-defaults branch May 28, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/ui github_actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants