Skip to content
VibeSafeDaily

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.

  1. In your own SQL editor, list views: select viewname from pg_views where schemaname = 'public'.
  2. For each view your app reads, check reloptions on the view for security_invoker=true. A view without that option is the risky default.
  3. As test user B in your project, select from the view and confirm A's private rows are absent.

Sources

Same symptom