Skip to content

fix(db): lock Supabase's Data API out — RLS on every table, no grants to anon - #12

Merged
devinder-dev merged 1 commit into
mainfrom
fix/supabase-data-api-lockdown
Sep 23, 2026
Merged

devinder-dev merged 1 commit into
mainfrom
fix/supabase-data-api-lockdown

Conversation

@devinder-dev

Copy link
Copy Markdown
Owner

Why

Supabase publishes every table in public through its REST Data API and grants anon/authenticated full access to new tables. The anon key is public by design. Checked after the first migration: all 12 tables had RLS off and anon could SELECT and INSERT — User password hashes readable, Transaction ledger writable, without going through our API. We never use the Data API.

What

  • Migration 20260923160000_lock_down_supabase_data_api
    • RLS on every table, no policies (the app role bypasses RLS: postgres/BYPASSRLS on Supabase, table owner elsewhere)
    • REVOKE ALL from anon, authenticated on tables/sequences/functions + default privileges for future tables — guarded, so plain Postgres skips it
  • tests/integration/rls.test.ts — fails if any table lacks RLS (shown failing on all 12 tables before the migration)
  • ADR 54

Verified on Supabase (already applied, same file)

  • 12/12 tables: rls = true, anon/authenticated SELECT/INSERT = false
  • a table created afterwards (rolled back) gets no grants
  • the app still reads its data: 6 users, 22 invoices

454 backend tests pass.

… to anon

Supabase exposes `public` over PostgREST and grants anon/authenticated full
access to new tables; the anon key is public by design. After the first
migration every table had RLS off and anon could SELECT and INSERT —
password hashes readable, ledger writable, bypassing the API entirely.

- migration: ENABLE ROW LEVEL SECURITY on every table (no policies), REVOKE
  from anon/authenticated incl. default privileges; the revoke is guarded
  so plain Postgres (local, CI) skips it
- tests/integration/rls.test.ts fails on any table without RLS
- applied and verified on Supabase: RLS on, anon/authenticated denied,
  future tables not granted, app still reads its data
- ADR 54
@vercel

vercel Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
fakturly-app Building Building Preview Sep 23, 2026 1:46pm UTC

@devinder-dev
devinder-dev merged commit 3ba7af2 into main Sep 23, 2026
8 checks passed

This branch was successfully deployed

1 active deployment
Preview — 44509249 Deployed Sep 23, 2026 by vercel[bot]
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.

1 participant