ShipWatchFree scan

The 15-minute pre-launch security pass for an AI-built app

It's launch day and you don't have time for an audit. This is a timed runbook, not another checklist: what to do in each block of minutes, what to skip if a block runs over, and what to leave for next week.

Short answer: Minute 0: scan your production URL. Minutes 2 to 7: fix anything critical, which almost always means rotating a leaked key. Minutes 7 to 10: add security headers. Minutes 10 to 13: three manual checks the scan can't do (table RLS, storage buckets, Stripe webhook). Minutes 13 to 15: rescan and record a baseline.

For the reasoning behind each item, read vibe coding security: 6 mistakes or the vibe coding security checklist. This page is just the order and the clock. Set a timer.

Before you start (not timed)

Minutes 0 to 2: scan production

Paste your production URL into the free scan. In about 30 seconds it reads your page and up to 25 linked scripts for Stripe, OpenAI, Anthropic, AWS, Google and Supabase secret keys; requests /.env and /.git/HEAD; and checks HTTPS, the HTTP to HTTPS redirect, and four headers (CSP, HSTS, X-Frame-Options or frame-ancestors, nosniff). Sort the findings: critical and high first.

Minutes 2 to 7: fix what's critical

Criticals are almost always a live secret key in the bundle or a public /.env. Work in this order:

  1. Revoke or roll the key with the provider first, before touching code. The copy in your bundle is already public. The rotate-first playbook has where each provider's button lives.
  2. Move the call server-side into an edge function or API route, with the new key in a server-only secret.
  3. Exposed /.env or /.git: remove it from the deployed output and block the path; rotate every secret it contained.
  4. Redeploy.

If this block runs over, let it. Don't launch with a live secret key in your JavaScript.

The security scan found a secret key in my frontend bundle. I have already revoked it with the provider. Move every call that uses it into a server-side function, read the new key from a server-only secret (never a VITE_ or NEXT_PUBLIC_ variable), and remove all references from client code. Then tell me which files changed.

Minutes 7 to 10: headers

Add HSTS, nosniff, X-Frame-Options and a framing CSP with one file: public/_headers on Netlify or Cloudflare Pages, or a headers block in vercel.json. The copy-paste versions are in security headers for Netlify and Vercel. A full Content-Security-Policy takes longer to get right; ship framing protection today and follow the CSP guide next week.

Minutes 10 to 13: three checks the scan can't do [manual]

  1. Tables (1 minute). Query one private table with your public key, exactly as a logged-out visitor would. Rows back means RLS is off or too loose. The curl command is in is the Supabase anon key safe?
  2. Storage (1 minute). Run select id, public from storage.buckets;. Any public bucket holding private files needs moving. See Supabase Storage buckets.
  3. Payments (1 minute). Search your webhook handler for constructEvent. If it isn't there, anyone can fake a "payment succeeded" event. See Stripe webhook signature verification.

If one fails and you can't fix it in the block, decide honestly: delay launch, or disable that feature for launch day.

Minutes 13 to 15: rescan and record

  1. Run the scan again on the same URL. Criticals and highs should be gone.
  2. Write down the score and remaining findings as your baseline.
  3. Launch.

After launch: keep it from regressing

AI builders change a lot of code per prompt, and a key can come back in any deploy. Rescan after every significant change, or turn on weekly monitoring, which re-runs the same checks and shows changes in your dashboard: Solo $19/mo or Pro $49/mo, see pricing. Next week, set aside an hour for what this pass skipped: a full CSP, auth flows, rate limits on AI endpoints, and dependency updates.

What the free scan checks here (and what it doesn't)

It checks secret keys in your HTML and up to 25 linked scripts (Stripe sk_live_ and rk_live_, OpenAI, Anthropic, AWS, Google, and Supabase service_role and sb_secret_), /.env, /.git/HEAD, HTTPS and its redirect, and four security headers. It reports your Supabase anon key and URL as info only. It doesn't test tables, storage buckets, webhooks, login flows or business logic; that's why minutes 10 to 13 are [manual].

FAQ

Is 15 minutes really enough to secure an app?
No, and this page doesn't claim it is. It's enough to catch the failures that hurt most on day one: live secret keys in your bundle, an exposed .env or .git, missing headers, and tables or files anyone can read. Auth and business logic need a proper review later.
What if the scan finds a critical issue at minute 2?
Stop the clock and fix it. A live secret key in your JavaScript is worth delaying launch for: revoke it with the provider first, move the call server-side, redeploy, then rescan before continuing.
Should I scan the preview URL or production?
Production, on the exact domain users will visit. Headers, redirects and environment variables often differ between preview and production, and the scan reports what that URL actually serves.

Scan your app free in 30 seconds

Paste your live URL for a plain-English report with fix prompts. If you keep shipping, weekly monitoring re-checks it: Solo $19/mo or Pro $49/mo.

Scan my app free