Production readiness checklist

For web apps and AI-built apps, before you ship.

AI coding tools — Cursor, Lovable, Bolt, Replit, v0, Windsurf — make it fast to build and ship, and just as fast to launch with leaked keys, an open database, or a missing defence. This checklist walks the 198things UseShipReady checks on a live site, grouped in the order you’d work through them before launch. Each item links to a page explaining what it means and how to fix it. For why these particular failures recur in generated apps, see vibe coding security.

It’s generated from the scanner itself, so it always matches exactly what runs against your site. Start at the top — secrets and database access are where the launch-day disasters live.

If you run a formal production readiness review, this covers the externally observable half of it — what your software exposes to the internet on launch day. It does not cover capacity planning, on-call rotation or rollback procedure, which no scanner can see from outside.

Copy the checklist as a template

Markdown task list, ready to paste into an issue, a PR description or a doc. Select all and copy.

Production readiness checklist — 198 checks
Generated from the UseShipReady scanner. https://useshipready.dev/checklist

## Secrets & API keys
- [ ] Anthropic API Key Exposed
- [ ] AWS Access Key Exposed
- [ ] Cloudinary API Secret Exposed
- [ ] Database Connection String Exposed
- [ ] Exposed environment file (.env)
- [ ] GitHub Token Exposed
- [ ] Groq API Key Exposed
- [ ] Hugging Face Token Exposed
- [ ] npm Access Token Exposed
- [ ] OpenAI API Key Exposed
- [ ] OpenRouter API Key Exposed
- [ ] Perplexity API Key Exposed
- [ ] Private Key Exposed
- [ ] PyPI API Token Exposed
- [ ] Replicate API Token Exposed
- [ ] Resend API Key Exposed
- [ ] SendGrid API Key Exposed
- [ ] Slack API Token Exposed
- [ ] Stripe Secret Key Exposed
- [ ] Stripe Webhook Signing Secret Exposed
- [ ] Supabase Secret Key Exposed
- [ ] xAI API Key Exposed
- [ ] Mapbox Secret Token Exposed
- [ ] Slack Incoming Webhook URL Exposed
- [ ] Stripe Restricted Key Exposed
- [ ] Potential Secret or Private Token Exposed

## AI coding-tool exposure
- [ ] Secret published through a browser-exposed environment variable
- [ ] AI provider client is configured to run in the browser
- [ ] Exposed AI tooling config that can contain credentials
- [ ] MCP server is reachable without authentication
- [ ] AI system prompt is hardcoded in the browser bundle
- [ ] Exposed AI Tooling Config File
- [ ] AI builder fingerprint exposed
- [ ] AI widget missing SRI
- [ ] AI endpoints are reachable from your client code

## Database & backend access
- [ ] Firebase Realtime Database is publicly readable
- [ ] Firebase Storage bucket is publicly listable
- [ ] Anyone can sign up with an email address they do not own
- [ ] Anyone can make your project send an SMS
- [ ] Anyone can obtain a signed-in session without an account
- [ ] Public Supabase Storage bucket
- [ ] Supabase table is publicly readable

## HTTPS & TLS
- [ ] HTTP is not redirected to HTTPS
- [ ] TLS certificate does not validate
- [ ] TLS certificate expiring
- [ ] Server still accepts a deprecated TLS version

## Security headers
- [ ] Missing Content-Security-Policy header
- [ ] CSP allows 'unsafe-eval'
- [ ] CSP allows 'unsafe-inline' scripts
- [ ] CSP script-src allows an overly permissive source
- [ ] Missing or permissive X-Frame-Options header
- [ ] Missing Strict-Transport-Security header
- [ ] Invalid Referrer-Policy value
- [ ] Missing or invalid X-Content-Type-Options header
- [ ] Missing Referrer-Policy header
- [ ] Response header discloses a software version
- [ ] Strict-Transport-Security is missing includeSubDomains
- [ ] Weak Strict-Transport-Security max-age

## Cookies & sessions
- [ ] Session Cookie Missing 'HttpOnly' Flag
- [ ] Session Cookie Missing 'Secure' Flag
- [ ] Session Cookie Missing 'SameSite' Attribute
- [ ] Session Cookie Uses 'SameSite=None' Without 'Secure'

## Information disclosure
- [ ] Exposed .git Directory
- [ ] Exposed docker-compose file
- [ ] Overly Permissive CORS with Credentials
- [ ] Directory Listing Enabled
- [ ] Error page leaks a stack trace
- [ ] Exposed Debug or Config Endpoint
- [ ] GraphQL introspection is enabled in production
- [ ] Exposed .DS_Store file
- [ ] Exposed JavaScript Source Map

## Payments
- [ ] A payment form submits over an unencrypted http:// connection
- [ ] Card details are collected by your own page, not a hosted payment field
- [ ] Payment test mode key
- [ ] Working discount codes are compiled into the browser bundle
- [ ] A PayPal order is priced in the browser
- [ ] Both live and test Stripe keys are shipped to the browser
- [ ] Checkout price is submitted from a hidden form field
- [ ] Checkout request sends an amount built in the browser

## Email deliverability & anti-spoofing
- [ ] More than one DMARC record is published
- [ ] Multiple SPF records published
- [ ] MX record points to a hostname with no address
- [ ] SPF explicitly authorizes any server to send mail
- [ ] BIMI logo could not be fetched
- [ ] BIMI record has no usable logo location
- [ ] DKIM key is published but revoked
- [ ] DKIM public key is not valid base64
- [ ] DMARC record has no usable policy
- [ ] Domain sends email but cannot receive it
- [ ] Email configuration incomplete
- [ ] MTA-STS policy file could not be fetched
- [ ] MTA-STS policy file is malformed
- [ ] No DKIM signature configured
- [ ] No DMARC record found
- [ ] No SPF record found
- [ ] SPF record contains an unrecognized term
- [ ] SPF record exceeds the 10 DNS-lookup limit
- [ ] SPF record says nothing about servers it does not list
- [ ] BIMI logo does not look like an SVG
- [ ] DKIM record declares an unrecognized key type
- [ ] DMARC has no aggregate reporting address
- [ ] DMARC policy applies to only part of your mail (pct < 100)
- [ ] DMARC policy is set to 'none'
- [ ] DMARC reports are sent to a domain that has not authorised them
- [ ] DMARC treats subdomains more leniently than the domain itself
- [ ] Eligible for BIMI but not configured
- [ ] Eligible for MTA-STS but not configured
- [ ] MX host has no reverse DNS (PTR) record

## Launch readiness
- [ ] A development build is being served to real visitors
- [ ] Missing Basic HTML Metadata
- [ ] Page says it does not exist but returns a success status
- [ ] Placeholder template content is still live on the site
- [ ] Production build points at localhost
- [ ] Production build references a staging or preview environment
- [ ] Shipped JavaScript logs sensitive data to the browser console
- [ ] Unedited Scaffold Branding
- [ ] Missing Proper 404 Status Code
- [ ] Missing robots.txt
- [ ] No sitemap is discoverable
- [ ] The site has no browser-tab icon

## SEO & AI visibility
- [ ] Your robots.txt tells search engines to stay out of the whole site
- [ ] Your site tells search engines not to index it
- [ ] AI assistants are blocked from reading your site
- [ ] Canonical URL points to a different domain
- [ ] Page declares more than one canonical URL
- [ ] Page title tag is empty
- [ ] Sitemap is published but lists no URLs
- [ ] Sitemap is served but cannot be parsed
- [ ] Sub-page canonicalises to the homepage
- [ ] Your CDN blocks AI crawlers before they reach your site
- [ ] Article does not declare its author or publication date
- [ ] Meta description is long enough to be truncated
- [ ] No canonical URL declared
- [ ] No mobile viewport declared
- [ ] No social preview image
- [ ] No structured data found
- [ ] Page has no H1 heading
- [ ] Page title is long enough to be truncated in search results
- [ ] Sitemap has not been updated in over a year

## More checks
- [ ] Exposed git credentials file
- [ ] Exposed SQL database dump
- [ ] Subdomain takeover
- [ ] A redirect parameter sends visitors to any URL it is given
- [ ] A response sets a session cookie and allows shared caching
- [ ] A sign-in form puts the password in the URL
- [ ] A sign-in form sends passwords over an unencrypted connection
- [ ] AI assistant response text left in the page
- [ ] Broken internal link
- [ ] Exposed config file containing credentials
- [ ] Exposed internal/monitoring endpoint
- [ ] Exposed version-control directory
- [ ] Legal page placeholder
- [ ] Pricing contradiction
- [ ] The contact address on your site cannot receive mail
- [ ] Unrendered template variable on the page
- [ ] A device-fingerprinting script is present
- [ ] A form collecting personal data submits via GET
- [ ] A JavaScript bundle is large enough to make the page feel slow
- [ ] A placeholder contact address is published on the site
- [ ] An image is large enough to be slowing the page down
- [ ] Dead link target
- [ ] Embedded frames have no title
- [ ] Form fields have no associated label
- [ ] Image buttons have no text alternative
- [ ] Images have no text alternative
- [ ] Insecure (http) resources loaded on a secure page
- [ ] No privacy policy link found
- [ ] Real visitors wait too long to see your main content
- [ ] Session-replay or behaviour-recording script is present
- [ ] Several pages share the same title
- [ ] The page does not declare a language
- [ ] The page is served without compression
- [ ] The page is slow to respond when people tap or click
- [ ] The page moves under people while it loads
- [ ] The page prevents pinch-to-zoom
- [ ] The page refreshes or redirects itself on a timer
- [ ] Third party script missing SRI
- [ ] Tracking cookie is set before the consent banner can be answered
- [ ] Tracking cookie is set on the first response
- [ ] Unremoved builder attribution
- [ ] Your API documentation is publicly reachable
- [ ] A stylesheet loads without an integrity check
- [ ] Analytics or advertising tracker loads without a detected consent step
- [ ] Build assets are served without caching
- [ ] Fonts are loaded from Google's servers
- [ ] Heading levels are skipped
- [ ] Headings have no text
- [ ] Images have no width and height
- [ ] No terms of service link found
- [ ] Outbound links lead to pages that are gone
- [ ] Several pages share the same meta description
- [ ] Several scripts block the page from rendering
- [ ] Stale copyright year
- [ ] The page is reached through a chain of redirects
- [ ] Third-party content is embedded on the page
- [ ] Your privacy policy does not appear to name a service the site uses
- [ ] Your privacy policy gives no way to contact you
- [ ] Your app calls routes that cost money per request

01Secrets & API keys26

The most common and most damaging mistake in AI-built apps: a real credential shipped into client JavaScript or a committed .env served publicly. Treat anything found here as already compromised — rotate it, then move it server-side.

02AI coding-tool exposure9

Files and keys AI builders leave behind — tool config and instruction files served to the public, and provider keys inlined into the browser bundle. They map your stack for an attacker and hand over working credentials.

03Database & backend access7

Whether your Supabase or Firebase backend actually enforces access control. A missing Row Level Security policy or a public storage bucket means anyone with the public key in your JavaScript can read — or change — your data. Building on Supabase? See the focused Supabase checklist. Supabase security checklist →

04HTTPS & TLS4

That connections are encrypted, modern and forced. Deprecated TLS versions and a missing HTTP→HTTPS redirect leave traffic open to downgrade and interception.

05Security headers12

The response headers browsers rely on to contain attacks — Content-Security-Policy, HSTS, X-Content-Type-Options and more. Rarely exploitable alone, but their absence weakens every other defence.

06Cookies & sessions4

That session cookies carry the flags keeping them out of JavaScript and off unencrypted connections. Missing HttpOnly, Secure or SameSite turns an XSS or CSRF bug into a full session takeover.

07Information disclosure9

Internal files and endpoints that should never be reachable in production — an exposed .git directory or source map, a debug endpoint, a stack trace, a directory listing, or CORS that trusts any origin. Each hands an attacker reconnaissance or data.

08Payments8

That a live site charges through live payment credentials. A test-mode Stripe key on production means real checkouts look like they work but silently collect no money.

09Email deliverability & anti-spoofing29

The DNS records that let your transactional email arrive and stop others forging your domain — SPF, DKIM, DMARC and MX. Missing records send password resets to spam and let anyone phish your users from your own address.

10Launch readiness12

The basics that signal a finished product rather than a preview: a real 404 page, a robots.txt and sitemap, page metadata, and no leftover starter-template branding.

11SEO & AI visibility19

Whether search engines and AI assistants can reach your pages at all — a stray noindex, a rule blocking AI crawlers, a canonical pointing at the wrong page, or a sitemap that no longer parses can each make a finished site invisible.

12More checks59

Additional checks UseShipReady runs.

Check your site against the whole list

UseShipReady runs every check here across up to ten pages of your live site and reports what it finds, with a paste-ready fix for each. Free, no signup.