To secure a Cursor + Supabase + Netlify stack, you need to: (1) enable Row Level Security on all Supabase tables and create policies for each operation, (2) configure security headers in _headers file or netlify.toml, (3) store your Supabase service_role key in Netlify environment variables and use it only in Netlify Functions, (4) create a .cursorignore file to prevent AI from accessing your .env files, and (5) configure auth redirect URLs to include your Netlify domain. This blueprint covers Netlify-specific configuration while maintaining the same Supabase security fundamentals.
TL;DR
Deploying your Cursor + Supabase app on Netlify? Key differences from Vercel: use netlify.toml or _headers for security headers, Netlify Functions for server-side code, and configure environment variables in the Netlify dashboard. Same Supabase security rules apply: enable RLS, protect the service_role key, and configure auth redirect URLs for your Netlify domain.
Platform Guides & Checklists
Cursor Security Guide
Supabase Security Guide
Netlify Security Guide
Pre-Launch Checklist
Stack Overview
This stack combines Cursor for AI-assisted development, Supabase for backend services, and Netlify for hosting. Netlify offers different configuration patterns compared to Vercel:
| Feature | Netlify | Vercel Equivalent |
|---|---|---|
| Config file | netlify.toml | vercel.json |
| Headers file | _headers | vercel.json headers |
| Server functions | Netlify Functions | API Routes / Edge Functions |
| Build command | netlify.toml build | package.json or vercel.json |
Part 1: Netlify Security Headers Netlify
Using _headers File Netlify
Create a _headers file in your publish directory (usually public/ or dist/):
/*
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
X-XSS-Protection: 1; mode=block
# API routes might need different CORS settings
/api/*
Access-Control-Allow-Origin: https://yourdomain.com
Using netlify.toml Netlify
Alternatively, configure headers in netlify.toml:
[build]
command = "npm run build"
publish = "dist"
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"
Permissions-Policy = "camera=(), microphone=(), geolocation=()"
Part 2: Environment Variables Netlify Supabase
Setting Variables in Netlify Netlify
In the Netlify dashboard:
- Go to Site settings > Environment variables
- Add your Supabase credentials
- Choose which contexts they apply to (Production, Deploy Previews, etc.)
# Public (for client-side frameworks, prefix varies)
# React: REACT_APP_
# Vite: VITE_
VITE_SUPABASE_URL=https://xxx.supabase.co
VITE_SUPABASE_ANON_KEY=eyJ...
# Private (Netlify Functions only)
SUPABASE_SERVICE_ROLE_KEY=eyJ...
Framework prefix: Different frameworks use different prefixes for client-exposed variables. React uses REACT_APP_, Vite uses VITE_, and Next.js uses NEXT_PUBLIC_. Make sure you're using the right prefix.
Part 3: Netlify Functions Netlify
Using Service Role Key Safely Netlify Supabase
Use Netlify Functions to run server-side code that needs the service_role key:
import { createClient } from '@supabase/supabase-js';
import type { Handler } from '@netlify/functions';
const supabaseAdmin = createClient(
process.env.VITE_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
);
export const handler: Handler = async (event) => {
// Verify authentication
const authHeader = event.headers.authorization;
if (!authHeader) {
return { statusCode: 401, body: 'Unauthorized' };
}
// Verify the user's JWT
const { data: { user }, error } = await supabaseAdmin.auth.getUser(
authHeader.replace('Bearer ', '')
);
if (error || !user) {
return { statusCode: 401, body: 'Invalid token' };
}
// Now safe to use admin operations
return {
statusCode: 200,
body: JSON.stringify({ success: true })
};
};
Security Checklist
Pre-Launch Checklist for Cursor + Supabase + Netlify
Security headers configured in _headers or netlify.toml
Environment variables set in Netlify dashboard
Service role key only used in Netlify Functions
RLS enabled on all Supabase tables
Auth redirect URLs include Netlify domain
.cursorignore excludes .env files
Deploy previews use separate Supabase project (recommended)
HTTPS enforced (automatic on Netlify)
Alternative Stack Configurations
Cursor + Supabase + Vercel Same database, different host. Vercel uses vercel.json instead of netlify.toml for configuration.
Cursor + Firebase + Vercel
Swap Supabase for Firebase. Different security model with Firestore rules instead of RLS.
Bolt.new + Supabase + Netlify
Swap Cursor for Bolt.new. Same Supabase/Netlify config, different AI code review approach.
Should I use _headers or netlify.toml for security headers?
Either works. The _headers file is simpler for header-only configuration, while netlify.toml is better if you're also configuring redirects, build settings, and other Netlify features in one place.
Can deploy previews access my production Supabase?
By default, deploy previews use the same environment variables as production. For security, consider using different Supabase projects for production vs previews, or restrict what deploy previews can access.
How do Netlify Functions compare to Vercel API routes?
They serve the same purpose (server-side code) but have different file locations and syntax. Netlify Functions go in netlify/functions/, while Vercel API routes go in pages/api/ or app/api/.