Blog September 28, 2026 • 3 min read AI coding tools have transformed how quickly developers can ship software. Platforms like Lovable, Bolt, Cursor, and Replit let you go from concept to working application in hours instead of weeks. But speed comes with trade-offs. According to a recent TechCrunch report, security researchers found approximately 16,000 […]
Blog
September 28, 2026 • 3 min read
AI coding tools have transformed how quickly developers can ship software.
Platforms like Lovable, Bolt, Cursor, and Replit let you go from concept to working application in hours instead of weeks.
But speed comes with trade-offs.
According to a recent TechCrunch report, security researchers found approximately 16,000 Supabase databases with publicly readable tables exposed to the internet. Many of these came from AI-generated or rapidly built applications where Row Level Security was either misconfigured or skipped entirely.
This isn’t a Supabase problem. It’s a configuration problem.
When you’re focused on shipping fast, database permissions often get deprioritized until it’s too late.
Let’s walk through how to set up Supabase RLS correctly so your application doesn’t become another statistic.
What Is Row Level Security and Why It Matters
Row Level Security is Postgres’s built-in mechanism for controlling which rows users can access in your database.
Without RLS enabled, anyone with your project’s public anon key ,which ships in your frontend code can read or modify every row in your exposed tables, no login required.
With proper RLS policies, you define exactly who can see what based on user identity, role, or tenant ownership.
Think of it like apartment building access. Without RLS, anyone with a building key can enter any apartment. With RLS, each resident only has access to their own unit.
Step 1: Enable RLS on Every Table
Tables created through the dashboard have RLS enabled by default , but tables created via SQL, migrations, or AI coding tools (Lovable, Cursor, etc.) do not. That’s where most exposures happen.
In the Supabase dashboard:
- Navigate to Table Editor
- Select your table
- Click the RLS disabled badge
- Toggle Enable RLS
Alternatively, run this SQL in the SQL Editor:
ALTER TABLE your_table_name ENABLE ROW LEVEL SECURITY;
Do this for every table that contains user data, business logic, or anything you don’t want publicly exposed.
Step 2: Write Policies That Match Your Access Patterns
Enabling RLS without policies locks down the table completely. No one can read or write.
You need to define explicit policies for each operation: SELECT, INSERT, UPDATE, DELETE.
Here’s a basic example for a multi-tenant SaaS app where users should only see their own data:
CREATE POLICY “Users can view own records”
ON profiles
FOR SELECT
USING (auth.uid() = user_id);
This policy allows users to SELECT rows only where the user_id column matches their authenticated auth.uid().
For INSERT operations:
CREATE POLICY “Users can insert own records”
ON profiles
FOR INSERT
WITH CHECK (auth.uid() = user_id);
The WITH CHECK clause ensures users can only insert rows where they own the data.
Step 3: Test Policies with Real User Contexts
Policies that look correct in SQL can fail under real-world access patterns.
Always test with actual user tokens, not just the service role key.
Use Supabase’s RLS policy testing tool or create test accounts and attempt unauthorized access:
- Can User A see User B’s data?
- Can unauthenticated requests read anything?
- Can a user modify someone else’s row?
If any of these succeed when they shouldn’t, your policy has a gap.
Step 4: Secure Service Role and Anon Keys
Supabase provides two main API keys:
- Anon / publishable key: Designed for frontend use, but only safe when RLS is enabled on every exposed table.
- Service role key: Bypasses RLS entirely, should never be exposed
Never embed your service role key in client-side code or version control.
Use it only in backend environments where you need admin-level access for migrations, batch operations, or system tasks.
Store it in environment variables and restrict access tightly.
Step 5: Audit Policies Before Production
Even experienced developers miss edge cases.
Before launching:
- Review every table’s RLS status
- Confirm policies exist for all CRUD operations
- Test access paths for each user role or tenant
- Run a security audit to catch misconfigurations early
Tools like BuildYourAI’s CodeScan are built specifically to identify RLS gaps and policy weaknesses in AI-generated or rapidly built applications.
It scans your codebase and database schema to flag tables without RLS, weak policies, or dangerous query patterns.
Common RLS Mistakes to Avoid
Leaving RLS disabled “temporarily” – Temporary shortcuts become permanent in production.
Using overly broad policies – Policies like USING (true) defeat the purpose of RLS.
Forgetting anon access – If your app allows public reads, you need policies for unauthenticated users.
Skipping policy tests – Automate RLS tests so every schema change is checked.
Build Fast, But Ship Safely
AI tools let you prototype and ship faster than ever.
But production readiness isn’t just about features. It’s about access control, data security, and user trust.
Setting up Supabase Row Level Security correctly takes an extra hour upfront. Fixing a data breach costs infinitely more.
If you’ve built your app with AI coding tools or need an expert review of your Supabase configuration, BuildYourAI offers production audits tailored for vibe-coded and AI-generated applications.
Check what you’re shipping before your users do.