LibraryExposed data
A view bypasses row level security
Cataloged October 16, 2026 · Lovable · Bolt · Cursor · Supabase
Symptom
The table policies look right. A view the app selects from still returns every row.
Root cause
Supabase documents that views bypass RLS by default because Postgres creates them as security definer, usually owned by postgres. A view over a protected table can hand out rows the table policies were meant to withhold. The guide says a view needs the same attention as a table, and points at creating it with security invoker.
Fix prompt
In this project only, list views in the public schema. For each view that clients can select, recreate it with security_invoker = true so the caller's RLS applies: create or replace view public.your_view with (security_invoker = true) as select id, user_id, title from public.your_table; Do not select sensitive columns the caller should not see. Add a test as anon and as a second user. Do not change other projects.
Paste this into the coding tool that has your own project open.
2-minute self-check
These steps are for an app you own. Do not run them against someone else's project.
- In your own SQL editor, list views: select viewname from pg_views where schemaname = 'public'.
- For each view your app reads, check reloptions on the view for security_invoker=true. A view without that option is the risky default.
- As test user B in your project, select from the view and confirm A's private rows are absent.