Security·Cursor
SecurityCursor

Enable Supabase Row Level Security on every tableCursor

Supabase tables are readable by anyone with the anon key (which ships to the browser) unless RLS is enabled. Without RLS, any visitor can dump your entire users table.

rocket_launch

Fixing this in Cursor

Agentic AI code editor built on VSCode

Write migrations as SQL files. Run `alter table X enable row level security;` plus your policies. Supabase CLI can version-control this.

Files to touch in Cursor:

supabase/migrations/*.sql

Using a different tool? Pick your stack:

The prompt for Cursor

Copy and paste this into your Cursor chat exactly as-is.

Apply these changes to my codebase. Edit the files directly and keep existing formatting:

Enable Supabase Row Level Security

1. Open the Supabase dashboard → Authentication → Policies.
2. Enable RLS on EVERY table (no exceptions, even ones you think are public).
3. Add explicit policies (e.g. `auth.uid() = user_id`) — RLS without policies blocks everything.
4. Audit your client code: only the anon key should ever reach the browser, never the service_role key.

Why this matters

Supabase has one job: be a PostgreSQL database you can talk to from the browser. The price of that convenience is Row Level Security — without RLS, anyone with your anon key (visible in your JS bundle) can run any query against any table.

This is the single most frequent severe finding in Lovable and Bolt apps. A dev follows the Supabase quickstart, builds a user dashboard, ships it, and does not notice that `select * from users` returns everyone's email from a browser tab. We have audited sites where the entire customer database was exposed this way.

RLS is not complicated. For a typical "users see only their own rows" setup, the policy is one SQL line: `using (auth.uid() = user_id)`. Most apps need fewer than 10 policies total across all tables.

How to use this prompt in Cursor

  1. 1. Open your Cursor project.
  2. 2. Copy the prompt above with the copy button.
  3. 3. Paste into the Cursor chat and send.
  4. 4. Review the diff, accept the changes, redeploy.
  5. 5. Verify the fix using the checklist below.

Common mistakes to avoid

  • error_outlineEnabling RLS but forgetting to add a SELECT policy — the table becomes invisible, features break, devs disable RLS again.
  • error_outlineWriting a policy with `using (true)` "to get things working" — same as no RLS.
  • error_outlineUsing the service_role key in a client-side file because "nothing was working" — bypasses RLS entirely.
  • error_outlineAdding RLS only to the tables you think are sensitive — the missed one is always the problem.
  • error_outlineEnabling RLS on Supabase auth tables manually — those are managed by Supabase, leave them alone.

How to verify the fix worked

  • check_circleIn Supabase dashboard → Authentication → Policies — every non-auth table shows RLS enabled and at least one policy.
  • check_circleFrom an incognito browser (unauthenticated), try a `select` on every table — must return 401 or empty results.
  • check_circlePantra Security Audit run shows "Supabase RLS: pass" (otherwise it is flagged as critical).
  • check_circleSQL query: `select tablename from pg_tables where schemaname='public' and rowsecurity=false` — must return zero rows.

Frequently asked questions

Why does enabling RLS "break everything"?expand_more
Because enabling RLS without policies means no one can read the table. Add policies matching your access pattern (e.g., `using (auth.uid() = user_id)` for per-user data).
Do I need RLS on tables only accessed from server?expand_more
If you only ever touch them via the service_role key from a server, technically no. But enable RLS anyway — defense in depth. Future-you or a teammate will open it to the client eventually.
How do I test policies?expand_more
The Supabase dashboard has a policy tester. Also test from an incognito browser with no auth — if you can query anything you should not, the policy is wrong.

Want all 34 prompts tailored to your Cursor site?

Pantra scans your site in 10 seconds, detects the stack, and generates the exact prompts that apply — only the ones you actually need.

Scan my site

Related Cursor prompts