Before you ship to real users
AI App Production
Readiness Checklist
The 50-point checklist for taking an AI-generated app from demo to production. Cover auth, secrets, database access, billing, logging, tests, governance, and rollback before real users arrive.
Why this checklist exists
AI app builders — Lovable, Bolt, v0, Cursor, Claude Code — generate functional prototypes fast. They do not generate threat models, test plans, or deployment contracts. This checklist is the gap between "it works in my browser" and "it survives contact with real users."
How to use it
Work through it category by category before your first production deployment. If you cannot check an item, that is a conscious decision you are deferring — document it in your CHANGELOG. Do not skip items without writing down why.
What this does not cover
Physical security, network perimeter controls, and formal compliance audits (SOC 2, ISO 27001) are out of scope. This checklist addresses the application-layer controls that are the prerequisite for any of those programs.
Authentication & Sessions
7 itemsAuth middleware applied to all protected routes — not just the ones you remembered
Review every route file. Auth applied to /dashboard but not /api/user is a common miss.
Session revocation implemented — logout actually invalidates sessions server-side
Deleting a cookie client-side without invalidating the server-side session token is not logout.
JWT algorithm allowlisted (HS256 or RS256 only, never 'none' or dynamic)
Libraries that accept algorithm from the JWT header are vulnerable to alg:none bypass. Severity: critical.
MFA available for high-privilege actions (billing changes, user deletions, role escalations)
Does not need to be enforced for all users — required for admin-level operations.
Password reset flow does not leak account existence
Both 'email found' and 'email not found' paths should return identical responses and timing.
OAuth redirect URI allowlisted explicitly — no wildcard or path-prefix matching
Wildcard redirect URIs allow open redirect attacks. Each URI must be exact-match.
Session tokens use appropriate max-age and HttpOnly + Secure + SameSite flags
HttpOnly prevents XSS token theft. Secure prevents transmission over HTTP. SameSite=Strict prevents CSRF.
Secrets & Environment
6 itemsAll secrets in environment variables, not source code or config files
Search git history for common patterns: sk_live_, AKIA, password =, token =.
Secrets rotation plan documented — who does it, how, and on what schedule
A secret that has never been rotated is a secret that has probably leaked.
.env file in .gitignore — and git history audited for any prior commit
Use git log --all --full-history -- '**/.env' to check history.
Webhook secrets verified on every incoming request, not just on first setup
Stripe-Signature header must be validated with constructEvent() on every webhook POST.
API keys scoped to minimum required permissions
A Stripe key used only for checkout does not need refund or dispute permissions.
Separate secrets for dev, staging, and production environments
Using production Stripe keys in development is a compliance and financial risk.
Database & Data Access
6 itemsRow-level security (RLS) policies on all tables with multi-tenant data
In multi-tenant apps without RLS, every query must manually filter by tenant_id. Both approaches require explicit enforcement.
Parameterized queries everywhere — no string concatenation in SQL
db.query('SELECT * FROM users WHERE email = ' + email) is a SQL injection. No exceptions.
Database errors sanitized before reaching API responses
SQLite, Postgres, and D1 error messages often include table names, column names, and constraint details.
Migrations are reversible with a documented rollback path
DOWN migration or manual rollback script for every schema change. Test it before production.
No direct database access from client-side code
Even if your DB client 'works' from the browser, it means your credentials are in the bundle.
Backup strategy documented and tested — restore procedure verified at least once
An untested backup is not a backup. Restore from backup to a staging environment to confirm.
API & Input Validation
6 itemsInput validation on all incoming request bodies — schema or runtime type checking
Zod, Valibot, or equivalent. Validate shape, type, length, and allowed values — not just presence.
Rate limiting on authentication endpoints (login, password reset, 2FA verify)
Unprotected login endpoints allow credential stuffing at scale. 5–10 requests per minute per IP is a reasonable default.
Rate limiting on expensive operations (AI calls, file uploads, email sends)
A single user triggering 10,000 AI API calls will cost you money before you notice.
CORS configured explicitly — not wildcard (*) in production
Allow-Origin: * on an authenticated API defeats cookie-based CSRF protections entirely.
Request size limits enforced — especially on file upload and JSON body endpoints
Without limits, a single 1GB POST can exhaust your worker's memory budget.
Content-Type validation on file uploads — MIME type checked server-side
Client-specified content type is trivially forged. Inspect magic bytes for file type verification.
Billing & Payments
5 itemsStripe webhook signature verified (not just parsing the JSON payload)
Stripe.webhooks.constructEvent() must be called with raw body and STRIPE_WEBHOOK_SECRET before any processing.
Webhook handler is idempotent — safe to replay any event
Stripe retries failed webhooks. INSERT OR IGNORE or idempotency key on event.id prevents double-billing.
Failed payment handling does not leave database in inconsistent state
If the webhook fails halfway through updating subscription state, is the tenant in limbo? Use transactions.
Tier gating enforced server-side — not just in the UI
Checking the user's tier only in a React component means any API client bypasses the gate entirely.
Checkout flow has server-side pre-flight check for existing active subscriptions
Double-checkout creates two active subscriptions in Stripe. Check before creating a Checkout Session.
Logging & Observability
5 itemsError logging to a monitoring service — not just console.log or wrangler tail
console.log is not persistent. Sentry, Datadog, or structured D1/KV logging survives process restarts.
No PII in logs — email, phone, SSN, payment data scrubbed before logging
Log user IDs and tenant IDs, not email addresses. A log file is not a GDPR-compliant data store.
Request tracing enabled — trace IDs propagated through all downstream calls
Without trace IDs, debugging a production failure means correlating timestamps across disconnected logs.
Alert on anomalous error rates — not just on downtime
A 20% error rate on /api/users that doesn't take the service fully down will not trigger an uptime monitor.
Health check endpoint available and returns build hash or deploy timestamp
GET /health → {"status":"ok","build":"abc123"}. Useful for confirming which version is deployed.
Error Handling
4 itemsGeneric error messages to users in production — no stack traces in API responses
Stack traces reveal file paths, library versions, and internal variable names to attackers.
All async operations have error boundaries or catch blocks
An unhandled promise rejection in a Cloudflare Worker crashes the request. Every await needs try/catch.
Unhandled promise rejections logged and alerted on
addEventListener('unhandledrejection') in the worker global catches escaping rejections.
Graceful degradation on dependency failures — external APIs, DB, KV
If your KV session store is unavailable, should all users get 500? Or can you degrade gracefully to read-only mode?
Testing
5 itemsAuth flow tests: login, logout, session expiry, protected route rejection
The most important tests to have. Auth regressions are silent until a user reports data they shouldn't see.
Multi-tenant isolation test: confirm tenant A cannot read tenant B's data
Seed two tenants, cross-query from tenant A, assert 404 not 200. Run this test on every schema change.
Billing test: checkout, webhook receipt, tier upgrade, failed payment
Use Stripe's test webhook CLI to replay real webhook payloads in your test environment.
Rate limit test: confirm limits are enforced at the specified threshold
Don't just test that rate limiting exists — test that it fires at the right count and resets correctly.
Coverage target documented and measured in CI — not just locally
A coverage gate that only runs on your laptop is not a coverage gate.
Governance
4 itemsThreat model exists and has been reviewed — even informally
A one-page STRIDE analysis for your specific architecture is better than generic security advice from a blog post.
ADRs document key architectural decisions — auth strategy, data isolation approach, third-party dependencies
ADRs prevent the next developer (or AI agent) from undoing decisions that have non-obvious reasons.
Architectural constraints documented for AI coding agents in machine-readable form
A .ai/constraints.yaml file read by Cursor or Claude Code prevents agents from bypassing auth or adding insecure patterns.
CHANGELOG maintained for significant changes — what shipped, when, and what it changed
A CHANGELOG is not a luxury. It is how you debug production incidents that correlate with recent deploys.
Deployment & Rollback
5 itemsRollback plan documented for every deployment — not improvised in an outage
Know which wrangler rollback command, git revert, or database migration to run before you deploy.
Feature flags in place for high-risk changes — especially billing and auth changes
A feature flag lets you disable a broken feature without a full rollback.
Database migrations tested on staging before production — not skipped
A migration that drops a column and adds a new one is a multi-step operation that can fail midway.
CDN and cache invalidation strategy documented — stale assets after deploy are a user-visible bug
Deploy a new API contract, forget to bust the CDN cache, watch old JS call new endpoints with wrong payloads.
Zero-downtime deployment verified — especially for schema migrations that run while traffic is live
Adding a NOT NULL column without a default to a live table will fail every inflight request during migration.
Field findings
What teams most commonly miss
These four gaps appear repeatedly in AI-generated SaaS apps. All four are non-obvious at build time and visible only when an attacker looks — or when your first enterprise prospect runs a security review.
Webhook signature not verified
The Stripe webhook handler parses the event body as JSON and acts on it — without calling constructEvent() with the webhook secret. Any attacker can POST a forged invoice.paid or customer.subscription.updated event and trigger a free tier upgrade. This is the single most common billing security gap in AI-generated apps.
Missing tenant_id predicate in D1 queries
A multi-tenant app with a single shared D1 database and no RLS must filter every query by tenant_id. A single SELECT * FROM users WHERE id = ? without AND tenant_id = ? means any authenticated user can read any other tenant's data by guessing or enumerating UUIDs. AI builders generate the CRUD; they do not generate the isolation predicate.
Tier gate enforced only in the UI
The Pro feature check is a conditional in a React component: if (user.tier === 'pro') return <ProFeature />. The API endpoint behind the feature has no server-side tier check. A free user with the browser dev tools can call the endpoint directly. Gating only in the UI means the gate does not exist.
Logout does not invalidate the session server-side
The logout handler deletes the session cookie client-side. The session token in KV is never invalidated. The cookie is gone — but anyone who captured the token value (via XSS, log file, or shoulder-surfing) can still authenticate with it for however long the TTL lasts. Real revocation requires deleting the server-side session record.
The governance layer
Stackbilder generates the threat model, ADRs, and test plan that underpin this checklist.
The Governance section of this checklist — threat model, ADRs, architectural constraints — is generated automatically for every scaffold. The Testing section maps directly to the test plan. The Security items trace back to the STRIDE threat model.
Start free. Full governance suite with every scaffold. Cloudflare Workers scaffold with D1, KV, auth middleware, and Stripe webhook verification wired correctly from the first file.
What ships with every scaffold
Questions about this checklist
How should I use this checklist?
Work through it category by category before your first production deployment with real users or real money. Treat it as a gate, not a guideline — if you cannot check an item, that is a decision you are consciously deferring, not an oversight. Document what you are skipping and why. The Governance section is the right place to record those decisions.
What do teams most commonly miss before shipping?
In order of frequency: (1) Stripe webhook signature verification — webhooks parsed without checking the signature allow forged billing events; (2) cross-tenant data access — missing tenant_id predicates in multi-tenant queries; (3) server-side tier gating — billing tier enforced only in the UI; (4) session revocation — logout does not invalidate the session token server-side. All four are non-obvious at build time and appear invisible until exploited.
Does Stackbilder automate all of this?
Stackbilder generates the governance layer — threat model, ADRs, test plan, and architectural constraints — that covers the Governance section and directly informs the Testing and Security items. It does not replace your deployment pipeline, secret rotation tooling, or observability stack. The generated test plan tells you which tests to write; you still write and run them. The generated threat model identifies the risks; you still implement the mitigations.
Does passing this checklist mean I am SOC 2 compliant?
No. SOC 2 requires an independent auditor to review your controls over a trust service period — it cannot be achieved by self-attestation. This checklist covers the technical controls that are prerequisites for a SOC 2 engagement. Without them, an audit surfaces them as gaps immediately. Completing this checklist puts you in a defensible starting position. For teams preparing for formal compliance, our consulting offering includes bespoke security review engagements.
Related pages