[{"data":1,"prerenderedAt":200},["ShallowReactive",2],{"blog-blueprints/jamstack-supabase":3},{"id":4,"title":5,"body":6,"category":180,"date":181,"dateModified":181,"description":182,"draft":183,"extension":184,"faq":185,"featured":183,"headerVariant":186,"image":185,"keywords":185,"meta":187,"navigation":188,"ogDescription":189,"ogTitle":185,"path":190,"readTime":191,"schemaOrg":192,"schemaType":193,"seo":194,"sitemap":195,"stem":196,"tags":197,"twitterCard":198,"__hash__":199},"blog/blog/blueprints/jamstack-supabase.md","Jamstack + Supabase Security Blueprint",{"type":7,"value":8,"toc":169},"minimark",[9,20,23,29,34,49,53,62,66,75,84,88,93,96,99,102,105,108,122,157],[10,11,12],"blueprint-summary",{},[13,14,15,19],"p",{},[16,17,18],"strong",{},"To secure a Jamstack + Supabase site,"," you need to: (1) enable RLS on ALL tables since Jamstack sites have no server layer, (2) use only the anon key in client-side code, (3) leverage Edge Functions for operations requiring the service key, (4) test RLS policies thoroughly in the SQL editor, and (5) configure Storage bucket policies for file uploads. This blueprint covers pure client-side security patterns with Edge Functions for privileged operations.",[21,22],"blueprint-meta",{},[24,25,26],"tldr",{},[13,27,28],{},"Jamstack sites with Supabase have no server layer-100% of your security depends on RLS. Enable RLS on every table with restrictive policies, use anon key only, and leverage Edge Functions for operations requiring the service key.",[30,31,33],"h2",{"id":32},"client-side-supabase-setup-supabase","Client-Side Supabase Setup Supabase",[35,36,38],"code-block",{"label":37},"src/lib/supabase.js",[39,40,45],"pre",{"className":41,"code":43,"language":44},[42],"language-text","import { createClient } from '@supabase/supabase-js'\n\n// Only use the anon key on the client\nexport const supabase = createClient(\n  import.meta.env.PUBLIC_SUPABASE_URL,\n  import.meta.env.PUBLIC_SUPABASE_ANON_KEY\n)\n","text",[46,47,43],"code",{"__ignoreMap":48},"",[30,50,52],{"id":51},"row-level-security-supabase","Row Level Security Supabase",[35,54,56],{"label":55},"supabase/migrations/rls.sql",[39,57,60],{"className":58,"code":59,"language":44},[42],"-- Enable RLS on all tables\nALTER TABLE posts ENABLE ROW LEVEL SECURITY;\nALTER TABLE comments ENABLE ROW LEVEL SECURITY;\n\n-- Public read, authenticated write\nCREATE POLICY \"Public read posts\"\n  ON posts FOR SELECT\n  USING (published = true);\n\nCREATE POLICY \"Authors manage own posts\"\n  ON posts FOR ALL\n  USING (auth.uid() = author_id)\n  WITH CHECK (auth.uid() = author_id);\n\n-- Comments: authenticated users only\nCREATE POLICY \"Auth users read comments\"\n  ON comments FOR SELECT\n  USING (auth.uid() IS NOT NULL);\n\nCREATE POLICY \"Auth users create own comments\"\n  ON comments FOR INSERT\n  WITH CHECK (auth.uid() = user_id);\n",[46,61,59],{"__ignoreMap":48},[30,63,65],{"id":64},"edge-function-for-service-key-operations-supabase","Edge Function for Service Key Operations Supabase",[35,67,69],{"label":68},"supabase/functions/admin-action/index.ts",[39,70,73],{"className":71,"code":72,"language":44},[42],"import { createClient } from '@supabase/supabase-js'\n\nDeno.serve(async (req) => {\n  // Verify user auth from request\n  const authHeader = req.headers.get('Authorization')\n  const supabaseClient = createClient(\n    Deno.env.get('SUPABASE_URL')!,\n    Deno.env.get('SUPABASE_ANON_KEY')!,\n    { global: { headers: { Authorization: authHeader! } } }\n  )\n\n  const { data: { user } } = await supabaseClient.auth.getUser()\n  if (!user) {\n    return new Response('Unauthorized', { status: 401 })\n  }\n\n  // Use service key for admin operations\n  const adminClient = createClient(\n    Deno.env.get('SUPABASE_URL')!,\n    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!\n  )\n\n  // Perform privileged operation\n  const { data } = await adminClient.from('posts').select('*')\n\n  return new Response(JSON.stringify(data))\n})\n",[46,74,72],{"__ignoreMap":48},[76,77,78],"warning-box",{},[13,79,80,83],{},[16,81,82],{},"RLS is your only security layer."," With no server, clients access the database directly. Every table needs RLS. Test policies thoroughly before launch.",[30,85,87],{"id":86},"security-checklist","Security Checklist",[89,90,92],"h4",{"id":91},"pre-launch-checklist","Pre-Launch Checklist",[13,94,95],{},"RLS enabled on ALL tables",[13,97,98],{},"RLS policies tested in SQL editor",[13,100,101],{},"Only anon key in client code",[13,103,104],{},"Service key in Edge Functions only",[13,106,107],{},"Storage bucket policies configured",[109,110,111,117],"related-articles",{},[112,113],"related-card",{"description":114,"href":115,"title":116},"Hybrid rendering","/blog/blueprints/astro-supabase","Astro + Supabase",[112,118],{"description":119,"href":120,"title":121},"Deep dive","/blog/guides/supabase","Supabase Security Guide",[123,124,125,130,133],"stack-comparison",{},[126,127,129],"h3",{"id":128},"alternative-stacks","Alternative Stacks",[13,131,132],{},"Consider these related blueprints:",[134,135,136,143,150],"ul",{},[137,138,139,142],"li",{},[140,141,116],"a",{"href":115}," - With hybrid SSR support",[137,144,145,149],{},[140,146,148],{"href":147},"/blog/blueprints/nextjs-supabase-vercel","Next.js + Supabase + Vercel"," - Full-stack with server rendering",[137,151,152,156],{},[140,153,155],{"href":154},"/blog/blueprints/react-supabase","React + Supabase"," - React SPA alternative",[158,159,162,166],"cta-box",{"href":160,"label":161},"/","Start Free Scan",[30,163,165],{"id":164},"check-your-jamstack-supabase-site","Check Your Jamstack + Supabase Site",[13,167,168],{},"Scan for missing RLS policies.",{"title":48,"searchDepth":170,"depth":170,"links":171},2,[172,173,174,175,179],{"id":32,"depth":170,"text":33},{"id":51,"depth":170,"text":52},{"id":64,"depth":170,"text":65},{"id":86,"depth":170,"text":87,"children":176},[177],{"id":128,"depth":178,"text":129},3,{"id":164,"depth":170,"text":165},"blueprints","2026-02-05","Security guide for Jamstack sites with Supabase backend. Configure RLS for static sites, secure edge functions, implement client-side auth safely, and protect your Jamstack app.",false,"md",null,"purple",{},true,"Complete security configuration for Jamstack with Supabase.","/blog/blueprints/jamstack-supabase","9 min read","[object Object]","Article",{"title":5,"description":182},{"loc":190},"blog/blueprints/jamstack-supabase",[],"summary_large_image","CBFxNspiw33Ongps0C__MG4MQsBQhqeH9aWeagrCKgw",1775843932231]