← All posts
supabaseservice role keyvibe codingnext.jssecurity

Supabase Service Role Key Fix Vibe Code: Step-by-Step for Next.js

O

OverMCP Team

Quick answer

A leaked Supabase service role key in a vibe-coded Next.js app gives attackers full admin access to your database. Immediately rotate the key in Supabase dashboard, revoke any exposed keys from your codebase and version history, and enforce environment variable usage. Use a secret scanner to catch leaks before they cause damage.

What to check first

Before you panic, run through this checklist to assess the damage and secure your app:

  • [ ] Check Supabase dashboard for any suspicious activity (unusual queries, new users, deleted tables).
  • [ ] Search your entire codebase for the service role key (look for service_role, anon keys, or supabaseKey in plaintext).
  • [ ] Scan your GitHub repos (including private ones) for the leaked key using a secret leak scanner.
  • [ ] Check environment variables in your deployment platform (Vercel, Netlify, etc.) to ensure the key is stored securely.
  • [ ] Review commit history – the key may be in old commits even if removed now.
  • [ ] Verify your Supabase Row Level Security (RLS) policies – if they're missing, a leaked key is catastrophic.
  • [ ] Check client-side code – the service role key should NEVER appear in frontend JavaScript.
  • Step-by-step fix

    Follow these steps to fix a leaked Supabase service role key in your vibe-coded Next.js app.

    Step 1: Rotate the service role key immediately

    Go to your Supabase project dashboard → Settings → API → Service Role Key. Click "Reveal" and then "Rotate". This invalidates the old key.

    ⚠️ After rotation, any service using the old key will break. Update your environment variables immediately.

    Step 2: Update environment variables

    In your Next.js app, ensure the service role key is stored in .env.local (for local dev) and in your deployment platform's environment variables.

    # .env.local (never commit this file)
    NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
    SUPABASE_SERVICE_ROLE_KEY=your-new-rotated-key
    NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

    Important: The NEXT_PUBLIC_ prefix exposes the variable to the browser. Never prefix the service role key with NEXT_PUBLIC_. Only the anon key should be public.

    Step 3: Update your server-side code

    In API routes or server actions, use the service role key from the environment variable:

    // app/api/admin/route.ts
    import { createClient } from '@supabase/supabase-js'
    
    export async function POST(req: Request) {
      // ❌ Wrong: hardcoded key
      // const supabase = createClient(url, 'service_role_key_here')
    
      // ✅ Correct: use environment variable
      const supabase = createClient(
        process.env.NEXT_PUBLIC_SUPABASE_URL!,
        process.env.SUPABASE_SERVICE_ROLE_KEY!
      )
    
      // ... your admin logic
    }

    Step 4: Remove the key from version history

    If the key was committed, remove it from Git history:

    # Rewrite history to remove the file containing the key
    git filter-branch --force --index-filter \
      "git rm --cached --ignore-unmatch .env.local" \
      --prune-empty --tag-name-filter cat -- --all
    
    # Force push to GitHub
    git push origin --force --all
    git push origin --force --tags
    🔒 After force pushing, notify your team to re-clone the repository.

    Step 5: Enforce RLS policies

    A leaked service role key bypasses RLS. Without RLS, an attacker can read/write all data. Check your Supabase SQL editor:

    -- Check if RLS is enabled on all tables
    SELECT tablename, rowsecurity
    FROM pg_tables
    WHERE schemaname = 'public';
    
    -- Enable RLS on a table
    ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;
    -- Then create policies for select, insert, update, delete
    CREATE POLICY "Users can view own data" ON your_table
      FOR SELECT USING (auth.uid() = user_id);

    Step 6: Monitor for future leaks

    Set up continuous security monitoring to automatically scan your repo and deployments for secrets.

    Common mistakes

    Vibe-coded apps often make these mistakes with Supabase keys:

    1. Using the service role key in client-side code

    AI tools sometimes generate code that exposes the service role key in the browser. The service role key should only be used in server-side code (API routes, server actions, server components). The anon key is safe for public use because RLS protects the data.

    2. Committing `.env.local` or hardcoded keys

    Cursor, Bolt.new, or Lovable might generate a .env.local file and forget to add it to .gitignore. Always check that .env.local is in .gitignore before committing.

    3. Assuming RLS is enough

    RLS policies are often missing in vibe-coded apps. Even with RLS, the service role key bypasses all policies – it's designed for admin tasks. Never expose it to the client.

    4. Not rotating after a leak

    Some developers just delete the key from the codebase without rotating it. The old key remains valid and can still be exploited.

    5. Forgetting to scan old commits

    A key removed in the latest commit may still exist in Git history. Use a secret leak scanner to find it.

    Preventing future leaks

  • Use a pre-commit hook to scan for secrets before every commit (e.g., git-secrets or talisman).
  • Add a `.env.example` file with placeholder values (never real keys).
  • Run a [free AI app security scanner](https://www.overmcp.com/) regularly to catch leaks early.
  • Educate your team about the difference between public anon key and secret service role key.
  • FAQ

    What is the Supabase service role key used for?

    The service role key is a secret key that bypasses Row Level Security (RLS) and has full admin access to your Supabase database. It should only be used in trusted server-side environments.

    Can I use the anon key instead of the service role key?

    Yes, for client-side operations. The anon key is safe for public use because RLS policies control what data users can access. The service role key is only needed for admin tasks like creating users, running migrations, or performing server-side operations that require elevated privileges.

    How do I know if my service role key was leaked?

    You may notice unusual database activity, new users created without authorization, or data being deleted. Use a secret leak scanner to check GitHub and your codebase. Also check Supabase audit logs for unexpected API calls.

    Is your app secure?

    Free scan in 30 seconds. No signup needed.

    Scan My App Free