At Inithouse, we run Audit Vibe Coding: a professional audit service for AI-generated web apps. We review vibecoded projects across security, performance, accessibility, and code quality before they go to production.
After auditing dozens of Supabase-backed projects, we started noticing the same patterns. The same five mistakes appear in nearly every vibecoded Supabase app that comes through our pipeline. Here they are, along with what we recommend.
1. No Row Level Security policies
This is the most common and most dangerous one. AI code generators create tables and wire up queries, but they almost never enable Row Level Security. The result: any authenticated user can read or modify any row in any table by calling the Supabase client directly from the browser console.
What we see: RLS disabled on 80%+ of tables. No policies written at all.
The fix: Enable RLS on every table immediately after creation. Write explicit policies for SELECT, INSERT, UPDATE, and DELETE. Test them by querying as a different user. A good starting policy for user-owned data:
CREATE POLICY "Users can only access own data"
ON your_table
FOR ALL
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
2. Secrets stored in client-side code
Vibecoded apps frequently hardcode API keys, webhook URLs, and third-party service credentials directly in React components or utility files. These end up in the browser bundle, visible to anyone who opens DevTools.
What we see: OpenAI keys, Stripe secret keys, and internal service URLs sitting in .tsx files.
The fix: Move all secrets to Supabase Edge Functions or a backend proxy. Store them as environment variables in the Supabase dashboard under Settings > Edge Functions. Client-side code should only call your Edge Function endpoint, never the third-party API directly.
3. No database indexes on hot columns
AI generators rarely think about query performance. They create tables, write queries, and move on. As usage grows, queries slow down because there are no indexes on the columns that get filtered or sorted most often.
What we see: Full table scans on columns like user_id, created_at, and status that appear in every WHERE clause.
The fix: Identify your most frequent queries (Supabase Dashboard > SQL Editor > Query Performance) and add indexes proactively:
CREATE INDEX idx_your_table_user_id ON your_table (user_id);
CREATE INDEX idx_your_table_created_at ON your_table (created_at DESC);
We track this across our own portfolio too. Products like Magical Song, our custom AI song generator, went through the same index audit early on.
4. Using the service_role key in the frontend
The service_role key bypasses all RLS policies. It exists for server-side admin operations. When a vibecoding tool reaches for the easiest way to fix a "permission denied" error, it often swaps the anon key for the service_role key in the client config. That single change gives every visitor full admin access to the database.
What we see: service_role key in supabaseClient.ts, committed to the repo, shipped to production.
The fix: The frontend must always use the anon key. If a query fails with RLS enabled, the answer is to write a proper RLS policy or move the operation to an Edge Function that uses service_role server-side. Never expose service_role to the browser.
5. No backup or recovery strategy
Most vibecoded projects never configure backups. Supabase provides daily automatic backups on the Pro plan, but free-tier projects get nothing. We see teams running production workloads on the free tier with no backup plan at all.
What we see: Production data on Free tier with no exports, no Point-in-Time Recovery, no tested restore process.
The fix: If you are on a paid plan, enable Point-in-Time Recovery (PITR) in the Supabase dashboard. If you are on Free tier, set up a scheduled pg_dump export via a cron job or Edge Function. Either way, test your restore process at least once. A backup you have never restored is not a backup.
Why these keep showing up
AI code generators optimize for "make it work." Security, performance, and operational resilience come second because the model has no context about production constraints. That gap is exactly what we built Audit Vibe Coding to fill: a 47-point checklist across security, SEO, performance, accessibility, and code quality, with a scored report delivered in 24 hours.
If you are shipping vibecoded apps to production, we recommend running through these five checks first. Or let our team at Inithouse, a studio shipping a growing portfolio of AI products in parallel, handle the full audit.
Top comments (0)