[{"data":1,"prerenderedAt":440},["ShallowReactive",2],{"blog-blueprints/bolt-supabase-vercel":3},{"id":4,"title":5,"body":6,"category":412,"date":413,"dateModified":414,"description":415,"draft":416,"extension":417,"faq":418,"featured":416,"headerVariant":424,"image":425,"keywords":425,"meta":426,"navigation":427,"ogDescription":428,"ogTitle":425,"path":429,"readTime":430,"schemaOrg":431,"schemaType":432,"seo":433,"sitemap":434,"stem":435,"tags":436,"twitterCard":438,"__hash__":439},"blog/blog/blueprints/bolt-supabase-vercel.md","Bolt.new + Supabase + Vercel Security Blueprint",{"type":7,"value":8,"toc":385},"minimark",[9,20,24,33,38,41,44,72,76,79,84,87,102,106,109,118,127,131,134,138,194,198,201,226,235,239,246,254,258,261,266,269,272,275,278,281,284,287,300,304,308,311,315,322,326,333,337,341,344,348,351,355,358,366],[10,11,12],"blueprint-summary",{},[13,14,15,19],"p",{},[16,17,18],"strong",{},"To secure a Bolt.new + Supabase + Vercel stack,"," you need to: (1) enable Row Level Security on every Supabase table with proper policies for each operation, (2) move API keys to Vercel environment variables and ensure service_role key never reaches client code, (3) add security headers via vercel.json, and (4) verify RLS is working before deploying. This blueprint covers the complete security configuration for the most popular Bolt.new deployment stack.",[21,22],"blueprint-meta",{"time":23},"2-3 hours",[25,26,27,30],"tldr",{},[13,28,29],{},"TL;DR",[13,31,32],{},"Bolt.new apps deployed on Vercel with Supabase need three critical security configurations: Row Level Security (RLS) policies on every Supabase table, environment variables for API keys instead of hardcoded values, and security headers in your vercel.json. Missing any of these leaves your app vulnerable.",[34,35,37],"h2",{"id":36},"why-this-boltnew-supabase-vercel-stack-needs-extra-attention","Why This Bolt.new + Supabase + Vercel Stack Needs Extra Attention",[13,39,40],{},"The Bolt.new + Supabase + Vercel combination is one of the most popular vibe coding stacks because Bolt.new generates Supabase-connected apps quickly and Vercel deployment is seamless. However, Bolt.new prioritizes speed over security configuration.",[13,42,43],{},"Common security gaps in Bolt.new generated apps:",[45,46,47,54,60,66],"ul",{},[48,49,50,53],"li",{},[16,51,52],{},"Missing RLS policies"," - Supabase tables are created without row-level security enabled",[48,55,56,59],{},[16,57,58],{},"Exposed API keys"," - Supabase URL and anon key hardcoded in client-side code",[48,61,62,65],{},[16,63,64],{},"No security headers"," - Vercel deployment lacks CSP and other protective headers",[48,67,68,71],{},[16,69,70],{},"Service role key exposure"," - Sometimes the service_role key (which bypasses RLS) is accidentally exposed",[34,73,75],{"id":74},"step-1-configure-supabase-row-level-security","Step 1: Configure Supabase Row Level Security",[13,77,78],{},"This is the most critical step. Without RLS, anyone with your Supabase URL and anon key can read and modify all data in your database.",[80,81,83],"h3",{"id":82},"enable-rls-on-every-table","Enable RLS on Every Table",[13,85,86],{},"In the Supabase dashboard, go to each table and enable RLS:",[88,89,91],"code-block",{"label":90},"SQL - Enable RLS",[92,93,98],"pre",{"className":94,"code":96,"language":97},[95],"language-text","-- Enable RLS on your tables\nALTER TABLE profiles ENABLE ROW LEVEL SECURITY;\nALTER TABLE posts ENABLE ROW LEVEL SECURITY;\nALTER TABLE comments ENABLE ROW LEVEL SECURITY;\n","text",[99,100,96],"code",{"__ignoreMap":101},"",[80,103,105],{"id":104},"create-basic-rls-policies","Create Basic RLS Policies",[13,107,108],{},"Here are common policy patterns for Bolt.new apps:",[88,110,112],{"label":111},"SQL - User can only see their own data",[92,113,116],{"className":114,"code":115,"language":97},[95],"-- Users can only read their own profile\nCREATE POLICY \"Users can view own profile\"\n  ON profiles FOR SELECT\n  USING (auth.uid() = user_id);\n\n-- Users can update their own profile\nCREATE POLICY \"Users can update own profile\"\n  ON profiles FOR UPDATE\n  USING (auth.uid() = user_id);\n",[99,117,115],{"__ignoreMap":101},[88,119,121],{"label":120},"SQL - Public read, authenticated write",[92,122,125],{"className":123,"code":124,"language":97},[95],"-- Anyone can read posts\nCREATE POLICY \"Posts are viewable by everyone\"\n  ON posts FOR SELECT\n  USING (true);\n\n-- Only authenticated users can create posts\nCREATE POLICY \"Authenticated users can create posts\"\n  ON posts FOR INSERT\n  WITH CHECK (auth.role() = 'authenticated');\n\n-- Users can only update their own posts\nCREATE POLICY \"Users can update own posts\"\n  ON posts FOR UPDATE\n  USING (auth.uid() = author_id);\n",[99,126,124],{"__ignoreMap":101},[34,128,130],{"id":129},"step-2-secure-your-supabase-api-keys","Step 2: Secure Your Supabase API Keys",[13,132,133],{},"Bolt.new often generates code with hardcoded Supabase credentials. Move these to environment variables.",[80,135,137],{"id":136},"whats-safe-vs-dangerous","What's Safe vs Dangerous",[139,140,141,157],"table",{},[142,143,144],"thead",{},[145,146,147,151,154],"tr",{},[148,149,150],"th",{},"Key Type",[148,152,153],{},"Client-Side Safe?",[148,155,156],{},"Why",[158,159,160,172,183],"tbody",{},[145,161,162,166,169],{},[163,164,165],"td",{},"SUPABASE_URL",[163,167,168],{},"Yes",[163,170,171],{},"Public project identifier",[145,173,174,177,180],{},[163,175,176],{},"SUPABASE_ANON_KEY",[163,178,179],{},"Yes (with RLS)",[163,181,182],{},"Only allows RLS-permitted operations",[145,184,185,188,191],{},[163,186,187],{},"SUPABASE_SERVICE_ROLE_KEY",[163,189,190],{},"NEVER",[163,192,193],{},"Bypasses all RLS, full database access",[80,195,197],{"id":196},"vercel-environment-variables","Vercel Environment Variables",[13,199,200],{},"Add your Supabase keys to Vercel:",[202,203,204,207,210,220],"ol",{},[48,205,206],{},"Go to your Vercel project settings",[48,208,209],{},"Navigate to Environment Variables",[48,211,212,213,216,217],{},"Add ",[99,214,215],{},"NEXT_PUBLIC_SUPABASE_URL"," and ",[99,218,219],{},"NEXT_PUBLIC_SUPABASE_ANON_KEY",[48,221,222,223,225],{},"For server-side only, add ",[99,224,187],{}," (without NEXT_PUBLIC_ prefix)",[88,227,229],{"label":228},"lib/supabase.ts - Using environment variables",[92,230,233],{"className":231,"code":232,"language":97},[95],"import { createClient } from '@supabase/supabase-js';\n\nconst supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;\nconst supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;\n\nexport const supabase = createClient(supabaseUrl, supabaseAnonKey);\n",[99,234,232],{"__ignoreMap":101},[34,236,238],{"id":237},"step-3-add-security-headers-on-vercel","Step 3: Add Security Headers on Vercel",[13,240,241,242,245],{},"Create or update your ",[99,243,244],{},"vercel.json"," with security headers:",[88,247,248],{"label":244},[92,249,252],{"className":250,"code":251,"language":97},[95],"{\n  \"headers\": [\n    {\n      \"source\": \"/(.*)\",\n      \"headers\": [\n        {\n          \"key\": \"X-Content-Type-Options\",\n          \"value\": \"nosniff\"\n        },\n        {\n          \"key\": \"X-Frame-Options\",\n          \"value\": \"DENY\"\n        },\n        {\n          \"key\": \"X-XSS-Protection\",\n          \"value\": \"1; mode=block\"\n        },\n        {\n          \"key\": \"Referrer-Policy\",\n          \"value\": \"strict-origin-when-cross-origin\"\n        },\n        {\n          \"key\": \"Permissions-Policy\",\n          \"value\": \"camera=(), microphone=(), geolocation=()\"\n        }\n      ]\n    }\n  ]\n}\n",[99,253,251],{"__ignoreMap":101},[34,255,257],{"id":256},"step-4-verify-your-configuration","Step 4: Verify Your Configuration",[13,259,260],{},"Test that your security is properly configured:",[262,263,265],"h4",{"id":264},"security-verification-checklist","Security Verification Checklist",[13,267,268],{},"RLS is enabled on all tables in Supabase dashboard",[13,270,271],{},"Each table has appropriate SELECT, INSERT, UPDATE, DELETE policies",[13,273,274],{},"No hardcoded API keys in your codebase (check .ts, .tsx, .js files)",[13,276,277],{},"Environment variables are set in Vercel dashboard",[13,279,280],{},"SUPABASE_SERVICE_ROLE_KEY is only used in server-side code",[13,282,283],{},"Security headers are present (check with browser dev tools)",[13,285,286],{},".env files are in .gitignore",[288,289,290,294],"stack-comparison",{},[80,291,293],{"id":292},"alternative-stacks-to-consider","Alternative Stacks to Consider",[92,295,298],{"className":296,"code":297,"language":97},[95],"      **Bolt.new + Next.js + Supabase**\n      App Router-specific patterns\n\n\n      **Bolt.new + Firebase**\n      Firebase alternative stack\n\n\n      **Bolt.new + Supabase**\n      Supabase-only security guide\n",[99,299,297],{"__ignoreMap":101},[34,301,303],{"id":302},"common-boltnew-security-mistakes","Common Bolt.new Security Mistakes",[80,305,307],{"id":306},"mistake-1-using-service-role-key-client-side","Mistake 1: Using Service Role Key Client-Side",[13,309,310],{},"Bolt.new sometimes generates code that uses the service_role key. This key bypasses all RLS and gives full database access. Never expose it to the client.",[80,312,314],{"id":313},"mistake-2-forgetting-to-enable-rls","Mistake 2: Forgetting to Enable RLS",[13,316,317,318,321],{},"Creating policies without enabling RLS on the table does nothing. Always run ",[99,319,320],{},"ALTER TABLE tablename ENABLE ROW LEVEL SECURITY;"," first.",[80,323,325],{"id":324},"mistake-3-overly-permissive-policies","Mistake 3: Overly Permissive Policies",[13,327,328,329,332],{},"Policies like ",[99,330,331],{},"USING (true)"," for INSERT or UPDATE allow anyone to modify data. Be specific about who can do what.",[34,334,336],{"id":335},"frequently-asked-questions","Frequently Asked Questions",[80,338,340],{"id":339},"does-boltnew-automatically-configure-supabase-rls","Does Bolt.new automatically configure Supabase RLS?",[13,342,343],{},"No. Bolt.new creates the database tables and basic structure, but RLS policies are usually not enabled by default. You must manually enable RLS and create policies for each table.",[80,345,347],{"id":346},"is-the-supabase-anon-key-safe-in-boltnew-apps","Is the Supabase anon key safe in Bolt.new apps?",[13,349,350],{},"The anon key is designed to be public, but only if RLS is properly configured. Without RLS policies, anyone with the anon key can read and modify all data. Always enable RLS before deploying.",[80,352,354],{"id":353},"should-i-use-separate-supabase-projects-for-dev-and-production","Should I use separate Supabase projects for dev and production?",[13,356,357],{},"Yes, strongly recommended. Using separate projects prevents accidental data leaks, lets you test RLS changes safely, and gives you isolated environments.",[359,360,363],"cta-box",{"href":361,"label":362},"/","Start Free Scan",[13,364,365],{},"Run a free security scan to identify exposed API keys, missing RLS, and other common vulnerabilities in your Bolt.new project.",[367,368,369,375,380],"related-articles",{},[370,371],"related-card",{"description":372,"href":373,"title":374},"Security configuration for Bolt apps using Supabase.","/blog/blueprints/bolt-supabase","Bolt.new + Supabase Security",[370,376],{"description":377,"href":378,"title":379},"Vercel-specific security settings for Bolt apps.","/blog/blueprints/bolt-vercel","Bolt.new + Vercel Security",[370,381],{"description":382,"href":383,"title":384},"Complete guide to Row Level Security policies.","/blog/how-to/setup-supabase-rls","How to Set Up Supabase RLS",{"title":101,"searchDepth":386,"depth":386,"links":387},2,[388,389,394,398,399,402,407],{"id":36,"depth":386,"text":37},{"id":74,"depth":386,"text":75,"children":390},[391,393],{"id":82,"depth":392,"text":83},3,{"id":104,"depth":392,"text":105},{"id":129,"depth":386,"text":130,"children":395},[396,397],{"id":136,"depth":392,"text":137},{"id":196,"depth":392,"text":197},{"id":237,"depth":386,"text":238},{"id":256,"depth":386,"text":257,"children":400},[401],{"id":292,"depth":392,"text":293},{"id":302,"depth":386,"text":303,"children":403},[404,405,406],{"id":306,"depth":392,"text":307},{"id":313,"depth":392,"text":314},{"id":324,"depth":392,"text":325},{"id":335,"depth":386,"text":336,"children":408},[409,410,411],{"id":339,"depth":392,"text":340},{"id":346,"depth":392,"text":347},{"id":353,"depth":392,"text":354},"blueprints","2026-01-29","2026-02-05","Complete security guide for the Bolt.new + Supabase + Vercel stack. Learn to configure RLS, protect API keys, set security headers, and deploy securely.",false,"md",[419,421,422],{"question":340,"answer":420},"No. Bolt.new creates the database tables and basic structure, but RLS policies are usually not enabled by default. You must manually enable RLS and create policies for each table to protect your data.",{"question":347,"answer":350},{"question":354,"answer":423},"Yes, strongly recommended. Using separate projects prevents accidental data leaks, lets you test RLS changes safely, and gives you isolated environments. Bolt.new makes it easy to switch between projects using environment variables.","purple",null,{},true,"Complete security configuration for the default Bolt.new deployment stack.","/blog/blueprints/bolt-supabase-vercel","12 min read","[object Object]","Article",{"title":5,"description":415},{"loc":429},"blog/blueprints/bolt-supabase-vercel",[437],"Popular Stack","summary_large_image","Dp8_PMM0WGRqOioi7QPJaGCB-gqs9VAI_G86Wy4GTlE",1775843932803]