It is late, and you are proud of yourself. You asked your AI builder to “add user accounts,” and it did. There is a sign-up page, a login page and a dashboard that greets each person by name. You invite a few early customers. One of them uploads their invoices. Another adds their client list.
Then a thought lands. You never told the app who is allowed to see what. You told it to add logins. Are those the same thing?
They are not. And it is a good question to be asking before anyone else asks it for you.
What’s actually going on
Most apps built with Lovable, Bolt and similar tools use a backend like Supabase. Supabase gives you a database, user accounts and file storage, and your app talks to it directly from the browser.
That last part is the key. Your app’s frontend, the code that runs in your customer’s browser, connects straight to your database. That is fast and convenient. It also means the database itself has to enforce the rules, because anything in the browser can be inspected and changed by a curious user.
Authentication versus authorization
Two words that sound alike do very different jobs.
- Authentication answers “who are you?” That is your login screen.
- Authorization answers “what are you allowed to see and do?” That is the part people skip.
Your login screen can be perfect while authorization is missing entirely. The dashboard might only show each person their own records, but if the database will hand over everyone’s records to anyone who asks the right way, the data is not private. The filtering is just cosmetic.
Row Level Security
In Supabase, authorization lives in Row Level Security, often shortened to RLS. When RLS is turned on for a table, the database checks a set of policies on every request. A typical policy says something like “a user can only read rows where the owner column matches their user ID.”
If RLS is off, or on with no sensible policies, the table can be readable, and sometimes writable, by anyone with your project’s public key. Supabase warns about this in its dashboard, but those warnings are easy to miss when a builder created the tables for you.
A login screen is the front door. Row Level Security is the lock on every room inside.
The two keys
Supabase gives you two important keys, and mixing them up is one of the most common mistakes in AI-built apps.
- The anon key is designed to be public. It goes in your frontend. It is safe only because RLS limits what it can do.
- The service_role key skips RLS entirely. It can read and change everything. It belongs only in server-side code, like edge functions or a backend, kept in environment variables.
If the service_role key shows up anywhere in your frontend code, or in a public code repository, treat it as exposed. Rotate it and move it.
File storage counts too
Uploaded files, like profile photos, invoices or documents, live in storage buckets. Buckets have their own access rules. A bucket marked public means anyone with the file’s URL can open it. For anything personal, you want a private bucket with policies that match your tables.
Password resets and emails
The last piece is the one customers notice first. Sign-up confirmations and password reset emails need to arrive, and the links in them need to point to your real site. Default email senders are often limited and can land in spam. Reset links that point to a preview URL or localhost are a common leftover from building.
What to do right now
You do not need to be a developer to run these checks.
- Open your Supabase project and look at each table. Confirm Row Level Security is turned on for every table that holds customer data. Pay attention to any security warnings in the dashboard.
- Read the policies in plain English. For each table, ask: who can read, who can add, who can change, who can delete? If you cannot tell, ask your AI builder to explain each policy in one sentence.
- Search your code for “service_role.” If it appears in anything that runs in the browser, rotate the key in Supabase and ask your builder to move that logic to a server-side function.
- Test as a second user. Create two accounts. Add data as the first. Sign in as the second in a private window and try to find the first account’s data, including by changing IDs in the address bar if your app uses them. Try editing and deleting, not just viewing.
- Check your storage buckets. Make sure anything personal is in a private bucket with policies.
- Send yourself a password reset. Confirm it arrives, does not land in spam and links to your live domain.
- Turn on two-factor authentication for your own Supabase, builder and hosting accounts. Your admin login is the master key to all of it.
When to hand it off
If the second-user test passes and your policies read sensibly, you are in better shape than many apps that launch. If you find gaps, or you are not sure what you are looking at, this is a good moment to get help. Getting policies right for teams, shared records or admin roles takes care, and the cost of a mistake is your customers’ trust.
On a care plan, we review your tables, policies and storage rules, move any exposed keys to the right place, test access as multiple users, and set up a custom email sender on your domain so confirmation and reset emails actually arrive. We work inside your existing Supabase project and builder, so nothing gets rebuilt. You can read more on our logins and accounts and security and backups pages, and if you built with Lovable, the Lovable sites page covers the common patterns we see.
For apps that handle real customer data, the Growth or Scale plan gives you enough monthly hours to fix issues and keep checking as you add features. See the pricing page for what each includes.
If you want a second set of eyes before more customers sign up, send us your URL for a free site check and we will report back within 48 hours.