Turning Row Level Security on is one click. Writing a policy that actually protects your data is the part most people skip, and it's the part that matters.
An overlay appears directly on top of Supabase and Lovable. No tab switching, no re-reading docs.
Copy your Project URL
Find the Project URL field below and click the copy icon. We will use this in Lovable’s environment settings.
Stylized preview. The real guide is interactive, not a screenshot.
Authentication controls who can access your app and what they're allowed to do once inside. Open the Authentication section and look at Providers. Email is turned on by default, so people can already sign up with a password before you touch anything else.
Open the Users tab under Authentication. Every account that signs up through your app lands here. It will be empty on a fresh project, but this is the exact screen you'll come back to later to confirm signups are actually working.
A table with RLS off is fully readable and writable by anyone holding a valid API key, logged in or not. It's easy to assume authentication alone locks things down. It doesn't. RLS is the separate switch that actually restricts row access.
Go back to your table and enable Row Level Security from the table's settings. This one toggle blocks all row access by default the moment it's on, which is exactly why the next step isn't optional.
Turning RLS on isn't enough by itself, you also need a policy that says who's allowed to see what. Supabase's policy wizard walks you through this without requiring you to write the underlying SQL yourself. A common first policy: let signed in users read their own rows.
Your table effectively goes dark: even you, querying from your own app, will get empty results back until a policy exists. If a table suddenly looks empty right after enabling RLS, this is almost always why.
Authentication answers who someone is. Row Level Security answers what that specific person is allowed to touch once they're in. Supabase keeps these separate on purpose: your app's login flow doesn't have to know anything about data permissions, and your data permissions don't have to trust the login flow to police itself. Once a table holds anything user specific, a saved record, a message, a profile field, RLS is what stops one signed in user from reading another user's row through the same API.
The RLS toggle gets most of the attention because it's the visible switch, but the policy wizard is where the actual protection gets defined. Writing row security policies by hand means writing SQL expressions that reference the current authenticated user, which is exactly the kind of thing that's easy to get subtly wrong. The wizard offers common patterns, like letting users read only their own rows, as a starting template instead of a blank SQL box.
Want to build this for real instead of just reading about it?
No. Every new table starts with RLS off, which means it's fully readable and writable through the API until you turn it on. This applies even if your app has authentication working correctly, since auth and row level access are handled separately.
The table becomes inaccessible by default, including to your own app's queries. RLS blocks all row access until at least one policy explicitly allows it, so an empty result right after enabling RLS almost always means the policy step got skipped.
Not necessarily. Supabase's policy wizard covers common patterns, like restricting rows to their owner, through a guided form rather than a blank SQL editor. You can still write custom SQL policies for more specific rules, but it isn't required to get started.
Any table that stores information tied to a specific user, saved records, messages, profile data, uploaded file references. A table with no user specific data, like a public list of categories, is lower risk, but enabling RLS on every table is still the safer default.
The performance impact is small for typical app scale table sizes and policy complexity. The bigger practical cost is usually forgetting to add it, not the overhead of having it on.
Don't wait until the table is in active use. Enable it as part of creating the table, not as a follow up task, so there's never a window where the data sits unprotected.
The wizard's common patterns, like letting users read their own rows, cover most first policies. Reach for custom SQL only once you need a rule the wizard doesn't offer.
The Supabase dashboard often queries with elevated access. Confirm your policy behaves correctly from your actual app's logged in session, not only from the table editor.
If a table looks unexpectedly empty right after enabling RLS, check for a missing or misconfigured policy before assuming the data itself is gone.
You're not the problem. The format is. Here's what changes when you switch to an interactive mission.
Looking for the next thing to build? Browse every mission and find one that matches what you are trying to ship.
Browse all missions