Skip to content

docs: add guide for securing npm installs against supply-chain attacks#46384

Merged
mandarini merged 21 commits into
masterfrom
docs/npm-safeguard
May 26, 2026
Merged

docs: add guide for securing npm installs against supply-chain attacks#46384
mandarini merged 21 commits into
masterfrom
docs/npm-safeguard

Conversation

@mandarini

@mandarini mandarini commented May 26, 2026

Copy link
Copy Markdown
Contributor

Adds a consumer-side guide for hardening npm installs of @supabase/* packages: lockfile hygiene, minimum-release-age quarantine across pnpm/yarn/npm/bun, private registries, provenance verification, lifecycle script controls, blocking exotic transitive refs, Edge Functions specifics, and an incident-response checklist.

Lives at guides/security/ alongside platform-security and product-security; filesystem-driven sidebar picks it up automatically.

Originally drafted in supabase/supabase-js#2382 and moved here per review.

Summary by CodeRabbit

  • Documentation
    • Added an npm security hardening guide (lockfile & CI practices, release-age quarantines, transitive/exotic dependency controls, provenance verification, lifecycle-script hardening, package-manager pinning, CI/lockfile hygiene, Deno/Edge guidance, incident-response checklist).
    • Added a navigation entry for the new guide.
    • Note: guide frontmatter contains unresolved merge-conflict markers.
  • Chores
    • Expanded spelling allowlist to include common tech terms (e.g., lockfile, sigstore, postinstall).

Review Change Stack

@vercel

vercel Bot commented May 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment, Open in v0 May 26, 2026 2:17pm
6 Skipped Deployments
Project Deployment Actions Updated (UTC)
studio Ignored Ignored May 26, 2026 2:17pm
design-system Skipped Skipped May 26, 2026 2:17pm
studio-self-hosted Skipped Skipped May 26, 2026 2:17pm
studio-staging Skipped Skipped May 26, 2026 2:17pm
ui-library Skipped Skipped May 26, 2026 2:17pm
zone-www-dot-com Skipped Skipped May 26, 2026 2:17pm

Request Review

@supabase

supabase Bot commented May 26, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project xguihxuzqibwxjnimxev because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label May 26, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit

rdjsonl

🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: lockfile (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- Run `--frozen-lockfile` / `npm ci` in every CI job. Never let CI silently regenerate the lockfile.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: lockfile (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- Review lockfile diffs in PRs the same way you review code diffs. Unexpected new transitives or version jumps deserve a question.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: transitives (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- Review lockfile diffs in PRs the same way you review code diffs. Unexpected new transitives or version jumps deserve a question.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: Dependabot (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- Configure Dependabot or Renovate to batch updates and respect the same min-age you set locally. Renovate's `minimumReleaseAge` option is the direct equivalent.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: Dependabot (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- **Enable [Dependabot alerts](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/about-dependabot-alerts)** on every repository that has a lockfile. Free for both public and private repos. It checks your lockfile against the GitHub Advisory Database and pings you when a transitive becomes a known-vulnerable version.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: lockfile (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- **Enable [Dependabot alerts](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/about-dependabot-alerts)** on every repository that has a lockfile. Free for both public and private repos. It checks your lockfile against the GitHub Advisory Database and pings you when a transitive becomes a known-vulnerable version.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: lockfile (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- **Enable [Dependabot alerts](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/about-dependabot-alerts)** on every repository that has a lockfile. Free for both public and private repos. It checks your lockfile against the GitHub Advisory Database and pings you when a transitive becomes a known-vulnerable version.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: Snyk (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- **Third-party scanners** — Socket, Snyk, Aikido, and similar services often spot compromises faster than the GHSA feed. We don't endorse a specific one; if your org already has a license, plug it in. If not, evaluate based on detection time on past incidents, not feature lists.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: Bluesky (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- **Watch the channels your peers watch.** During the TanStack incident, GitHub issue #7383 and a handful of security researcher accounts on X / Bluesky were the canonical signal hours before formal advisories. There is no substitute for a few well-curated follows.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: defenses (configure rule at supa-mdx-lint/Rule003Spelling.toml)

If you're using `@supabase/supabase-js` (or any `npm:` specifier) from Deno in a Supabase Edge Function, you don't have the npm-side minimum-release-age gate available at the runtime layer. The practical defenses are:


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: vendored (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- **Vendor critical dependencies** (`deno vendor`) and commit the vendored output. This freezes the dep at a known-good snapshot and removes the runtime fetch entirely.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: lockfile (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- **Stay current on Deno** — newer versions are landing more supply-chain features (lockfile integrity, `npm:` provenance verification). Track the [Deno release notes](https://github.com/denoland/deno/releases).


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: exfiltrated (configure rule at supa-mdx-lint/Rule003Spelling.toml)

1. **Treat the install host as potentially compromised.** Anything readable by the user that ran the install — env vars, files, secrets in memory — should be assumed exfiltrated.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: installable (configure rule at supa-mdx-lint/Rule003Spelling.toml)

6. **Report it**: file a GitHub Security Advisory on the upstream repo, and email `security@npmjs.com` if the version is still installable.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: sigstore (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- **Provenance attestations.** Every release of `@supabase/supabase-js` and its sibling packages ships with a sigstore attestation tying the tarball to its source commit and workflow run. Verify with `npm audit signatures`.


🚫 [rdjsonl] reported by reviewdog 🐶
[Rule003Spelling] Word not found in dictionary: Adnan (configure rule at supa-mdx-lint/Rule003Spelling.toml)

- Adnan Khan, ["The Monsters in Your Build Cache — GitHub Actions Cache Poisoning"](https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/) (May 2024).

@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a consumer-facing MDX guide for hardening npm installs (lockfiles, transitive pinning, minimum-release-age quarantines, provenance checks, lifecycle-script controls, exotic-ref blocking, package-manager pinning, CI/lockfile hygiene), plus a navigation entry and expanded MDX-lint spelling allowlist; frontmatter contains unresolved merge-conflict markers.

Changes

npm Security Hardening Guide

Layer / File(s) Summary
Frontmatter, title conflict, and introduction
apps/docs/content/guides/security/npm-security.mdx
Frontmatter updated but includes unresolved merge-conflict markers; intro and TL;DR checklist of core hardening steps.
Dependency/version pinning and minimum-age quarantine
apps/docs/content/guides/security/npm-security.mdx
Commit/enforce lockfiles, pin transitive deps via overrides/resolutions, avoid ad-hoc npx/dlx/bunx, and configure per-manager minimum-release-age quarantine (pnpm/yarn/npm/bun).
Provenance verification, lifecycle-script hardening, exotic refs
apps/docs/content/guides/security/npm-security.mdx
Describe Sigstore attestations and npm audit signatures verification; recommend deny-by-default lifecycle scripts and manager-specific allowlists/ignore-scripts; block exotic/non-registry dependency refs.
Package-manager pinning, pruning, CI hygiene
apps/docs/content/guides/security/npm-security.mdx
Recommend packageManager+sha512 pinning, prune unused deps, enforce frozen lockfile CI installs, review lockfile diffs, and configure Renovate/Dependabot to respect min-age.
Monitoring, Edge/Deno, incident response, Supabase practices, references
apps/docs/content/guides/security/npm-security.mdx
Stay-informed monitoring steps, Edge Functions/Deno defenses (pin/vendor/fail-on-change), incident-response checklist, Supabase-side publishing controls, and references.
Documentation navigation update
apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
Adds “Securing your npm installs” to Security → Guides linking to /guides/security/npm-security.
MDX-lint spelling allowlist updates
supa-mdx-lint/Rule003Spelling.toml
Expanded allow_list with entries/patterns used in the new guide (e.g., lockfile, sigstore, postinstall, unpublish, tooling and vendor names, and regex patterns).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • kallebysantos
  • gregnr

Poem

🐰 I nibble words and patch the trail,
Lockfiles snug and provenance hale,
Quiet scripts, exotic refs barred,
Quarantine waits for packages starred,
We pin and vet—safe hops prevail.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete and does not follow the required template structure. It lacks the required sections: 'I have read CONTRIBUTING.md', 'What kind of change', 'What is the current behavior', and 'Additional context'. Restructure the description to follow the template: add the CONTRIBUTING.md acknowledgment, categorize the change type (docs update), provide context/issue links, and maintain the existing detailed summary as part of the new behavior section.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding a guide for securing npm installs against supply-chain attacks, which directly matches the PR's primary objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/npm-safeguard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mandarini mandarini force-pushed the docs/npm-safeguard branch from f30ddf4 to ad567f2 Compare May 26, 2026 13:41

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/docs/content/guides/security/npm-security.mdx`:
- Around line 3-9: Remove the unresolved git conflict markers (<<<<<<<, =======,
>>>>>>>) from the MDX frontmatter and leave a single coherent title/description
pair; specifically, edit the frontmatter fields "title" and "description" to
remove the conflict blocks and keep the intended values (e.g., title: 'Securing
npm installs' and description: 'Consumer-side guide to hardening your npm
installs of Supabase packages against supply-chain attacks.'), ensuring the
frontmatter is valid YAML/MDX (no conflict markers remain) so the file
(apps/docs/content/guides/security/npm-security.mdx) parses correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: e6a19baa-930b-4db1-9f99-d124cfd154b8

📥 Commits

Reviewing files that changed from the base of the PR and between 68d5990 and 919f6cc.

📒 Files selected for processing (3)
  • apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
  • apps/docs/content/guides/security/npm-security.mdx
  • supa-mdx-lint/Rule003Spelling.toml

Comment thread apps/docs/content/guides/security/npm-security.mdx Outdated
@mandarini mandarini self-assigned this May 26, 2026
@mandarini mandarini merged commit c9d34a6 into master May 26, 2026
32 checks passed
@mandarini mandarini deleted the docs/npm-safeguard branch May 26, 2026 14:20
@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Braintrust eval report

Assistant (master-1779805332)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants