How to Secure an App Built with Lovable
Connect Lovable to GitHub, scan the code and deployed app, then fix Supabase access, service-role key, and storage risks.
SafeWeave
Lovable can sync a project to a GitHub repository, which gives you a way to check the code as you build. You can also scan the deployed app’s URL. For Lovable projects that use Supabase, pay particular attention to Row Level Security (RLS), privileged keys, Edge Functions, and storage settings.
What goes wrong
Supabase uses RLS to control which rows a caller can read or change through the public API. If RLS is disabled on a table, the anon and authenticated roles can read and write every row through that API. Turning RLS on is not enough if a policy still allows every row through. A policy using USING (true) or WITH CHECK (true) can effectively disable RLS for the operation it covers.
Privileged Supabase operations also need careful handling. The service_role key bypasses RLS, so it must stay in server code. A key in a public environment variable such as NEXT_PUBLIC_ or VITE_ can be included in the browser bundle. The same concern applies when browser code calls supabase.auth.admin: admin auth calls need the service-role key.
An Edge Function that uses the service-role key must check who is calling before it performs privileged work. Without that check, anyone who knows the function URL could get database access through the function. Other risks may only show up when checking the running app: tables readable by anyone, a visible Anthropic API key, or public storage buckets.
How to check
Start by connecting Lovable to GitHub. In Lovable, open Project settings → Git. On the GitHub card, click Connect. Lovable creates a repository and keeps it in sync with the project.
Then connect that repository in SafeWeave. If you have not connected GitHub, use the GitHub connection instructions. Go to Repositories, click Connect repository, and choose the repository Lovable created. Click Scan now to start a scan. Each later sync is a push, and every push is scanned.
For a live app check, open App URLs, click Scan an app URL, and enter the address where your app is deployed. See the App URLs guide. Code checks and live app checks look for different things, so check the results from both. Code checks look for issues in the repository. Live app checks look at the deployed app.
For Lovable projects using Supabase, the code checks look for tables without RLS and keys exposed to the browser. On Cloud and Cloud Plus, you can also connect Supabase to check the database itself. Live checks for readable tables, exposed Anthropic keys, and public storage buckets are available on Cloud and Cloud Plus. Cloud has a 14-day trial.
The free scan at safeweave.dev/scan does not require signup. A free account connects one repository and shows its grade and finding counts. Cloud is $29/mo and includes 5 repos, 15 scans per repo a month, hosted scans on every push, and PR checks. Choose the check that matches what you need to inspect; do not assume a repository scan covers the live app.
Check your own code for issues like these
A free SafeWeave account runs 7 scanners locally, inside your AI editor. Cloud adds hosted scans and PR checks, with a 14-day trial.
Create a free accountHow to fix it
For a table with RLS disabled, re-enable it and add explicit policies that scope access to the current user. For example:
ALTER TABLE <table> ENABLE ROW LEVEL SECURITY;
A policy can use a condition such as USING (auth.uid() = user_id) to restrict access to rows belonging to the caller. Do not leave a user-data table with RLS off. See the RLS disabled check.
Review policies as well as the table setting. Replace an always-true condition with a predicate that checks the caller’s access. For example, use USING (auth.uid() = user_id) for SELECT, UPDATE, or DELETE, and WITH CHECK (auth.uid() = user_id) for INSERT or UPDATE. A blanket USING (true) is only appropriate for a genuinely public lookup table. See the RLS passthrough policy check.
For an Edge Function that uses the service-role key, check the caller before doing privileged work. Create a client with the caller’s Authorization header and call auth.getUser(). Return 401 or 403 if there is no user or the user lacks the required role from app_metadata. Only then use the service-role client. See the Edge Function authentication check.
Move any supabase.auth.admin call out of browser code and into a server route or Edge Function. Check that the caller is an admin there. Read the service-role key from a server-only environment variable, and have the client call the server code with fetch. See the auth.admin in client code check.
Do not put a service-role key in a NEXT_PUBLIC_ or VITE_ environment variable. Rename it to a server-only variable, such as SUPABASE_SERVICE_ROLE_KEY, and read it only from server code, such as a Route Handler, Server Action, or API route. The browser should use the anon key with RLS. See the public service-role environment variable check.
For a table that is readable by anyone in the live app, turn on RLS in Supabase and add policies that let people read only their own rows. See the readable table check.
If an Anthropic API key is visible in website code, rotate it. Remove it from front-end code and public environment variables, then use it only from a server or Edge Function. See the Anthropic key check.
Make storage buckets private unless every file in a bucket is meant to be public. Serve private files with signed links. See the public storage bucket check.
A practical review sequence
After making a change, check the repository scan results and address the findings they report. Then scan the deployed app URL for live app findings. If the app uses Supabase and you have Cloud or Cloud Plus, connect Supabase to check the database itself as well. SafeWeave separates these checks because code, the running app, and the database each need to be reviewed in their own context.
Check your app now
- Free scan, no signup: scan your app and see what is exposed.
- Create a free account: sign up and connect 1 repository to see its grade and finding counts.
- Cloud: hosted scans on every push and PR checks, 5 repos and 15 scans per repo a month for $29/mo, with a 14-day trial. See pricing.
Check your app in three steps
- Step 1
Free scan, no signup
See what your app exposes right now.
Scan your app - Step 2
Create a free account
Connect 1 repository and see its grade and finding counts.
Sign up free - Step 3
Cloud
Hosted scans on every push and PR checks: 5 repos, 15 scans per repo a month, $29/mo with a 14-day trial.
See pricing