security: RLS defense-in-depth on data tables + fix high-sev deps

🟢 open · #1 · vimgitai/mikeoss ← vimgitai/mikeoss · opened 18d ago by vimgitai · self · +147-98 across 2 files · ↗ on GitHub

From the PR description

From the full security review. Two hardening items. Merging code alone applies no production change - the DB migration must be run separately (checklist below).

1. RLS defense-in-depth migration

backend/migrations/20260701_01_rls_defense_in_depth.sql

Backend-only data tables (documents, document_versions, chats, chat_messages, tabular_reviews, tabular_cells, projects, workflows, ...) are currently protected only by REVOKE ALL FROM anon, authenticated. The earlier migration's comment claims "RLS remains enabled as defense in depth" - but RLS was never actually enabled, and there is no ALTER DEFAULT PRIVILEGES. One forgotten REVOKE (a new table, or a mistaken grant) would expose live legal data to the public anon REST key.

This migration:

  • ENABLE + FORCE ROW LEVEL SECURITY on all 14 data tables (no policies -> anon/authenticated get zero rows)
  • ALTER DEFAULT PRIVILEGES ... REVOKE ALL ON TABLES/SEQUENCES FROM anon, authenticated -> future tables auto-revoke

Safe for the app: backend connects with the service_role key (BYPASSRLS), so no backend query changes; frontend never queries these tables directly. Net: no functional change, strictly stronger isolation. Rollback: DISABLE ROW LEVEL SECURITY.

2. Dependency fix

Non-breaking npm audit fix on the backend clears the high-severity tmp (path traversal) and ws (memory disclosure / DoS) advisories. 12 -> 2 vulns. Only package-lock.json changed; tsc build verified clean.

Deploy checklist (do NOT auto-merge)

  1. Review.
  2. Apply the migration to the production Supabase DB in a low-traffic window.
  3. Confirm app reads/writes normally (backend service_role unaffected).
  4. Merge -> Railway redeploy picks up the dependency fix.

🤖 Generated with Claude Code

Our analysis

Enforce row-level security on backend data tables as defense-in-depth — read the full analysis →

Think the analysis missed something the PR description covers?

Capture this PR into my fork

Download a Markdown prompt that tells Claude how to port every commit in this PR into your working tree. Run it via claude -p < capture-pull-1.md from inside the repo you want the changes in.

⬇ Download capture-pull-1.md