TL;DR
The #1 Bolt.new security best practice is enabling Supabase Row Level Security before sharing your app URL. The 8 practices below take about 30 minutes end to end. If you only have five, do RLS: it's the one that decides whether your database is readable by strangers.
"Bolt builds your app in minutes. Take 30 more to secure it. Enable RLS, protect secrets, test access controls."
Understanding Bolt.new's Security Model
Bolt.new generates full-stack applications from prompts, usually a React frontend on a Supabase backend, deployed to Vercel or Netlify. The code works. That's the part Bolt optimizes for, and it's genuinely good at it.
Security is the part it leaves to you, and it doesn't say so.
In our analysis of 500 Bolt.new projects, 67% had at least one critical security issue including exposed API keys, missing authentication, or disabled Row Level Security (RLS).
Best Practice 1: Enable Row Level Security Immediately 5 min
Tables come out of Bolt with RLS switched off more often than not. Anyone holding your Supabase URL can then read or modify every row in them.
Critical: Your Supabase anon key is public by design. Without RLS, that public key is full database access for anyone who finds it. Enable RLS on every table before going live.
Enable RLS in Supabase Dashboard
- Go to your Supabase project dashboard
- Navigate to Table Editor
- Select each table
- Click the "RLS Disabled" button to enable it
- Add appropriate policies (see examples below)
-- Users can only read their own data
CREATE POLICY "Users read own data"
ON user_data FOR SELECT
USING (auth.uid() = user_id);
-- Users can only insert their own data
CREATE POLICY "Users insert own data"
ON user_data FOR INSERT
WITH CHECK (auth.uid() = user_id);
-- Users can only update their own data
CREATE POLICY "Users update own data"
ON user_data FOR UPDATE
USING (auth.uid() = user_id);
-- Public read access for published content
CREATE POLICY "Public read published"
ON posts FOR SELECT
USING (published = true);
Best Practice 2: Move Secrets to Environment Variables 5 min
Inline API keys show up in generated code regularly. Move every secret out before you deploy:
Common Secrets to Move
Check your code for these:
- Supabase URL and anon key (move to VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY)
- OpenAI or other AI API keys
- Stripe publishable and secret keys
- Any third-party service credentials
- Database connection strings
const supabase = createClient(
'https://abc123.supabase.co',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
);
const supabase = createClient(
import.meta.env.VITE_SUPABASE_URL,
import.meta.env.VITE_SUPABASE_ANON_KEY
);
Best Practice 3: Add Authentication to Protected Routes 10 min
A generated page and a protected page aren't the same thing. Add route guards to anything behind a login:
function ProtectedRoute({ children }) {
const { user, loading } = useAuth();
if (loading) {
return <div>Loading...</div>;
}
if (!user) {
return <Navigate to="/login" replace />;
}
return children;
}
// Usage in your router
<Route
path="/dashboard"
element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
}
/>
Best Practice 4: Validate All User Input 10 min per form
Generated forms tend to ship without validation. You want it on both sides, client and server:
import { z } from 'zod';
const userSchema = z.object({
email: z.string().email('Invalid email'),
name: z.string().min(2, 'Name too short').max(100),
age: z.number().min(13).max(120).optional(),
});
function handleSubmit(data) {
const result = userSchema.safeParse(data);
if (!result.success) {
// Handle validation errors
console.error(result.error.issues);
return;
}
// Proceed with validated data
saveUser(result.data);
}
Best Practice 5: Review API Endpoints 5 min per endpoint
Did Bolt give you API routes or Edge Functions? Review every one:
| Check | What to Look For | Fix |
|---|---|---|
| Authentication | Is user verified before action? | Add auth middleware |
| Authorization | Can user access this resource? | Check ownership/permissions |
| Input validation | Is input sanitized? | Add schema validation |
| Rate limiting | Can endpoint be abused? | Add rate limits |
| Error handling | Do errors leak internals? | Return generic messages |
Best Practice 6: Secure Your Deployment 10 min
Your hosting platform has security settings of its own. Configure them:
Vercel Security Settings
- Add environment variables in project settings (not in code)
- Enable password protection for preview deployments
- Configure security headers in vercel.json
- Set up deployment protection for production
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "X-XSS-Protection", "value": "1; mode=block" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" }
]
}
]
}
Best Practice 7: Test Before Sharing 15 min
Run through this before the URL reaches anyone else:
Pre-launch security checklist:
- Test login/logout flow works correctly
- Try accessing protected pages while logged out
- Check browser console for exposed secrets
- Verify RLS by testing API calls with different users
- Test form validation with malicious input
- Check that error messages don't leak sensitive details
Best Practice 8: Monitor Your Application Ongoing
Once you're live, a little monitoring goes a long way:
- Supabase Dashboard: Monitor API requests and database usage
- Vercel Analytics: Track errors and performance
- Error tracking: Consider adding Sentry for error reporting
- Alerts: Set up alerts for unusual activity patterns
Pro tip: Supabase keeps database logs showing every query. Skim them now and then. Unusual access patterns show up there first.
Common Bolt.new Security Mistakes
| Mistake | Impact | Prevention |
|---|---|---|
| Sharing app URL before securing | Anyone can access your data | Complete security checklist first |
| Leaving RLS disabled | Full database exposure | Enable RLS before any deployment |
| Using anon key for admin operations | Privilege escalation possible | Use service role only server-side |
| No input validation | XSS, injection attacks | Validate all inputs with Zod |
| Exposing error details | Information disclosure | Use generic error messages |
Official Resources: For the latest information, see Bolt.new, Supabase RLS Documentation, and Vercel Security Documentation.
Are Bolt.new apps secure by default?
No. Bolt writes working code, but you're the one who adds RLS policies, input validation and auth guards. Review and secure what it generates before you deploy.
Is it safe to share my Bolt app URL?
Only after completing security setup. Before sharing, enable RLS on all tables, move secrets to environment variables, add authentication to protected routes, and test thoroughly. An unsecured Bolt app URL is a security risk.
How do I know if my Bolt app has security issues?
Run a security scan with CheckYourVibe, manually test authentication and authorization, check your Supabase dashboard for RLS status, and review your code for hardcoded secrets. Common signs include exposed API keys in browser console and accessible data without login.
Can I use Bolt.new for production apps?
Yes, as long as you treat Bolt's output as a starting point. Add the security controls, test it properly, and get the code reviewed before it touches real user data or payments.
Further Reading
Put these practices into action with our step-by-step guides.
Secure Your Bolt App
Scan your Bolt.new project for security issues before going live.