Skip to content

PLT-658: Supply chain security hardening β€” pnpm v10.33.4, CI audit, Actions SHA pinning#170

Merged
zemeja merged 2 commits into
masterfrom
plt-658
May 13, 2026
Merged

PLT-658: Supply chain security hardening β€” pnpm v10.33.4, CI audit, Actions SHA pinning#170
zemeja merged 2 commits into
masterfrom
plt-658

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented May 7, 2026

Copy link
Copy Markdown

I have created this PR because

This applies supply chain security hardening to the purple-stack monorepo, following the patterns established in my-axiory PR #8946 and prop-tech-engine PR #1604.

A follow-up commit on this branch goes further than the source PRs: because this is a template repo with no legacy debt, we both (a) cleared every existing high/critical advisory and (b) flipped the audit job to fail on any new finding.

Changes

pnpm upgrade (10.18.2 β†’ 10.33.4)

  • Updated packageManager in package.json and mise.toml

pnpm 10 security features (pnpm-workspace.yaml)

Feature Value Purpose
strictDepBuilds true Blocks postinstall scripts unless explicitly allowed
allowBuilds esbuild: true, telemetry scripts blocked Whitelist for legitimate build scripts
minimumReleaseAge 10080 (7 days) Blocks freshly-published packages (typosquatting defense)
minimumReleaseAgeExclude @purple/*, @package/* Internal packages bypass the 7-day wait
trustPolicy no-downgrade Prevents provenance downgrades
blockExoticSubdeps true Blocks git/http URLs in transitive dependencies

CI hardening

  • SHA-pinned third-party GitHub Actions (jdx/mise-action@v3, aws-actions/configure-aws-credentials@v4) β€” GitHub-owned actions (actions/*) left on version tags per convention
  • Added save-prefix='' to .npmrc (complements existing save-exact=true)
  • Added security-audit.yaml reusable workflow (pnpm audit), wired into the test pipeline

Audit enforcement & vulnerability fixes (commit 213fe38)

The initial commit shipped pnpm audit with continue-on-error: true (the same posture as our app repos, which need a grace period before fixing inherited vulns). For a template repo we can be stricter: zero high/critical advisories and a hard-fail CI gate, so the template never seeds new repos with known vulns.

Cleared 1 critical + 9 high advisories:

Module Severity Fix Route
@trpc/server high catalog β†’ 11.17.0 Direct (GHSA-43p4-m455-4f4j, prototype pollution)
vite high Γ— 2 catalog β†’ 7.3.2 + override Direct + transitive (GHSA-v2wj-q39q-566r, GHSA-p9ff-h696-f583)
fast-xml-parser 1 critical + 3 high pnpm.overrides >=5.5.6 Transitive via @aws-sdk/client-sfn
picomatch high pnpm.overrides >=4.0.4 Transitive via vite/chokidar (ReDoS)
path-to-regexp high pnpm.overrides >=8.4.0 Transitive via express β†’ router (DoS)

Approach decisions:

  • Catalog bump for direct deps, pnpm.overrides for transitives. Forcing the resolution is more honest than chasing a direct-dep version that happens to pull the patched transitive β€” it makes the fix explicit and easy to remove when upstream catches up.
  • vite is in both places. The catalog bump alone left vitest's bundled vite at 7.3.1, so it also lives in pnpm.overrides.
  • Stuck at vite@7.3.2 even though 7.3.3 exists β€” 7.3.3 was published 2026-05-07 and is blocked by our minimumReleaseAge: 10080 (7 days). 7.3.2 is the highest version old enough to pass the gate, and it still satisfies the advisory patched_versions: >=7.3.2.
  • Removed continue-on-error: true from security-audit.yaml. The workflow_call audit-level input remains so downstream consumers of this template can configure their own bar.

After the fix: pnpm audit --audit-level high β†’ 0 advisories (10 moderate remain, by design β€” audit-level is high).

Plan document: docs/plans/2026-05-11-001-feat-enforce-pnpm-audit-and-fix-vulns-plan.md

Verification

  • pnpm install β€” clean resolve, lockfile updated
  • pnpm run -r typecheck β€” pass (catches any @trpc/server 11.6 β†’ 11.17 type drift)
  • pnpm run -r test β€” pass
  • pnpm lint β€” pass
  • pnpm audit --audit-level high β€” 0 high, 0 critical
  • CI security-audit job β€” must be green for this PR to merge (proves the fixes hold and the gate works)

Not in scope

  • No runtime dependency upgrades beyond the security-driven ones above
  • No Renovate configuration (not present in repo, not added)
  • Moderate/low advisories (currently 10 moderate) β€” audit-level remains high by design

Operational notes

If a new high/critical advisory drops for a dep with no patched version yet, CI will go red and block merges β€” this is the explicit accepted tradeoff. Options for the PR author at that point: (a) downgrade the dep, (b) add a pinned pnpm.overrides to a non-vulnerable version, (c) temporarily raise audit-level to critical in a focused, time-boxed PR. There is intentionally no pre-built escape hatch (allowlist, advisory-ignore file) β€” keep the signal honest.

Human review checklist

  • Verify the allowBuilds list is complete β€” only esbuild was flagged during pnpm install; if your project has other deps with postinstall scripts, they'll need to be added
  • Confirm minimumReleaseAgeExclude covers all internal package scopes you use
  • Verify SHA pins are correct for jdx/mise-action and aws-actions/configure-aws-credentials (resolved from rolling major tags v3/v4)
  • Confirm the pnpm.overrides block in root package.json is the right home (vs. overrides: in pnpm-workspace.yaml) β€” both work on pnpm 10
  • Sanity-check that @trpc/server 11.6 β†’ 11.17 didn't change any router/handler shape we rely on (typecheck already passed; runtime smoke-test on deploy)

Post-Deploy Monitoring & Validation

No additional production monitoring required β€” this PR is build-time/CI-only. Validation surface is the CI run on this branch:

  • test.yaml > test should remain green (proves @trpc/server 11.17 and vite 7.3.2 don't break the workspace)
  • test.yaml > security-audit should be green (proves U1+U2 cleared every high/critical finding and the now-blocking gate works)

If either goes red on this PR or a future one, the failure log itself is the actionable signal β€” no dashboard or external metric to watch.

Link to Devin session: https://app.devin.ai/sessions/e6f9d0be409943c4b66901239f3246e4

…ons SHA pinning

- Upgrade pnpm from 10.18.2 to 10.33.4 (package.json, mise.toml)
- Enable pnpm 10 security features in pnpm-workspace.yaml:
  strictDepBuilds, allowBuilds, minimumReleaseAge (7 days),
  trustPolicy (no-downgrade), blockExoticSubdeps
- Add save-prefix='' to .npmrc
- Pin third-party GitHub Actions to commit SHAs:
  jdx/mise-action@v3, aws-actions/configure-aws-credentials@v4
- Add security-audit.yaml reusable workflow (pnpm audit)
- Wire security audit into test pipeline
@linear

linear Bot commented May 7, 2026

Copy link
Copy Markdown

@devin-ai-integration

Copy link
Copy Markdown
Author

πŸ€– Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

βœ… I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

βš™οΈ Control Options:

  • Disable automatic comment and CI monitoring

…rce in CI

- Bump @trpc/server and @trpc/client 11.6.0 β†’ 11.17.0 in catalog
  (CVE-2025-68130 / GHSA-43p4-m455-4f4j, prototype pollution in
  experimental_nextAppDirCaller)
- Bump vite 7.1.9 β†’ 7.3.2 in catalog (GHSA-v2wj-q39q-566r, GHSA-p9ff-h696-f583
  dev-server fs.deny bypass and WS arbitrary file read). 7.3.3 is <7d old,
  blocked by minimumReleaseAge: 10080.
- Add pnpm.overrides for transitive vulns with no direct upgrade path:
  - fast-xml-parser β‰₯5.5.6 (CVE-2026-25128/-25896/-26278/-33036, via
    @aws-sdk/client-sfn β†’ @aws-sdk/xml-builder)
  - picomatch β‰₯4.0.4 (ReDoS, transitive via vite/chokidar)
  - path-to-regexp β‰₯8.4.0 (DoS via sequential optional groups, transitive
    via express β†’ router)
  - vite β‰₯7.3.2 (catalog bump alone left vitest's transitive vite at 7.3.1)
- Remove `continue-on-error: true` from .github/workflows/security-audit.yaml
  so any future high/critical advisory blocks the build. workflow_call
  audit-level input remains so downstream consumers can configure their bar.

Verification:
- `pnpm audit --audit-level high` β†’ 0 advisories
- `pnpm run -r typecheck` β†’ green
- `pnpm run -r test` β†’ green
- `pnpm lint` β†’ green

Plan: docs/plans/2026-05-11-001-feat-enforce-pnpm-audit-and-fix-vulns-plan.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zemeja zemeja requested a review from a team May 11, 2026 14:26
@zemeja zemeja merged commit 16f5146 into master May 13, 2026
3 checks passed
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.

2 participants