[{"data":1,"prerenderedAt":352},["ShallowReactive",2],{"blog-blueprints/bolt-planetscale":3},{"id":4,"title":5,"body":6,"category":332,"date":333,"dateModified":333,"description":334,"draft":335,"extension":336,"faq":337,"featured":335,"headerVariant":338,"image":337,"keywords":337,"meta":339,"navigation":340,"ogDescription":341,"ogTitle":337,"path":342,"readTime":343,"schemaOrg":344,"schemaType":345,"seo":346,"sitemap":347,"stem":348,"tags":349,"twitterCard":350,"__hash__":351},"blog/blog/blueprints/bolt-planetscale.md","Bolt.new + PlanetScale Security Blueprint",{"type":7,"value":8,"toc":312},"minimark",[9,20,24,30,35,38,105,109,114,129,133,142,151,155,159,162,171,180,184,187,196,200,204,213,217,222,225,228,231,234,237,240,243,246,259,281,300],[10,11,12],"blueprint-summary",{},[13,14,15,19],"p",{},[16,17,18],"strong",{},"To secure a Bolt.new + PlanetScale stack,"," you need to: (1) use separate database branches for production and development environments, (2) store DATABASE_URL in environment variables with SSL enabled, (3) implement application-level authorization since MySQL lacks RLS, and (4) use deploy requests for safe production migrations. This blueprint covers MySQL-specific security patterns for serverless databases.",[21,22],"blueprint-meta",{"time":23},"1-2 hours",[25,26,27],"tldr",{},[13,28,29],{},"PlanetScale provides serverless MySQL with branching. After exporting from Bolt: use separate database branches for production and development, store DATABASE_URL in environment variables, implement authorization in your API routes (PlanetScale doesn't have RLS), and enable SSL in all connections. Use deploy requests for safe production migrations.",[31,32,34],"h2",{"id":33},"planetscale-with-boltnew","PlanetScale with Bolt.new",[13,36,37],{},"PlanetScale offers MySQL compatibility with modern features:",[39,40,41,57],"table",{},[42,43,44],"thead",{},[45,46,47,51,54],"tr",{},[48,49,50],"th",{},"Feature",[48,52,53],{},"Security Benefit",[48,55,56],{},"Configuration Required",[58,59,60,72,83,94],"tbody",{},[45,61,62,66,69],{},[63,64,65],"td",{},"Database branching",[63,67,68],{},"Environment isolation",[63,70,71],{},"Create dev/prod branches",[45,73,74,77,80],{},[63,75,76],{},"Deploy requests",[63,78,79],{},"Safe migrations",[63,81,82],{},"Require approval for prod",[45,84,85,88,91],{},[63,86,87],{},"Connection strings",[63,89,90],{},"Credential management",[63,92,93],{},"Environment variables",[45,95,96,99,102],{},[63,97,98],{},"SSL connections",[63,100,101],{},"Data in transit",[63,103,104],{},"sslaccept=strict",[31,106,108],{"id":107},"part-1-planetscale-branch-security","Part 1: PlanetScale Branch Security",[110,111,113],"h3",{"id":112},"set-up-separate-branches","Set Up Separate Branches",[115,116,118],"code-block",{"label":117},"PlanetScale branch strategy",[119,120,125],"pre",{"className":121,"code":123,"language":124},[122],"language-text","# Production branch\nmain\n  ├── Production data\n  ├── Protected from direct schema changes\n  └── Changes via deploy requests only\n\n# Development branch\ndevelopment\n  ├── Test data only\n  ├── Safe for schema experimentation\n  └── Bolt development uses this branch\n","text",[126,127,123],"code",{"__ignoreMap":128},"",[110,130,132],{"id":131},"connection-string-management","Connection String Management",[115,134,136],{"label":135},"Environment-specific connection strings",[119,137,140],{"className":138,"code":139,"language":124},[122],"# Production (.env.production)\nDATABASE_URL=\"mysql://user:pass@aws.connect.psdb.cloud/mydb?sslaccept=strict\"\n\n# Development (.env.development)\nDATABASE_URL=\"mysql://user:pass@aws.connect.psdb.cloud/mydb-dev?sslaccept=strict\"\n\n# NEVER commit these files\n# Add to .gitignore: .env*\n",[126,141,139],{"__ignoreMap":128},[143,144,145],"warning-box",{},[13,146,147,150],{},[16,148,149],{},"PlanetScale passwords are one-time view."," Store them securely immediately after creation. If lost, create a new password.",[31,152,154],{"id":153},"part-2-planetscale-query-security","Part 2: PlanetScale Query Security",[110,156,158],{"id":157},"check-bolt-generated-queries","Check Bolt-Generated Queries",[13,160,161],{},"If Bolt used Prisma or raw SQL, verify parameterization:",[115,163,165],{"label":164},"DANGEROUS: String interpolation",[119,166,169],{"className":167,"code":168,"language":124},[122],"// If Bolt generated raw queries, check for this:\nconst user = await connection.execute(\n  `SELECT * FROM users WHERE email = '${email}'`  // SQL injection!\n);\n",[126,170,168],{"__ignoreMap":128},[115,172,174],{"label":173},"SAFE: Parameterized query",[119,175,178],{"className":176,"code":177,"language":124},[122],"// Correct pattern\nconst user = await connection.execute(\n  'SELECT * FROM users WHERE email = ?',\n  [email]  // Parameterized - safe\n);\n\n// Or with Prisma (automatically safe)\nconst user = await prisma.user.findUnique({\n  where: { email }\n});\n",[126,179,177],{"__ignoreMap":128},[31,181,183],{"id":182},"part-3-application-authorization","Part 3: Application Authorization",[13,185,186],{},"PlanetScale (MySQL) doesn't have row-level security. Implement in code:",[115,188,190],{"label":189},"Authorization pattern",[119,191,194],{"className":192,"code":193,"language":124},[122],"// lib/auth.ts\nexport async function requireOwnership(\n  userId: string,\n  resourceId: string,\n  resourceType: 'post' | 'comment'\n) {\n  const resource = await prisma[resourceType].findUnique({\n    where: { id: resourceId }\n  });\n\n  if (!resource) {\n    throw new NotFoundError(`${resourceType} not found`);\n  }\n\n  if (resource.userId !== userId) {\n    throw new ForbiddenError('Not authorized');\n  }\n\n  return resource;\n}\n\n// Usage in API route\nexport async function PUT(req: Request, { params }) {\n  const session = await getSession(req);\n  if (!session?.user?.id) {\n    return Response.json({ error: 'Unauthorized' }, { status: 401 });\n  }\n\n  await requireOwnership(session.user.id, params.id, 'post');\n\n  // Safe to update...\n}\n",[126,195,193],{"__ignoreMap":128},[31,197,199],{"id":198},"part-4-deploy-requests","Part 4: Deploy Requests",[110,201,203],{"id":202},"safe-migration-workflow","Safe Migration Workflow",[115,205,207],{"label":206},"Migration process",[119,208,211],{"className":209,"code":210,"language":124},[122],"# 1. Make schema changes on development branch\nnpx prisma db push  # Against development DATABASE_URL\n\n# 2. Test your changes\n\n# 3. Create deploy request in PlanetScale dashboard\n#    Source: development\n#    Target: main\n\n# 4. Review schema diff\n\n# 5. Deploy when ready (production updated safely)\n",[126,212,210],{"__ignoreMap":128},[31,214,216],{"id":215},"security-checklist","Security Checklist",[218,219,221],"h4",{"id":220},"post-export-checklist-for-bolt-planetscale","Post-Export Checklist for Bolt + PlanetScale",[13,223,224],{},"Separate branches for dev and production",[13,226,227],{},"DATABASE_URL in environment variables",[13,229,230],{},"SSL enabled (sslaccept=strict)",[13,232,233],{},"No hardcoded credentials in code",[13,235,236],{},"Parameterized queries (no string interpolation)",[13,238,239],{},"Authorization checks in API routes",[13,241,242],{},"Production changes via deploy requests",[13,244,245],{},".env files in .gitignore",[247,248,249,253],"stack-comparison",{},[110,250,252],{"id":251},"alternative-stacks-to-consider","Alternative Stacks to Consider",[119,254,257],{"className":255,"code":256,"language":124},[122],"      **Bolt.new + Supabase**\n      PostgreSQL with built-in RLS\n\n\n      **Bolt.new + MongoDB**\n      Document database alternative\n\n\n      **Bolt.new + Convex**\n      Real-time TypeScript database\n",[126,258,256],{"__ignoreMap":128},[260,261,262,269,275],"faq-section",{},[263,264,266],"faq-item",{"question":265},"Does PlanetScale support row-level security?",[13,267,268],{},"No, MySQL doesn't have built-in RLS like PostgreSQL. You must implement authorization in your application code. This is a common pattern and works well with proper middleware.",[263,270,272],{"question":271},"Why use deploy requests?",[13,273,274],{},"Deploy requests show you exactly what schema changes will occur before applying them to production. This prevents accidental data loss and lets you review changes safely.",[263,276,278],{"question":277},"Can Bolt-generated code use PlanetScale directly?",[13,279,280],{},"Yes, PlanetScale is MySQL-compatible. If Bolt generated MySQL or Prisma code, it should work with PlanetScale after configuring the connection string.",[282,283,284,290,295],"related-articles",{},[285,286],"related-card",{"description":287,"href":288,"title":289},"Similar stack with Cursor","/blog/blueprints/cursor-planetscale-vercel","Cursor + PlanetScale + Vercel",[285,291],{"description":292,"href":293,"title":294},"Deep dive into PlanetScale","/blog/guides/planetscale","PlanetScale Security Guide",[285,296],{"description":297,"href":298,"title":299},"PostgreSQL alternative","/blog/blueprints/bolt-supabase","Bolt + Supabase",[301,302,305,309],"cta-box",{"href":303,"label":304},"/","Start Free Scan",[31,306,308],{"id":307},"exported-a-bolt-planetscale-app","Exported a Bolt + PlanetScale app?",[13,310,311],{},"Scan for query security and authorization issues.",{"title":128,"searchDepth":313,"depth":313,"links":314},2,[315,316,321,324,325,328,331],{"id":33,"depth":313,"text":34},{"id":107,"depth":313,"text":108,"children":317},[318,320],{"id":112,"depth":319,"text":113},3,{"id":131,"depth":319,"text":132},{"id":153,"depth":313,"text":154,"children":322},[323],{"id":157,"depth":319,"text":158},{"id":182,"depth":313,"text":183},{"id":198,"depth":313,"text":199,"children":326},[327],{"id":202,"depth":319,"text":203},{"id":215,"depth":313,"text":216,"children":329},[330],{"id":251,"depth":319,"text":252},{"id":307,"depth":313,"text":308},"blueprints","2026-01-28","Security guide for Bolt.new + PlanetScale stack. Secure database connections, protect credentials, implement authorization, and safely deploy your Bolt-generated app.",false,"md",null,"purple",{},true,"Complete security configuration for PlanetScale apps built with Bolt.new.","/blog/blueprints/bolt-planetscale","9 min read","[object Object]","Article",{"title":5,"description":334},{"loc":342},"blog/blueprints/bolt-planetscale",[],"summary_large_image","ALcAcgVugAuyE475EnoqmYPFnKinqKxRZt_2NcDrto8",1775843932886]