How to enable RLS in a Lovable (Supabase) app

Updated

How do I enable row level security in my Lovable app?

Enable RLS on every table in the public schema, then add policies that only match the signed-in user's rows: USING (auth.uid() = user_id) and, for updates, WITH CHECK (auth.uid() = user_id). Test by querying as a logged-out user: you should get no private rows back.

1. Turn RLS on for every table

In the Supabase SQL editor (or a new migration), run this for each table. With RLS on and no policies, nobody except the service role can read the table, which is a safe starting point.

alter table public.profiles enable row level security;

2. Add owner policies

Most app tables have a user_id column pointing to auth.users. These four policies give users full control over their own rows and nothing else:

create policy "select own" on public.profiles for select to authenticated using (auth.uid() = user_id);
create policy "insert own" on public.profiles for insert to authenticated with check (auth.uid() = user_id);
create policy "update own" on public.profiles for update to authenticated
  using (auth.uid() = user_id) with check (auth.uid() = user_id);
create policy "delete own" on public.profiles for delete to authenticated using (auth.uid() = user_id);

3. Make public content public on purpose

Product lists or blog posts can be readable by everyone. Give them a separate SELECT policy, and never USING (true) on UPDATE or DELETE.

create policy "posts are public" on public.posts for select using (published = true);

4. Protect privileged columns

If users can update their own profile, they can also change any column on it, including is_admin, plan or credits. Keep those in a separate table without an update policy, or set them only from server code.

Prompt for Lovable or Bolt

You can paste this into the chat:

Enable row level security on every table in the public schema. For each table with a user_id column, add SELECT, INSERT, UPDATE and DELETE policies for the authenticated role that only match auth.uid() = user_id, with WITH CHECK on INSERT and UPDATE. Do not use USING (true) for UPDATE or DELETE. Move role, plan and credit columns to a table users cannot update.

Questions

Does Lovable enable RLS automatically?

Often, but not always, and policies are sometimes broader than intended. Check every table; do not assume.

Is auth.uid() IS NOT NULL a good policy?

It allows every signed-in user to access every row. Fine for shared reference data, wrong for anything that belongs to one user.

How do I test my policies?

Query the table from the browser while logged out, and while logged in as a second test user. Neither should see another user's rows.