Cursor + Supabase + Vercel Security Blueprint

Share

To secure a Cursor + Supabase + Vercel stack, you need to: (1) enable Row Level Security on all Supabase tables and write policies for each operation, (2) store your Supabase URL and anon key as NEXT_PUBLIC_ environment variables in Vercel while keeping the service_role key server-side only, (3) add security headers (X-Frame-Options, CSP) in vercel.json, (4) create a .cursorignore file to prevent AI from accessing your .env files, and (5) review all AI-generated code for missing authentication checks. This blueprint covers all three tools with color-coded guidance showing which security tasks belong to each platform.

Setup Time2-3 hours

TL;DR

This is the most popular vibe coding stack. Key security priorities: enable Row Level Security (RLS) on all Supabase tables, store your Supabase keys in Vercel environment variables, add security headers in vercel.json, and review AI-generated code for authentication gaps. About 73% of security issues in this stack come from missing RLS policies or exposed API keys.

Platform Guides & Checklists

      Cursor Security Guide



      Supabase Security Guide



      Vercel Security Guide



      Pre-Launch Checklist

Stack Overview

The Cursor + Supabase + Vercel stack has become the default choice for vibe coders building full-stack applications. Here's how the pieces fit together:

ComponentRoleSecurity Responsibility
CursorAI code editorCode quality, secret detection in code
SupabaseDatabase + Auth + StorageRLS policies, auth config, API key protection
VercelHosting + DeploymentEnvironment variables, headers, edge functions

Part 1: Supabase Security Configuration

Enable Row Level Security Supabase

RLS is the most critical security feature in Supabase. Without it, anyone with your anon key can read and modify all data.

Enable RLS on every table
-- Enable RLS
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
ALTER TABLE comments ENABLE ROW LEVEL SECURITY;

-- Example policy: users can only read their own data
CREATE POLICY "Users can view own data"
  ON users FOR SELECT
  USING (auth.uid() = id);

-- Example policy: users can only update their own data
CREATE POLICY "Users can update own data"
  ON users FOR UPDATE
  USING (auth.uid() = id);

Common mistake: Creating tables without RLS enabled. Cursor might generate table creation SQL without RLS. Always add ENABLE ROW LEVEL SECURITY immediately after creating any table.

Protect Your Supabase Keys Supabase Vercel

Supabase provides two types of keys:

Key TypeWhere to UseExposure Risk
anon/public keyFrontend (browser)Safe if RLS is configured
service_role keyServer onlyNever expose (bypasses RLS)
Vercel environment variables
# Public (can be exposed to browser)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...

# Private (server-side only)
SUPABASE_SERVICE_ROLE_KEY=eyJ...

Configure Auth Settings Supabase

In the Supabase dashboard, configure these auth settings:

  • Site URL: Set to your production domain
  • Redirect URLs: Add only your app's domains
  • Email confirmations: Enable for production
  • Password requirements: Set minimum length (8+ characters)

Part 2: Vercel Security Configuration

Set Security Headers Vercel

Add security headers to protect against common attacks:

vercel.json
{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "Referrer-Policy",
          "value": "strict-origin-when-cross-origin"
        },
        {
          "key": "Permissions-Policy",
          "value": "camera=(), microphone=(), geolocation=()"
        }
      ]
    }
  ]
}

Configure Environment Variables Vercel

In Vercel's dashboard, add your environment variables:

  1. Go to Project Settings > Environment Variables
  2. Add variables for each environment (Production, Preview, Development)
  3. Prefix client-side variables with NEXT_PUBLIC_
  4. Keep service keys without the prefix (server-only)

Tip: Use different Supabase projects for development and production. This prevents accidental data exposure and makes it easier to test RLS policies.

Part 3: Cursor Security Practices

Configure .cursorignore Cursor

Prevent sensitive files from being sent to AI:

.cursorignore
# Environment files
.env
.env.local
.env.production

# Supabase local config
supabase/.env

# Any credentials
**/credentials.json
**/service-account.json

Review AI-Generated Code Cursor

When Cursor generates code that interacts with Supabase, check for:

  • Missing auth checks: Ensure protected routes verify the user session
  • Direct service_role usage: Use anon key on client, service_role only on server
  • Hardcoded keys: Replace any hardcoded values with environment variables
  • Missing error handling: Don't expose error details to users
Secure Supabase client setup
// Client-side (browser)
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)

// Server-side (API routes, server components)
import { createClient } from '@supabase/supabase-js'

const supabaseAdmin = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!
)

Security Checklist with Tool Attribution

Pre-Launch Checklist for Cursor + Supabase + Vercel

Common Vulnerabilities in This Stack

VulnerabilityCauseFix
Data exposed to all usersRLS not enabled or no policiesEnable RLS, create policies
API key in git historyCommitted .env fileRotate key, add to .gitignore
Unauthorized data modificationMissing UPDATE/DELETE policiesAdd policies for all operations
Service key exposedUsed service_role on clientMove to server-side only

Alternative Stack Configurations

Cursor + Firebase + Vercel Swap Supabase for Firebase. Different security model with Firestore rules instead of RLS.

      Cursor + Supabase + Netlify
      Same database, different host. Netlify uses _headers file instead of vercel.json.


      Bolt.new + Supabase + Vercel
      Swap Cursor for Bolt.new. Same Supabase/Vercel config, different AI code review approach.

Is the Supabase anon key safe to expose?

Yes, if RLS is properly configured. The anon key is designed for client-side use and only allows access that your RLS policies permit. Think of it as a "public API key" that still requires authentication for protected data.

Do I need different Supabase projects for dev and production?

It's strongly recommended. Using separate projects prevents accidental data leaks, lets you test RLS changes safely, and gives you isolated environments for development.

How do I test if my RLS policies work?

Use the Supabase SQL editor with "Run as authenticated user" to test policies. Also test your app while logged out and as different users to verify data isolation.

Using This Stack?

Scan your Cursor + Supabase + Vercel app for security issues.

Start Free Scan
Security Blueprints

Cursor + Supabase + Vercel Security Blueprint