Missing row-level security on your Supabase or Firebase database
Row-level security (RLS) is a set of rules on your database that decide which rows a given request is allowed to touch. Supabase and Firebase both ship with RLS off or wide open by default, which means the client-side key your app already exposes to the browser can query the entire table unless you lock it down.
#What goes wrong
AI coding tools set up the database schema and the client connection, but RLS policies are a separate manual step that's easy to skip, especially since the app works fine in testing with a single account. Nothing breaks until someone opens dev tools and points a request at another user's data.
#Why it matters
The public anon key that ships in your JS bundle is, by design, visible to anyone who opens your site. If RLS isn't enabled, that key is enough to read or write any row in any table: other users' profiles, private messages, payment records, everything.
#How Heimdall checks for this
Heimdall looks at your Supabase or Firebase setup and checks whether row-level security is enabled on your tables, and whether the policies that exist actually scope rows to the requesting user instead of allowing all access.
#How to fix it
In Supabase, enable RLS on every table from the dashboard or a migration, then add a policy like auth.uid() = user_id for row ownership. In Firebase, write security rules that check request.auth.uid against the document owner. Test with a second account to confirm you can't see the first account's data.
Frequently asked questions
Does RLS slow down my queries?
I use the service role key on the server. Do I still need RLS?
Is RLS on by default in a new Supabase project?
Run this check on your own repo
Heimdall scans your GitHub repo for this and 29 other issues in under a minute.
