Vercel + Supabase Security
Vercel and Supabase are a popular Next.js stack. Learn how to scope environment variables correctly, protect preview deployments, and ensure RLS guards your data.
Why Vercel + Supabase?
Vercel's native Supabase integration automatically injects environment variables into deployments, making this the default stack for Next.js developers who need a database. The convenience also creates consistent misconfiguration patterns.
Common Vulnerabilities
These are the security issues we find most often in Vercel apps using Supabase.
NEXT_PUBLIC_ Prefix Exposes Service Key
The service_role key accidentally prefixed with NEXT_PUBLIC_ is bundled into client JavaScript and visible to every user.
Preview Deployments Share Production Credentials
By default, Vercel preview deployments use the same environment variable set as production, giving pull request previews access to live Supabase data.
Missing RLS on Supabase Tables
Vercel makes deployment frictionless, which means apps reach production faster — before RLS has been configured on all tables.
Edge Functions Bypass Row-Level Auth
Vercel Edge Functions that use the service_role key to initialise Supabase skip RLS entirely, making every query fully privileged even when the caller is anonymous.
What We Check for Vercel + Supabase
Environment Variable Scoping
Verify service_role key is never prefixed with NEXT_PUBLIC_ and is absent from any client-side bundle.
Preview Deployment Isolation
Confirm preview deployments use a separate Supabase project or at minimum a read-only role, not production credentials.
RLS Coverage
Test all tables using the anon key to verify RLS blocks unauthorised access across both production and preview environments.
Edge vs Serverless Auth Context
Audit Vercel Edge Functions for service_role key usage and verify they pass the user JWT to Supabase when possible.
Quick Security Wins
Apply these fixes right now to improve your security.
In Vercel dashboard, set SUPABASE_SERVICE_ROLE_KEY with no NEXT_PUBLIC_ prefix and mark it as server-onlyCreate a separate Supabase project for preview deployments and add it to Vercel's Preview environment variable scopeEnable RLS on all tables: ALTER TABLE tablename ENABLE ROW LEVEL SECURITY;Use createServerClient from @supabase/ssr in API routes and Server Components, createBrowserClient in client componentsAdd a vercel.json headers block for Content-Security-Policy and X-Frame-OptionsThe Bottom Line
Vercel + Supabase is a secure stack when environment variables are correctly scoped. The biggest risk is the service_role key reaching the client — check this before every deployment.
Secure Your Vercel + Supabase App
Find Row Level Security misconfigurations, exposed credentials, and other vulnerabilities before attackers do.
Start Security ScanFrequently Asked Questions
How does Vercel's Supabase integration affect environment variable security?
Vercel's one-click Supabase integration injects NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, and SUPABASE_SERVICE_ROLE_KEY automatically. The first two are correctly public; the third is server-only. Verify none of your code accidentally uses the service_role key in a client context.
Should preview deployments use a different Supabase project?
Yes. Preview deployments from pull requests often include unreviewed code changes. Giving them production Supabase credentials means a bad PR can corrupt or expose live user data. Create a dedicated development Supabase project and point Vercel preview environments at it.
What is the correct Supabase client for Vercel Edge Functions?
Use createClient from @supabase/supabase-js with the anon key and pass the user's Authorization header as the auth token. This allows RLS to identify the user. Only use service_role in Edge Functions when you explicitly need to bypass RLS, and document why.
How do I add security headers to my Vercel + Supabase app?
Add a headers() configuration to next.config.js or a vercel.json headers block. Essential headers: Content-Security-Policy, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, and Strict-Transport-Security. Vercel does not add these by default.