You shipped it at 2am. It's up, it works, some traffic is trickling in. Give it one hour before the traffic scales up. Twelve questions, each is a yes/no.
Client-side
- 1. View source. Open the page and search the HTML for
sk_,sk-,AKIA,AIza. Any hits? - 2. Bundle scan. In devtools → Sources, do a project-wide search for
service_role. If it's there, rotate immediately. - 3. Env vars. Any secret prefixed with
VITE_,NEXT_PUBLIC_, orPUBLIC_is public. Confirm none of them are real secrets.
Database
- 4. RLS enabled on every table in
public. - 5. Owner policies — user-owned tables filter by
auth.uid() = user_id. - 6. No
USING (true)for INSERT, UPDATE, DELETE. - 7. Roles table exists — admin flags are NOT stored on the profile row.
API + auth
- 8. Every mutation server-side re-checks the user.
- 9. Webhooks verify signatures. Stripe, GitHub, whoever calls in.
- 10. No admin UI purely client-gated. Even the API rejects non-admins.
The rest
- 11. Storage buckets private by default. Signed URLs only.
- 12. Password reset works — including the return-to-app step. If it doesn't, users can lock themselves out and you'll never notice.
Run this list on the URL you launched last night. Take an hour. It's a lot cheaper than a Sunday-night migration.