One thing worth flagging first: /home/coder/uxcontinuum/content/blog/app-security/is-replit-safe.mdx already exists on disk, dated yesterday (2026-07-20), untracked and never committed or pushed. It covers this exact topic and slug almost identically (same three-gap structure: visibility, secrets sync, auth). Looks like a prior session generated it and it never got saved. I didn't touch it, just wrote fresh copy below. Worth deciding whether to commit that old one, replace it with this, or diff the two before either goes live.
Here's the post:
---
title: "Is Replit Safe for a Real Launch? Auth, Secrets, and the Deploy Gap"
description: "Replit Agent builds fast in the browser. Here's the Repl visibility leak, the secret that syncs to prod on deploy, and the auth check Agent skips."
date: "2026-07-21"
dateModified: "2026-07-21"
author:
name: "Matthew Turley"
avatar: "/avatar.jpg"
bio: "Fractional CTO and embedded technical partner. 20+ years shipping production software."
twitter: "uxcontinuum"
linkedin: "matthewturley"
category: "app-security"
tags: ["replit security", "replit agent safety", "vibe coded app security", "ai built app security", "supabase rls check"]
featured: false
readingTime: 6
image: "/images/blog/is-replit-safe.jpg"
---
Somebody DMed me last week: "Built my whole backend in Replit before lunch." That's not an exaggeration, that's the actual pitch, and for a rough scaffold it's often true. Type a sentence, watch Replit Agent write the frontend, wire up an endpoint, spin up a database if you asked for one. No terminal required. It's a genuinely different way of working than the one I learned on twenty years ago.
Most of my week now is the opposite motion. I get handed apps that some tool already built, days before somebody tries to put real users on them. Lovable, Bolt, v0, Base44, Cursor, Replit, whatever got a founder from idea to a live URL over a weekend. Replit shows up constantly in that stack. And the question I actually get isn't "is Replit good," it's "is Replit safe." Different question. Here's the honest answer.
## Where Replit actually does this right
The in-browser IDE isn't a toy sandbox, it's a real container, so what runs while you're building looks like what runs once you deploy. Agent installs dependencies, runs migrations, and as of this year can run its own test pass and retry a failed step without you babysitting every line. Deploy options are one click: Autoscale for a normal web app, Reserved VM if something needs to stay always on. And Replit ships a dedicated Secrets pane, AES-256 encrypted, kept separate from your source. That's more than a few AI builders bother with. None of that is where this goes wrong.
## Three gaps, and they're not the ones people ask about
**The Repl visibility toggle.** Every Repl is set to Public or Private. Easy to leave it Public while you're moving fast with Agent, because flipping the switch feels like a later problem. Public means anyone with the link browses your file tree, full stop. If a key ever got pasted into a comment, a config file, an old `.env` you thought you deleted, it's sitting there in plain text. This one's specific to Replit. Bolt and v0 don't expose a raw source tree the same way, you're never actually looking at files in those tools.
**The deploy sync nobody reads about.** This is the one that matches the headline, and it's the least obvious of the three. Secrets in Replit live scoped to your dev workspace. Publish for the first time, though, and most of them carry straight into the deployment, everything except database connection strings, which Replit deliberately holds back. Convenient default. Also exactly how a test-mode Stripe key or a personal API token you only meant for prototyping ends up live in production, without anyone actually deciding it should be there. You can turn off auto-sync per key before that first deploy. Almost nobody does, because nothing tells them to.
**The auth check Agent doesn't consistently write.** Agent is good at building an endpoint that returns whatever data your prompt described. It's a lot less consistent about writing the check in front of that endpoint, the part that confirms the session calling it actually belongs to someone. Hide a button behind a login screen in the UI and the route underneath is still just sitting there, answering any request that hits it directly. I see the same pattern in Bolt and v0 output too, it's not a Replit-only habit. It's the whole category trusting the frontend to enforce something only the backend can.
If your Replit app talks to Supabase, there's a fourth thing worth checking: the same row-level security gap every Supabase-backed AI builder ships by default. Agent wires the client, creates the tables, and stops there. Turning RLS on is a separate step, and it's the single most common finding across every AI-built app I've reviewed, Replit included.
## What the broader data says
I haven't run a Replit-only version of my own scan yet. The pass behind [the exposure report](/blog/app-security/ai-built-apps-exposure-report) covered 66 apps on Lovable, Bolt, Cursor, base44, and Tempo, not Replit specifically. But Replit is in the largest version of this study that exists anywhere. Security firm RedAccess scanned roughly 380,000 live apps across Lovable, Base44, Replit, and Netlify, and found about 5,000 of them leaking something real: medical records, financial documents, chat logs nobody meant to publish. WIRED and Axios both covered it. The root cause across every sample I've seen, mine included, traces back to a default nobody thought to check before the demo went live. I walk through where that pattern starts in [the audit findings post](/blog/ai-built-app-audit-findings).
## The self-check, about two minutes
Three checks. Nothing here needs a scanner or a security background, just a settings page and a terminal.
```bash
# 1. Is your Repl set to Public?
# Replit -> your Repl -> Settings -> confirm visibility is Private,
# especially if a .env file ever existed in it, even briefly.
# 2. Did a database table ship without RLS?
curl "https://<your-project>.supabase.co/rest/v1/<table_name>?select=*&limit=1" \
-H "apikey: <your-anon-key>"
# 3. Does a protected route actually check the session?
# Copy the request as curl from devtools, strip the auth header
# or cookie, run it again from a terminal.
Rows coming back on check two means that table has no policy stopping an anonymous read. Data still coming back on check three means the route trusts the request more than it trusts a session. Both are fixable in under an hour. Neither one touches Agent's generated code structure.
If you find something
Set the Repl to Private first, costs nothing, closes the visibility gap immediately. For the database, turn on RLS and scope reads to the owner, auth.uid() = user_id handles most tables. For the auth gap, the fix lives in the route handler, not the UI, add a session check before the query runs, then confirm the same stripped-header request from check three now fails. And rotate anything that was ever visible in a Public Repl's file tree while you're at it. A key that was exposed once should be treated as burned, whether or not you can prove somebody actually saw it.
Where this leaves Replit
Is Replit less safe than Lovable or Bolt? Not structurally, they all inherit the same database-layer risk the second Supabase enters the picture. What's specific to Replit is the visibility toggle and the secrets-sync default, two things fully in your control, maybe ninety seconds combined to check. Run the checks above first either way, they're free and they're the exact test behind every claim in this post. If you'd rather have someone run all three, plus the storage-bucket and server-route checks a quick pass tends to miss, the Vibe Check Launch Risk Review is one option, a fixed-price overnight pass with a ranked report, not a sales call.
1123 words. I did not write this to the repo or commit anything, it's here for you to review and place. Let me know if you want me to reconcile it against yesterday's uncommitted draft instead of shipping a second version.