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.
TL;DR
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.
PlanetScale with Bolt.new
PlanetScale offers MySQL compatibility with modern features:
| Feature | Security Benefit | Configuration Required |
|---|---|---|
| Database branching | Environment isolation | Create dev/prod branches |
| Deploy requests | Safe migrations | Require approval for prod |
| Connection strings | Credential management | Environment variables |
| SSL connections | Data in transit | sslaccept=strict |
Part 1: PlanetScale Branch Security
Set Up Separate Branches
# Production branch
main
├── Production data
├── Protected from direct schema changes
└── Changes via deploy requests only
# Development branch
development
├── Test data only
├── Safe for schema experimentation
└── Bolt development uses this branch
Connection String Management
# Production (.env.production)
DATABASE_URL="mysql://user:pass@aws.connect.psdb.cloud/mydb?sslaccept=strict"
# Development (.env.development)
DATABASE_URL="mysql://user:pass@aws.connect.psdb.cloud/mydb-dev?sslaccept=strict"
# NEVER commit these files
# Add to .gitignore: .env*
PlanetScale passwords are one-time view. Store them securely immediately after creation. If lost, create a new password.
Part 2: PlanetScale Query Security
Check Bolt-Generated Queries
If Bolt used Prisma or raw SQL, verify parameterization:
// If Bolt generated raw queries, check for this:
const user = await connection.execute(
`SELECT * FROM users WHERE email = '${email}'` // SQL injection!
);
// Correct pattern
const user = await connection.execute(
'SELECT * FROM users WHERE email = ?',
[email] // Parameterized - safe
);
// Or with Prisma (automatically safe)
const user = await prisma.user.findUnique({
where: { email }
});
Part 3: Application Authorization
PlanetScale (MySQL) doesn't have row-level security. Implement in code:
// lib/auth.ts
export async function requireOwnership(
userId: string,
resourceId: string,
resourceType: 'post' | 'comment'
) {
const resource = await prisma[resourceType].findUnique({
where: { id: resourceId }
});
if (!resource) {
throw new NotFoundError(`${resourceType} not found`);
}
if (resource.userId !== userId) {
throw new ForbiddenError('Not authorized');
}
return resource;
}
// Usage in API route
export async function PUT(req: Request, { params }) {
const session = await getSession(req);
if (!session?.user?.id) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
await requireOwnership(session.user.id, params.id, 'post');
// Safe to update...
}
Part 4: Deploy Requests
Safe Migration Workflow
# 1. Make schema changes on development branch
npx prisma db push # Against development DATABASE_URL
# 2. Test your changes
# 3. Create deploy request in PlanetScale dashboard
# Source: development
# Target: main
# 4. Review schema diff
# 5. Deploy when ready (production updated safely)
Security Checklist
Post-Export Checklist for Bolt + PlanetScale
Separate branches for dev and production
DATABASE_URL in environment variables
SSL enabled (sslaccept=strict)
No hardcoded credentials in code
Parameterized queries (no string interpolation)
Authorization checks in API routes
Production changes via deploy requests
.env files in .gitignore
Alternative Stacks to Consider
**Bolt.new + Supabase**
PostgreSQL with built-in RLS
**Bolt.new + MongoDB**
Document database alternative
**Bolt.new + Convex**
Real-time TypeScript database
Does PlanetScale support row-level security?
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.
Why use deploy requests?
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.
Can Bolt-generated code use PlanetScale directly?
Yes, PlanetScale is MySQL-compatible. If Bolt generated MySQL or Prisma code, it should work with PlanetScale after configuring the connection string.