Guides / Is my Lovable app secure? (Supabase RLS checklist)

last checked oct 2026

Is my Lovable app secure? (Supabase RLS checklist)

Lovable ships real security tooling now. It still cannot know which rows your users should see. Here is the 20-minute check we run before a Lovable app goes public.

1. Run both built-in scans, not just the automatic one

Lovable has two scans. The Quick scan runs automatically when you open the publish dialog and checks database access rules, npm dependencies and MCP server exposure. The Deep scan reviews your actual application code (access control, unauthenticated endpoints, injection, leaked secrets, payments, auth) and does not run on its own.

Lovable's own docs say the scanners "cannot guarantee complete security" and recommend a professional review for apps handling sensitive data. Treat a clean scan as the floor, not the finish line.

2. Read your RLS policies yourself

If you use Lovable's built-in backend, every policy is listed under More → Cloud → Database → RLS policies. If your app is connected to your own Supabase project, open the SQL Editor in the Supabase dashboard and run:

-- 1. Which public tables have RLS off?
select tablename, rowsecurity
from pg_tables
where schemaname = 'public'
order by rowsecurity, tablename;

-- 2. What do the policies actually allow?
select tablename, policyname, roles, cmd, qual, with_check
from pg_policies
where schemaname = 'public'
order by tablename, cmd;

What you are looking for:

3. The owner-only pattern, written correctly

For a table where each user only touches their own rows, Supabase's documented pattern is one policy per operation:

alter table public.profiles enable row level security;

create policy "Users can view their own profile."
on profiles for select to authenticated
using ( (select auth.uid()) = user_id );

create policy "Users can create their own profile."
on profiles for insert to authenticated
with check ( (select auth.uid()) = user_id );

create policy "Users can update their own profile."
on profiles for update to authenticated
using ( (select auth.uid()) = user_id )
with check ( (select auth.uid()) = user_id );

create policy "Users can delete their own profile."
on profiles for delete to authenticated
using ( (select auth.uid()) = user_id );

Wrapping auth.uid() in (select ...) is Supabase's recommended form: it lets Postgres cache the value per statement instead of calling it per row. More detail in our Supabase RLS guide.

How using and with check actually work

Where the real update risks are:

Test, don't trust. In the SQL editor, impersonate a user inside a transaction and try the attack:

-- Attempt 1: can user A see or steal other rows?
begin;
set local role authenticated;
select set_config('request.jwt.claims',
  '{"sub":"<user-a-uuid>","role":"authenticated"}', true);
select * from profiles;   -- should show only user A's rows
update profiles set user_id = '<user-b-uuid>'
  where user_id = '<user-a-uuid>';   -- should fail (RLS error, or permission denied if column grants exclude user_id)
rollback;

-- Attempt 2 (separate transaction): can user A make themselves admin?
begin;
set local role authenticated;
select set_config('request.jwt.claims',
  '{"sub":"<user-a-uuid>","role":"authenticated"}', true);
update profiles set is_admin = true
  where user_id = '<user-a-uuid>';   -- should fail once column privileges are set
rollback;

We ran every SQL example in this guide against PostgreSQL 18.4 with a stub auth.uid() reading request.jwt.claims, the way Supabase does. Results matched the behavior described above.

4. Never authorize on user_metadata

Supabase warns that raw_user_meta_data can be updated by the signed-in user. A policy like "admins can read everything" that checks a role stored there lets any user promote themselves. Store roles in app_metadata or in a table the user cannot write.

5. Keep secret keys out of the frontend

Lovable builds browser code, and anything in the browser is public. Lovable detects API keys pasted into chat and steers you to store them in Secrets and call the service from server-side code. Check that nothing slipped past:

6. Turn on leaked password protection

If users sign in with email and password: on Lovable Cloud, enable Password HIBP check under More → Cloud → Users → Auth settings → Email. On your own Supabase project, use Supabase's leaked password protection setting.

Pre-launch checklist

next step

Want a second pair of eyes?

Grab the free Lockdown Pack (security rules for Cursor and Claude Code plus a pre-launch checklist), or have us check the whole app for a fixed $99.

Sources

Every product step above was checked against these official pages. Last checked Oct 2026. Products change; if a menu moved, the docs below are the source of truth.