What is row level security?
Row level security (RLS) is a database setting that decides which rows each user is allowed to see or change. With it switched on, a logged-in user only gets their own data. With it off, anyone who has your app's public key can read or edit every row in the table.
Also called: RLS
ON THIS PAGE
What it means
Your database is made of tables, and each table is made of rows. One row might be one user's profile, one order, or one message. Row level security is a switch, plus a set of rules called policies, that decides which of those rows a person can see or change.
Without it, your database has no idea who is asking. If someone has the key your app uses to talk to the database (and in most AI-built apps that key is public by design), they can ask for everything.
Why it matters for vibe-coded apps
Tools like Lovable and Bolt often use Supabase as the database. Supabase expects you to turn on row level security for every table, but the AI doesn't always do it, especially for tables added later in a project.
- Your users' names, emails and messages can be downloaded by anyone.
- Someone could change or delete other people's data.
- Your app works perfectly while this is happening, so you won't notice.
Example
Say your app has a profiles table. The AI created it, but never turned on row level security.
-- Table created, but RLS never switched on
create table profiles (
id uuid primary key,
email text,
phone text
);alter table profiles enable row level security;
create policy "Users can read their own profile"
on profiles for select
using ( auth.uid() = id );The policy says: only return a row if the logged-in user's ID matches the row's ID.
How to check if your app has this problem
- 1Open your Supabase dashboard and go to Table Editor.
- 2Look for any table marked "RLS disabled" or "Unrestricted".
- 3For tables with RLS on, open Authentication → Policies and make sure each one has at least one policy.
The quicker way: LetMeCheck tests for this automatically, from the outside, the way an attacker would.
Run a free scan →How to fix it
- 1Turn on row level security for every table that holds user data.
- 2Add a policy for each action (read, add, change, delete) that limits it to the row's owner.
- 3Test it: log in as one user and make sure you can't see another user's data.
- 4Run a check again to confirm the table is no longer open.
Turn on row level security for every table in my Supabase database. For each table with a user_id column, add policies so a logged-in user can only read, insert, update and delete their own rows. Don't change any other logic.
Check if your app has this problem
Paste your website and we'll check for row level security issues and other common issues in AI-built apps. Free, about a minute, and nothing on your site is changed.
Last updated
Related terms
- Service role keyA Supabase key that skips every security rule, meant only for your server.
- API key exposureA secret key for a paid service ends up where the public can see it.
- Authentication vs authorizationChecking who someone is, versus checking what they're allowed to do.
- Firebase security rulesThe rules that decide who can read and write data in Firebase.
- Public storage bucketA folder of uploaded files that anyone with the link can open.
Related reading
Need help?
Not sure what this means for your app? Our team will explain it in plain English.