Milo Kits
Guide

Lovable security checklist before launch: 12 checks with fix prompts

Before you launch a Lovable app, run Lovable's Quick and Deep security scans, then check the live app from the outside. The checks that matter most: Row Level Security on every table, private storage buckets for private files, no secret keys in VITE_ variables, Edge Functions that check who is calling, and pages and API calls that refuse a logged-out visitor or a second user. Each check below takes a few minutes and comes with a prompt you can paste into Lovable.

Before you start

You need your live URL, two test accounts you create yourself (call them A and B), and a private browser window. Only test apps you own. Everything here is read-only apart from signing in as your own test users.

1. Run the Quick scan and fix critical findings

Lovable runs a Quick scan when you publish. It checks your database access rules, npm dependencies and exposed MCP servers (Lovable security docs). Open the Security view and clear anything marked critical before launch.

2. Run the Deep scan once before launch

The Deep scan doesn't run automatically. Start it from the Security view before a real launch and again after big changes to sign-in, data or payments. It also reviews your application code, which is where problems like one user reaching another user's data tend to show up.

3. Turn on RLS on every table

In Supabase, open Table Editor and look for tables marked RLS disabled, or open the Security Advisor and look for "RLS Disabled in Public". Any table without RLS can be read, and often changed, by anyone with the public key that's already in your page.

Fix prompt
List every table in the public schema with its RLS status and policies. Enable RLS on any table where it's off. For tables with user data, add policies so each user can only select, insert, update and delete their own rows (auth.uid() = user_id). Flag any policy that uses (true) on private data. Show me the SQL before running it.

4. Check for "using (true)" policies

RLS that's on but has a policy like using (true) lets everyone through. It's a common AI shortcut when a query "returns nothing". The Security Advisor flags many of these as permissive policies.

5. Make private storage buckets private

Storage has its own rules. A bucket marked public serves every file to anyone with the link (Supabase storage docs). That's fine for logos, but not for invoices, IDs or user uploads.

Fix prompt
List my storage buckets and say which are public. Make any bucket that holds private user files private, add storage.objects policies so each user can only read and write their own folder, and serve those files with short-lived signed URLs. Show me the diff.

6. Keep secrets out of VITE_ variables

Lovable's docs say values in VITE_ variables are built into the browser bundle. That's fine for the Supabase URL and publishable key, and never fine for an OpenAI, Stripe secret or service_role key. Search your live JavaScript (DevTools → Sources, or view the bundle) for sk-, sk_live and service_role.

Fix prompt
Find every secret key used in the frontend or in a VITE_ variable. Move each one into Lovable secrets and use it only from an Edge Function, so the browser calls the function instead of the third-party API. Keep only the Supabase URL and publishable key in the frontend. Tell me which keys I must rotate.

7. Make Edge Functions check who is calling

An Edge Function that calls a paid API, or reads private data, should check the signed-in user, not just that a request arrived with your public key. The public key is in your page, so anyone has it.

Fix prompt
For every Edge Function, check whether it requires a signed-in user. Functions that call paid APIs or return private data must get the user from the Authorization header (auth.getUser), reject requests without a valid user, and check that the user owns the data they ask for. Add a per-user daily limit to functions that call paid APIs. Show me the diff.

8. Open private pages logged out

In a private window, paste the URLs of your dashboard, admin page and any page that shows user data. A login screen or an error is good. Seeing the page or its data means the login only hides the button.

9. Test with a second account

As user A, create something. Note its URL or ID. Sign in as user B in another browser and open A's URL, or change the ID in the address bar. B should see nothing. Our two-account RLS guide walks through this step by step, including the network tab.

10. Check who can make themselves an admin

If roles live in a profiles table that users can update, a user may be able to set role = 'admin' on their own row. Roles should be changeable only by a server-side function or by you.

Fix prompt
Check where user roles are stored and whether a normal user can change their own role through the API. Move roles to a table users can't update (or restrict the update policy so the role column can't change), and check admin access on the server with a security definer function that uses auth.uid(). Show me the SQL.

11. Unlock paid features from a verified webhook

If you take payments, paid access should switch on when your payment provider's signed webhook arrives, not when someone opens your "success" page. Otherwise anyone who finds that URL gets the paid plan free.

12. Check HTTPS and security headers on the live URL

Check that the live site redirects to HTTPS and sends headers such as HSTS, a Content-Security-Policy and clickjacking protection. Our free 10-second header check does this for your homepage, or see the headers guide if you host outside Lovable.

After launch

Re-run checks 3 to 9 after every big AI change. New tables, buckets and functions don't inherit the rules you set on launch day.

FAQ

Is Lovable secure enough to launch a real app?

Lovable gives you good building blocks: a Postgres database with Row Level Security, secrets storage, Edge Functions and built-in security scans. Whether your app is secure depends on how those were set up for your data. Run both scans, fix what they find, and test the live app as a logged-out visitor and as a second user before you take real users or payments.

Do Lovable's security scans replace a security review?

No, and Lovable's own security docs say its tools don't replace a thorough security review. The scans read your project from the inside. Checking the published app from the outside, and testing with two accounts, covers what actually shipped.

Is the Supabase key in my Lovable app's JavaScript a problem?

The publishable or anon key is designed to be public, as long as every table has RLS with the right policies. A service_role or sb_secret_ key in the browser is a real leak: remove it, move the code into an Edge Function and rotate the key.

Where should I put API keys in Lovable?

In Lovable's secrets storage, used from Edge Functions. Anything in a VITE_ variable is built into the browser bundle and anyone can read it.

Can I run these checks on someone else's Lovable app?

Only on apps you own or have permission to test. Every check here is read-only on your own app: opening pages, reading what the browser downloaded, and logging in with test accounts you created.

Sources

This guide is general information, not a security audit. Only test apps you own or have permission to test. Platforms change, so check the linked docs for current details. Spotted something out of date? Email hello@milokits.com.