Base44 security guide
How to secure your own Supabase project in a Base44 app
Base44 apps run on Base44's managed backend by default and need no Supabase. If you connect your own Supabase project anyway, reach it only from a backend function, store its key in Base44 secrets, and make each function check who is calling. Enable RLS on every Supabase table, then run both Base44's security scan and Supabase's Security Advisor before you publish.
Last updated
Does a Base44 app need Supabase at all?
Most do not. Base44 provides a managed database, user management, backend functions and hosting, and controls access with data permissions you set by AI chat or by hand. Base44 docs say auth tokens are stored in the browser's localStorage.
Connect Supabase only when you need data that already lives there. External services are reached through backend functions and API calls.
Where should the Supabase key live in a Base44 app?
- Store the Supabase key in Base44 secrets, never in frontend code.
- Call Supabase only from a backend function.
- Remember that Base44 users are not Supabase Auth users, so RLS cannot tell them apart. A function that holds a secret key (sb_secret_) bypasses RLS and must check the caller itself.
- Run Base44's security scan. It checks for exposed secrets.
What should a Base44 backend function check before it calls Supabase?
- Who is calling. Refuse anonymous callers for private data.
- Which rows that caller may see. With a secret key, RLS will not do this for you.
- Which tables and filters the request may name. Never pass them through from the client.
- How many rows one call may return.
How do I enable RLS in the Supabase project?
Base44's data permissions do not reach Supabase. Enable RLS on each Supabase table. With no policy, the API returns nothing to anon and authenticated, so only your backend function can read the data.
alter table public.invoices enable row level security;
create policy "invoices: customer reads" on public.invoices
for select to authenticated
using ((select auth.uid()) = customer_id);
create index invoices_customer_idx on public.invoices (customer_id);-- Every table in public without RLS. Expect zero rows.
select c.relname
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where n.nspname = 'public' and c.relkind = 'r' and not c.relrowsecurity;What do Base44's security checks cover?
These checks cover Base44's own backend. For a Supabase project you connect, open Supabase's Security Advisor and clear lint 0013 (RLS disabled in public) and lint 0010 (security definer views).
- Data permissions, user field access and private fields.
- Exposed secrets and backend functions.
- Dependencies and security headers, plus static analysis on the Builder plan and up.
- The publish panel shows security status. Fixes are not applied automatically. Wiz and Tenzai integrations are optional.
Frequently asked questions
- Can I use Supabase Auth instead of Base44's user management?
- Base44's docs do not describe that. Base44 handles users itself. If you call Supabase from a backend function, you decide how that function identifies the caller, and that check is the one to test.
- Will Base44 fix a Supabase problem its scan finds?
- Base44's scan shows security status in the publish panel and does not apply fixes automatically. It is also not documented to look inside an external Supabase project.
- How do I know my Base44 backend function is not leaking Supabase data?
- Call it signed out and as a second user, and confirm both get nothing private. After launch, Supahound's service-key and bulk-export detectors watch the Supabase side.