To secure a Cursor + PlanetScale + Vercel stack, you need to: (1) use separate database branches for production and development environments, (2) store connection strings in Vercel environment variables with SSL enabled, (3) protect your production branch and use deploy requests for schema changes, (4) implement authorization checks in all API routes since PlanetScale lacks built-in RLS, and (5) create a .cursorignore file to prevent AI from accessing your .env files. This blueprint covers PlanetScale branching security, Prisma configuration, and application-level authorization patterns.
TL;DR
PlanetScale provides a MySQL-compatible serverless database with git-like branching. Security priorities: use different database branches for development vs production, store connection strings in Vercel environment variables, enable safe migrations with deploy requests, and implement authorization in your API routes since PlanetScale doesn't have row-level security like Supabase.
Platform Guides & Checklists
Cursor Security Guide
PlanetScale Security Guide
Vercel Security Guide
Pre-Launch Checklist
Stack Overview
PlanetScale's branching model is excellent for safe database changes, but security depends on proper configuration:
| Component | Role | Security Focus |
|---|---|---|
| Cursor | AI code editor | Query safety, secret management |
| PlanetScale | Serverless MySQL | Branch isolation, connection security |
| Vercel | Hosting | Environment variables, API routes |
Part 1: Database Branch Security PlanetScale
Branch Strategy PlanetScale
Use PlanetScale branches to isolate environments:
# Production branch (protected)
main
├── Vercel Production deployment
├── Safe migrations via deploy requests
└── No direct schema changes
# Development branch
dev
├── Vercel Preview deployments
├── Schema experimentation
└── Test data only
# Feature branches (optional)
feature/user-profiles
├── Schema changes for new feature
└── Merge to dev, then main via deploy request
Connection Strings PlanetScale Vercel
Each branch has its own connection string. Never share production credentials:
# Production (main branch)
DATABASE_URL="mysql://user:pass@aws.connect.psdb.cloud/mydb?sslaccept=strict"
# Preview (dev branch) - set in Vercel for preview deployments
DATABASE_URL="mysql://user:pass@aws.connect.psdb.cloud/mydb-dev?sslaccept=strict"
PlanetScale passwords can't be retrieved after creation. Store them securely in Vercel immediately. If lost, you'll need to create a new password.
Part 2: Query Security with Prisma PlanetScale
PlanetScale works well with Prisma. Configure it for serverless:
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma" // Required for PlanetScale
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
}
model Post {
id String @id @default(cuid())
title String
content String @db.Text
authorId String
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now())
@@index([authorId])
}
Part 3: Application-Level Authorization Vercel
Unlike Supabase, PlanetScale doesn't have row-level security. Implement authorization in your code:
import { prisma } from '@/lib/prisma';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
export async function PUT(
request: Request,
{ params }: { params: { id: string } }
) {
// Verify authentication
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
// Fetch the post
const post = await prisma.post.findUnique({
where: { id: params.id }
});
if (!post) {
return Response.json({ error: 'Not found' }, { status: 404 });
}
// Authorization check - only author can update
if (post.authorId !== session.user.id) {
return Response.json({ error: 'Forbidden' }, { status: 403 });
}
// Safe to update
const { title, content } = await request.json();
const updated = await prisma.post.update({
where: { id: params.id },
data: { title, content }
});
return Response.json(updated);
}
Part 4: Safe Schema Migrations PlanetScale
Using Deploy Requests PlanetScale
Never run migrations directly on production. Use PlanetScale's deploy request workflow:
# 1. Make schema changes on dev branch
npx prisma db push
# 2. Create deploy request in PlanetScale dashboard
# dev → main
# 3. Review schema diff in dashboard
# 4. Deploy (applies changes to main branch)
# 5. Vercel will use the updated production schema
Security Checklist
Pre-Launch Checklist for Cursor + PlanetScale + Vercel
Production branch protected from direct changes
Separate connection strings for prod/dev
DATABASE_URL in Vercel environment variables
SSL enabled in connection string (sslaccept=strict)
Authorization checks in all API routes
Prisma relationMode set to "prisma"
No raw SQL with user input
.cursorignore excludes .env files
Deploy requests used for production migrations
Alternative Stack Configurations
Cursor + Supabase + Vercel Swap PlanetScale for Supabase PostgreSQL with built-in RLS. Different security model.
Cursor + Neon + Railway
Serverless Postgres with branching like PlanetScale, but with RLS support.
Cursor + Prisma + Vercel
General Prisma guide applicable to any database backend.
Why doesn't PlanetScale have row-level security?
PlanetScale is MySQL-compatible, and MySQL doesn't have built-in RLS like PostgreSQL. You implement authorization in your application layer. This gives you more flexibility but requires careful coding.
::faq-item{question="What's relationMode = "prisma"?"} PlanetScale doesn't support foreign key constraints at the database level. Setting relationMode to "prisma" tells Prisma to handle relations in application code instead, maintaining referential integrity through Prisma's query engine. ::
How do I handle connection pooling on Vercel?
PlanetScale handles connection pooling automatically on their edge. Unlike traditional MySQL, you don't need additional pooling like PgBouncer. The serverless driver handles this efficiently.
Using PlanetScale with Cursor?
Scan your app for query security and authorization issues.
Start Free Scan