Notes on securing AI‑built apps
Short, practical write-ups of failures that ship in apps built with Lovable, Bolt, Replit and Cursor, and how to check whether yours has them. Most come from real work, including my own mistakes.
Before launch
- Is my Lovable app secure? A checklist before you launchThe problems that matter most in AI-built apps don't produce errors. The app works. It's just open. Here is how to check yours in an afternoon.
- Delete your own account: the test most AI-built apps failSign up, delete your account, then look in the database. In most AI-built apps the rows are still there, and the app said it worked.
Supabase
- RLS is on, but anyone can still write to your Supabase tablesThe dashboard says your tables are protected. Here is a 60-second, read-only check that shows you what they actually allow.
- Fixing "new row violates row-level security policy" without opening your dataMost Supabase builders hit this error in their first week. The fix that makes it disappear fastest is the one that causes the most damage later.
- Publishable or secret: which Supabase key belongs whereOne key is designed to be public. The other ignores every security rule you have written. Here is where each belongs, and a test that shows you the difference.
- Is your Supabase secret key sitting in your frontend?One key is meant to be public. The other bypasses every security rule you have. Here is how to tell which one your live site is shipping.
- Securing file uploads in Supabase StorageUploads are the easiest place to leave a door open: a public bucket, a policy that lets anyone write, or a file path the user gets to choose.
- Why your Supabase app stops at 1,000 rows, and never tells youTotals that stop growing. Exports that are always exactly a thousand lines. No error anywhere. Here is what is happening and how to fix it properly.
Stripe
- Stripe says "No signatures found matching the expected signature for payload"The hint in the error message is usually right. Here are the four causes, and why switching the check off is the worst available fix.
- Stripe webhooks firing twice: how to make your handler safe to run againStripe will sometimes send you the same event more than once, and not always in the order things happened. Here is how to build a handler that doesn't care.
- Refunding a buyer after the seller has been paid, on Stripe ConnectOn a marketplace using separate charges and transfers, a refund does not touch the seller's money. I built a test marketplace in a Stripe sandbox to watch exactly what happens.