[{"data":1,"prerenderedAt":367},["ShallowReactive",2],{"blog-blueprints/bolt-supabase":3},{"id":4,"title":5,"body":6,"category":347,"date":348,"dateModified":348,"description":349,"draft":350,"extension":351,"faq":352,"featured":350,"headerVariant":353,"image":352,"keywords":352,"meta":354,"navigation":355,"ogDescription":356,"ogTitle":352,"path":357,"readTime":358,"schemaOrg":359,"schemaType":360,"seo":361,"sitemap":362,"stem":363,"tags":364,"twitterCard":365,"__hash__":366},"blog/blog/blueprints/bolt-supabase.md","Bolt.new + Supabase Security Blueprint",{"type":7,"value":8,"toc":324},"minimark",[9,20,24,30,35,38,90,94,99,102,117,121,130,143,147,151,154,163,167,176,180,184,187,196,200,204,207,216,225,229,234,237,240,243,246,249,252,255,258,271,293,312],[10,11,12],"blueprint-summary",{},[13,14,15,19],"p",{},[16,17,18],"strong",{},"To secure a Bolt.new + Supabase stack,"," you need to: (1) verify RLS is enabled on all tables after exporting from Bolt, (2) ensure only the anon key is used in client code while the service_role key stays server-side, (3) review authentication flows for proper session handling, and (4) add explicit user ID checks to data queries. This blueprint covers post-export security tasks with color-coded guidance for each platform.",[21,22],"blueprint-meta",{"time":23},"1-2 hours",[25,26,27],"tldr",{},[13,28,29],{},"Bolt.new generates full-stack apps rapidly, but often skips Supabase security configuration. Critical issues: RLS is frequently disabled or misconfigured, service_role keys may be exposed in client code, and authentication flows often lack proper session handling. After exporting from Bolt, immediately configure RLS policies, verify key usage, and add auth checks to any server-side code.",[31,32,34],"h2",{"id":33},"boltnew-security-considerations","Bolt.new Security Considerations",[13,36,37],{},"Bolt.new generates working apps quickly, but security requires post-generation review:",[39,40,41,54],"table",{},[42,43,44],"thead",{},[45,46,47,51],"tr",{},[48,49,50],"th",{},"What Bolt Does Well",[48,52,53],{},"What Needs Review",[55,56,57,66,74,82],"tbody",{},[45,58,59,63],{},[60,61,62],"td",{},"Generates working Supabase client setup",[60,64,65],{},"RLS policies may be missing or permissive",[45,67,68,71],{},[60,69,70],{},"Creates authentication UI",[60,72,73],{},"Session handling may be incomplete",[45,75,76,79],{},[60,77,78],{},"Scaffolds CRUD operations",[60,80,81],{},"Authorization checks often missing",[45,83,84,87],{},[60,85,86],{},"Sets up environment variables",[60,88,89],{},"May expose service_role key",[31,91,93],{"id":92},"part-1-check-supabase-rls-configuration","Part 1: Check Supabase RLS Configuration",[95,96,98],"h3",{"id":97},"verify-rls-is-enabled","Verify RLS is Enabled",[13,100,101],{},"After exporting your Bolt project, check Supabase dashboard:",[103,104,106],"code-block",{"label":105},"SQL to check RLS status",[107,108,113],"pre",{"className":109,"code":111,"language":112},[110],"language-text","-- Run in Supabase SQL Editor\nSELECT\n  schemaname,\n  tablename,\n  rowsecurity\nFROM pg_tables\nWHERE schemaname = 'public';\n\n-- If rowsecurity is 'false', enable it:\nALTER TABLE your_table ENABLE ROW LEVEL SECURITY;\n","text",[114,115,111],"code",{"__ignoreMap":116},"",[95,118,120],{"id":119},"add-proper-rls-policies","Add Proper RLS Policies",[103,122,124],{"label":123},"Common RLS policies for Bolt apps",[107,125,128],{"className":126,"code":127,"language":112},[110],"-- User profiles: only owner can access\nCREATE POLICY \"Users can view own profile\"\n  ON profiles FOR SELECT\n  USING (auth.uid() = id);\n\nCREATE POLICY \"Users can update own profile\"\n  ON profiles FOR UPDATE\n  USING (auth.uid() = id);\n\n-- User's items: full access to own data\nCREATE POLICY \"Users can manage own items\"\n  ON items FOR ALL\n  USING (auth.uid() = user_id);\n\n-- Public read, authenticated write\nCREATE POLICY \"Anyone can read posts\"\n  ON posts FOR SELECT\n  USING (true);\n\nCREATE POLICY \"Authenticated users can create posts\"\n  ON posts FOR INSERT\n  WITH CHECK (auth.uid() = author_id);\n",[114,129,127],{"__ignoreMap":116},[131,132,133],"warning-box",{},[13,134,135,138,139,142],{},[16,136,137],{},"Bolt often generates:"," ",[114,140,141],{},"allow read, write: if true"," equivalent policies or skips RLS entirely. Always verify before deploying.",[31,144,146],{"id":145},"part-2-supabase-api-key-security","Part 2: Supabase API Key Security",[95,148,150],{"id":149},"check-key-usage-in-generated-code","Check Key Usage in Generated Code",[13,152,153],{},"Search your exported code for key usage:",[103,155,157],{"label":156},"Search for potential key exposure",[107,158,161],{"className":159,"code":160,"language":112},[110],"# In your exported project directory\ngrep -r \"service_role\" .\ngrep -r \"supabase\" . --include=\"*.ts\" --include=\"*.js\"\n\n# Look for hardcoded keys\ngrep -r \"eyJ\" . --include=\"*.ts\" --include=\"*.js\"\n",[114,162,160],{"__ignoreMap":116},[95,164,166],{"id":165},"correct-key-setup","Correct Key Setup",[103,168,170],{"label":169},"lib/supabase.ts - Safe client setup",[107,171,174],{"className":172,"code":173,"language":112},[110],"import { createClient } from '@supabase/supabase-js'\n\n// Only use anon key in client code\nconst supabaseUrl = import.meta.env.VITE_SUPABASE_URL\nconst supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY\n\nexport const supabase = createClient(supabaseUrl, supabaseAnonKey)\n\n// NEVER do this in client code:\n// const supabase = createClient(url, process.env.SUPABASE_SERVICE_ROLE_KEY)\n",[114,175,173],{"__ignoreMap":116},[31,177,179],{"id":178},"part-3-authentication-flow","Part 3: Authentication Flow",[95,181,183],{"id":182},"verify-session-handling","Verify Session Handling",[13,185,186],{},"Bolt-generated auth often needs session persistence fixes:",[103,188,190],{"label":189},"hooks/useAuth.ts - Proper session handling",[107,191,194],{"className":192,"code":193,"language":112},[110],"import { useEffect, useState } from 'react'\nimport { supabase } from '../lib/supabase'\nimport { User, Session } from '@supabase/supabase-js'\n\nexport function useAuth() {\n  const [user, setUser] = useState\u003CUser | null>(null)\n  const [loading, setLoading] = useState(true)\n\n  useEffect(() => {\n    // Get initial session\n    supabase.auth.getSession().then(({ data: { session } }) => {\n      setUser(session?.user ?? null)\n      setLoading(false)\n    })\n\n    // Listen for auth changes\n    const { data: { subscription } } = supabase.auth.onAuthStateChange(\n      (_event, session) => {\n        setUser(session?.user ?? null)\n      }\n    )\n\n    return () => subscription.unsubscribe()\n  }, [])\n\n  return { user, loading }\n}\n",[114,195,193],{"__ignoreMap":116},[31,197,199],{"id":198},"part-4-data-fetching-security","Part 4: Data Fetching Security",[95,201,203],{"id":202},"add-authorization-to-queries","Add Authorization to Queries",[13,205,206],{},"Bolt-generated queries may fetch without checking ownership:",[103,208,210],{"label":209},"BEFORE: Bolt-generated query (potentially unsafe)",[107,211,214],{"className":212,"code":213,"language":112},[110],"// May fetch all items regardless of owner\nconst { data } = await supabase\n  .from('items')\n  .select('*')\n",[114,215,213],{"__ignoreMap":116},[103,217,219],{"label":218},"AFTER: Scoped to current user",[107,220,223],{"className":221,"code":222,"language":112},[110],"// With proper RLS, this returns only user's items\nconst { data: { user } } = await supabase.auth.getUser()\n\nif (!user) {\n  throw new Error('Not authenticated')\n}\n\nconst { data } = await supabase\n  .from('items')\n  .select('*')\n  .eq('user_id', user.id)  // Explicit filter (defense in depth)\n",[114,224,222],{"__ignoreMap":116},[31,226,228],{"id":227},"security-checklist","Security Checklist",[230,231,233],"h4",{"id":232},"post-export-checklist-for-bolt-supabase","Post-Export Checklist for Bolt + Supabase",[13,235,236],{},"RLS enabled on all tables",[13,238,239],{},"RLS policies restrict access properly",[13,241,242],{},"Only anon key used in client code",[13,244,245],{},"Service role key not in repository",[13,247,248],{},"Auth state properly persisted",[13,250,251],{},"Protected routes check authentication",[13,253,254],{},"Environment variables not hardcoded",[13,256,257],{},"No sensitive data in git history",[259,260,261,265],"stack-comparison",{},[95,262,264],{"id":263},"alternative-stacks-to-consider","Alternative Stacks to Consider",[107,266,269],{"className":267,"code":268,"language":112},[110],"      **Bolt.new + Firebase**\n      If you prefer Firebase's ecosystem\n\n\n      **Bolt.new + Supabase + Vercel**\n      Add Vercel deployment security\n\n\n      **Bolt.new + Convex**\n      Real-time alternative with built-in functions\n",[114,270,268],{"__ignoreMap":116},[272,273,274,281,287],"faq-section",{},[275,276,278],"faq-item",{"question":277},"Can I trust Bolt-generated Supabase code?",[13,279,280],{},"Bolt generates functional code, but security configuration requires manual review. Always check RLS policies, key usage, and authentication flows before deploying to production.",[275,282,284],{"question":283},"Why does my Bolt app work without RLS?",[13,285,286],{},"Without RLS, the anon key grants read/write access to all data. This is convenient for development but dangerous in production. Enable and configure RLS before going live.",[275,288,290],{"question":289},"How do I add server-side code to a Bolt app?",[13,291,292],{},"Export your Bolt project and add API routes or server functions to your deployment platform. Use the service_role key only in server-side code for admin operations.",[294,295,296,302,307],"related-articles",{},[297,298],"related-card",{"description":299,"href":300,"title":301},"Similar stack with Cursor","/blog/blueprints/cursor-supabase-vercel","Cursor + Supabase + Vercel",[297,303],{"description":304,"href":305,"title":306},"Deep dive into Supabase","/blog/guides/supabase","Supabase Security Guide",[297,308],{"description":309,"href":310,"title":311},"Alternative with Firebase","/blog/blueprints/bolt-firebase","Bolt + Firebase",[313,314,317,321],"cta-box",{"href":315,"label":316},"/","Start Free Scan",[31,318,320],{"id":319},"exported-a-bolt-supabase-app","Exported a Bolt + Supabase app?",[13,322,323],{},"Scan for RLS misconfigurations and key exposure.",{"title":116,"searchDepth":325,"depth":325,"links":326},2,[327,328,333,337,340,343,346],{"id":33,"depth":325,"text":34},{"id":92,"depth":325,"text":93,"children":329},[330,332],{"id":97,"depth":331,"text":98},3,{"id":119,"depth":331,"text":120},{"id":145,"depth":325,"text":146,"children":334},[335,336],{"id":149,"depth":331,"text":150},{"id":165,"depth":331,"text":166},{"id":178,"depth":325,"text":179,"children":338},[339],{"id":182,"depth":331,"text":183},{"id":198,"depth":325,"text":199,"children":341},[342],{"id":202,"depth":331,"text":203},{"id":227,"depth":325,"text":228,"children":344},[345],{"id":263,"depth":331,"text":264},{"id":319,"depth":325,"text":320},"blueprints","2026-01-28","Security guide for Bolt.new + Supabase stack. Configure RLS policies, protect API keys, handle authentication, and secure your Bolt-generated Supabase app.",false,"md",null,"purple",{},true,"Complete security configuration for Supabase apps built with Bolt.new.","/blog/blueprints/bolt-supabase","10 min read","[object Object]","Article",{"title":5,"description":349},{"loc":357},"blog/blueprints/bolt-supabase",[],"summary_large_image","I6-5UMCmMgGPHgIShqSeXydAMBQrvt4ngtakcLvvv0I",1775843932909]