Lovable + Supabase security playbook (post April 2026 BOLA breach)
Updated
Lovable hit $6.6B and $100M ARR — and the April 2026 BOLA disclosure. The structural fix: every Lovable app needs (1) RLS on every Supabase table, (2) tenant-scoped policies, (3) no direct browser-to-anon-key REST calls without RLS protection. See /incidents/lovable-bola-april-2026 for the full case.
What breaks on this stack
RLS disabled on at least one Supabase table
10.3% of Lovable apps had this in April 2026. Enable RLS on every table; default-deny baseline.
Read the guide →Hardcoded anon_key in client bundle
Lovable's generator hardcodes the anon_key. anon_key is public BY DESIGN — without RLS, it's a skeleton key.
Read the guide →Cross-tenant data leak via shared user_id
Policies scoping by auth.uid() only fail when user_ids span tenants. Add tenant claim from JWT.
Read the guide →Storage buckets default-public
Supabase Storage buckets need RLS too; many Lovable templates leave them public.
Read the guide →Pre-ship checklist
- RLS enabled on every table (alter table T enable row level security)
- Default-deny policy layered under explicit allows
- Tenant-scoped (auth.uid() AND tenant claim from JWT)
- anon_key only used with RLS-protected tables
- Storage buckets have RLS policies
- Service role key server-only
Starter config
-- canonical Supabase RLS bundle for Lovable apps
alter table public.orders enable row level security;
create policy "users_read_own_in_tenant" on public.orders for select
using (auth.uid() = user_id and tenant_id = (auth.jwt() ->> 'tenant')::uuid);