Launch playbook
Evidence-based pre-launch security playbook for MVPs and SaaS. Scans the real repo for open DBs/RLS gaps, IDOR, secret leaks, auth enumeration, AI cost abuse and prompt injection, uploads/SSRF, rate limits, CORS, and unsafe production config. Outputs SHIP / SHIP WITH FIXES / DO NOT SHIP with file:line proof. Use when the user says launch-playbook, launch playbook, pre-launch security, secure my launch, is this safe to ship, security checklist, audit before deploy, RLS check, vibe coding security, or runs /launch-playbook or /secure-launch.From its SKILL.md
npx -y skills add 0xkaizoku/launch-playbookAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 14 days oldThe repository was created 14 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
14.1 KB, ~3.5k tokens by cl100k_base, as published. Nobody here has run it
launch-playbook — Pre-Launch Security Playbook
Run a time-boxed, evidence-based security playbook before public launch.
Agent-agnostic procedure. Same steps on Claude Code, Gemini CLI, OpenAI Codex/ChatGPT agents, Cursor, Windsurf, Grok, or a human with a terminal. Loading differs by host (see README); execution does not.
| Goal | Baseline that stops the failures fast-shipped apps actually hit |
| Not a goal | Enterprise audit, pentest cert, HIPAA/PCI/SOC2 |
| Budget | ~30 minutes of agent work; depth over theater |
| Rule | No finding without path/evidence. No “might be vulnerable” without a reason. |
Load when needed (paths relative to this skill folder):
references/checklist.md— human checklistreferences/scan-playbook.md— commands + secret patternsreferences/ai-prompts.md— optional deep-dive prompts
If invoked without skill auto-load: user may attach or @ this file. Follow it fully anyway.
Modes
| User intent | Mode |
|---|---|
| Default / “audit” / “checklist” | Report only |
| “Fix it” / “make it shippable” | Remediate then re-score |
| “Quick” / “10 min” | Fast path: secrets → access control → paid APIs → auth → stop |
Do not rotate production secrets, wipe data, or force-enable RLS that locks out prod without explicit confirmation.
Phase 0 — Detect stack (2 min, mandatory)
Inspect lockfiles, config, and imports. Record in the report:
Framework: Next.js | Remix | SvelteKit | Vite SPA | other
Auth: Supabase Auth | Clerk | Auth.js/NextAuth | Lucia | Firebase | custom | none
DB: Supabase | Firebase | Prisma+Postgres | Mongo | Drizzle | other | none
Hosting signals: Vercel | Cloudflare | Fly | Railway | unknown
Paid APIs: OpenAI | Anthropic | xAI | Stripe | Resend | Twilio | other
Client data access: direct Supabase/Firebase from browser? yes/no
AI features: chat | agents/tools | image | embeddings | none
Uploads: yes/no Payments: yes/no Multi-tenant: yes/no
Branching: Skip N/A sections. Map Supabase RLS checks to Firebase Rules / server-only Prisma authz. Never pretend a Next-only check applies to a static SPA.
Phase 1 — Mandatory scans (run these, do not “reason about” secrets)
Use ripgrep/grep tools available. Prefer references/scan-playbook.md. Minimum:
1.1 Secret & key exposure
Search source (exclude node_modules, .git, lockfiles, dist / .next / build if noisy):
| Pattern family | Examples |
|---|---|
| Cloud LLM | sk- (OpenAI), sk-ant-, xai-, gsk_ (Groq), AIza (Google) |
| Stripe | sk_live, sk_test, rk_live, whsec_ |
| Supabase | service_role, long JWT-looking eyJ... in client files |
| AWS | AKIA + secret key patterns, AWS_SECRET |
| GitHub | ghp_, github_pat_, gho_, ghu_ |
| Private keys | BEGIN PRIVATE KEY, BEGIN RSA PRIVATE KEY, BEGIN OPENSSH |
| Slack/Discord | xoxb-, xoxp-, xoxa-, Discord bot tokens |
| Generic | api[_-]?key, secret[_-]?key, password\s*= in non-test code |
Also check:
.env,.env.local,.env.productiontracked by git?- Client env misuse:
NEXT_PUBLIC_*/VITE_*/EXPO_PUBLIC_*/PUBLIC_*holding secrets - README/docs/screenshots with real keys
service_roleorDATABASE_URLimported from modules that also run in the browser- CI/CD config and committed Terraform/Pulumi secrets
Classify each hit: public-by-design | secret-exposed | false positive.
secret-exposed in client or git → DO NOT SHIP until rotated + removed from tree (history purge is a follow-up; rotation is immediate).
1.2 Dangerous code patterns
Search and open matches:
| Risk | Patterns / files |
|---|---|
| XSS | dangerouslySetInnerHTML, {@html, v-html, unescaped markdown→HTML |
| SQL concat | string-built queries, raw $queryRaw / $executeRaw with user input |
| Command inject | exec(, execSync(, spawn( with user-controlled strings |
| SSRF | fetch(user, axios.get(req., webhook/URL fields without allowlist |
| Open redirect | redirect(, window.location = user param without allowlist |
| Admin naked | /admin, /debug, /api/test, swagger/openapi in prod without auth |
| Mass assign | spreading req.body straight into Prisma data: / Supabase update |
| Debug prod | missing production guards, console.log of tokens, source maps forced on |
1.3 Dependency & config
- Lockfile present? (
package-lock.json/pnpm-lock.yaml/yarn.lock/bun.lock) - Run
npm audit --omit=dev(or pnpm/yarn equivalent) when Node project; note critical/high only .gitignoreincludes.env*(and secrets are not force-added)- Public storage: Supabase storage policies, S3 public ACLs, unauthenticated upload routes
Phase 2 — Access control & data plane
2.1 Database / backend access (highest failure rate)
Supabase
- RLS enabled on every table with user/tenant data
- Policies scope by
auth.uid()or org membership — notusing (true)for private data -
WITH CHECKon inserts/updates (not onlyUSING) - No browser use of service role
- Migrations / SQL in repo match “we have RLS” claims; empty policy list on private tables is FAIL
Firebase
- Rules default-deny; read/write gated by
auth.uid+ resource ownership - No open
allow read, write: if true(orif request.auth != nullalone on private docs)
Prisma / Drizzle / server DB
- No
DATABASE_URLin client bundle - Every query that touches user rows filters by session user/org
- No “getById” without ownership check (classic IDOR)
IDOR / multi-tenant
- Routes like
/api/orders/[id],/api/docs/[id]verify owner or membership, not just “is logged in” - Numeric/sequential IDs: confirm server rejects cross-user access in code
- Team/org features: membership checked on mutate, not only on UI hide
- Realtime / subscriptions / storage paths also scoped (not only REST handlers)
False confidence: RLS enabled with wrong policies is worse than obvious “no RLS” (silent “secure”). Flag always-true policies for authenticated role on sensitive tables.
2.2 Validation & errors
- Writes validated on the server (Zod/Valibot in Server Actions / API / Edge) — client-only validation = FAIL/WARN
- Length limits on text fields; file size/MIME if uploads
- Production errors generic; no SQL/stack/
PrismaClientKnownRequestErrorto clients - Full user rows (password hash, tokens, internal flags) not returned to client
2.3 Uploads & storage (if present)
- Auth required unless intentionally public
- Size + type allowlist; no SVG-as-image without sanitization if served inline
- Stored outside web root or via signed URLs
- Path not user-controlled (
../../) - Bucket not world-readable for private user content
- Filename not used as executable path; content-type not fully trusted from client
2.4 SSRF & outbound fetch (if present)
- User-supplied URLs allowlisted (scheme + host) or blocked for link-local / metadata IPs (
169.254.169.254,metadata.google.internal,127.0.0.0/8, private RFC1918 ranges) - No blind
fetch(req.body.url)for “preview” / “import” features without controls - Redirect-following considered (open redirect to internal host)
Phase 3 — Auth & sessions
3.1 Failure-case design (code + copy review)
| Test | Secure | Insecure |
|---|---|---|
| Bad password ×5 | Generic error; rate limit / lockout | “Wrong password for this email”; no throttle |
| Reset unknown email | Same response as known | “Email not found” |
| Verify/magic link twice | Expired/used message | 500 / infinite re-auth bugs |
| Signup existing email | Non-enumerating message (or intentional product choice documented) | Clear “already registered” with no rate limit |
Also:
- Session cookies:
HttpOnly,Secure,SameSite(or provider defaults verified) - Logout invalidates server session when applicable
- Password reset tokens single-use / short TTL if custom
- OAuth: redirect URI allowlist; no open
redirectTo/callbackUrl/nextfrom query - Email verification required if app holds sensitive data (else WARN)
- CSRF: cookie-session mutations protected (SameSite + origin checks / framework CSRF)
3.2 Authorization ≠ authentication
Logged-in is not enough. Admin/role checks must be server-side on privileged routes. Client-only role flags in localStorage/JWT claims without server verify = FAIL.
Phase 4 — AI features (skip if none)
Fast-shipped AI apps die on cost and prompt injection, not only key leaks.
- Model calls only on server; keys never in client
- Auth required for expensive routes (or hard public quota + CAPTCHA)
- Rate limit + per-user daily/monthly cap on generation endpoints
- Provider dashboard hard cap + billing alert recommended in report
- User content treated as untrusted: not concatenated into system prompts as instructions
- Tool/agent calling: tools cannot exfiltrate secrets, run shell, or hit internal URLs without allowlist
- Output rendering safe (markdown XSS / HTML)
- No logging full prompts that contain user PII to third-party log drains without need
- Streaming endpoints cannot be invoked anonymously in a tight loop without limits
- Max tokens / max steps bounded on agent loops
DO NOT SHIP if an unauthenticated endpoint can burn paid tokens at scale.
Phase 5 — Abuse, cost, and edge
- Rate limits: auth routes + any paid/third-party route
- CAPTCHA/bot protection on public signup/contact/waitlist (Turnstile, hCaptcha, etc.)
- CORS: explicit origins in prod; not
*with credentials on private APIs - Webhooks (Stripe etc.): signature verify; reject unsigned; idempotency considered
- Body size limits on APIs
- Security headers where framework allows (baseline CSP,
X-Content-Type-Options: nosniff, frame controls if sensitive UI) - Cron/admin secrets not guessable query tokens
- Feature flags / debug routes disabled or auth-gated in production
Phase 6 — Legal / product floor (light, code-aware)
- Privacy policy route or external link exists if you collect email/PII
- Password hashing if custom auth (
bcrypt/argon2/scrypt— not plain, not reversible “encrypt password”) - No debug scripts that export users or dump production data into personal accounts
- Data map one-liner in report: where PII lives + processors (auth, email, analytics, AI)
Keep legal notes short and product-relevant. If AI-generated code or third-party licenses matter for this ship, one line: human review + license hygiene. Do not expand into caselaw.
Phase 7 — Verdict
Severity → verdict
| Severity | Examples | Effect |
|---|---|---|
| S0 Blocker | Secret in client/git; no RLS/rules on private data; unauth paid AI burn; public service_role | DO NOT SHIP |
| S1 High | Clear IDOR; SSRF; stored XSS; admin open; webhook unsigned with money impact | DO NOT SHIP if exploitable without auth or affects all tenants/users |
| S2 Medium | Auth enumeration; missing rate limit on auth; client-only validation; no CAPTCHA on spammy forms | SHIP WITH FIXES |
| S3 Low | Missing CSP; verbose logs server-only; dependency moderate noise | WARN; ship ok |
SHIP only if zero S0/S1 open.
If S1 is authenticated-only and single-tenant scoped, still default to DO NOT SHIP unless the user explicitly accepts residual risk in writing in the report.
Report format (always)
# Launch Playbook Report
**Repo:** …
**Stack:** … (from Phase 0)
**Mode:** report | remediate | fast
**Verdict:** SHIP | SHIP WITH FIXES | DO NOT SHIP
## Scorecard
| Phase | Area | Status | Highest severity |
|-------|------|--------|------------------|
| 1 | Secrets & dangerous patterns | PASS/FAIL/WARN/N/A | S0–S3 |
| 2 | Access control / IDOR / uploads | | |
| 3 | Auth & sessions | | |
| 4 | AI features | | |
| 5 | Abuse / cost / edge | | |
| 6 | Legal / product floor | | |
## Blockers (S0–S1)
### B1 — title
- **Evidence:** `path:line` — snippet or fact
- **Impact:** …
- **Fix:** concrete change (code/SQL/config)
## Fixes before / within 48h (S2)
…
## Passed (evidence-backed)
- …
## Scans run
- commands + outcome summary
## Out of scope / N/A
- …
Keep the report short. Prefer 5 real blockers over 40 theoretical essays.
Remediate mode
Order of operations:
- Remove/move secrets; tell user to rotate (do not print full secrets in chat)
- Access control (RLS/rules/ownership checks)
- Close unauth paid endpoints (auth + rate limit + cap)
- Fix XSS/SSRF/open redirect with minimal patches
- Generic errors + server validation on hottest write paths
- Re-run Phase 1 scans + re-score
Anti-slop rules (mandatory)
- Evidence or delete the finding. No “consider adding…” without a gap you observed.
- Do not dump
references/ai-prompts.mdas the whole audit. Use those prompts only as optional depth after mandatory scans. - Do not mark PASS because the README says “secure” or “read-only.”
- Map to stack. Wrong-stack advice is a failed audit.
- Prioritize money and data loss over header perfectionism.
- Never claim “pentest complete” or “compliant.”
- If the app is static marketing with no backend: short report, mostly N/A, still scan for leaked keys in repo.
What ships with it: 5 files
22.2 KB alongside SKILL.md
references/
- ai-prompts.md2.3 KB
- checklist.md3.3 KB
- scan-playbook.md5.7 KB
Gives 0 of the 12 instructions most ship operate skills give in ~3.5k tokens
Counted across 779 of the 1,178 authors here whose files we hold, read 2026-08-07
- Document a rollback plan before deploymentin 41 of 779, across 22 files
- Update the changelogin 21 of 779, across 19 files
- Run the test suitein 20 of 779
- Create an annotated git tagin 20 of 779
- Clean up feature flags after full rolloutin 18 of 779, across 10 files
- Verify deployment health after launchin 18 of 779, across 10 files
- Test both feature flag statesin 17 of 779, across 9 files
- Verify the working tree is cleanin 17 of 779
- Make database migrations backward-compatiblein 16 of 779, across 8 files
- Set up error monitoring before launchin 15 of 779, across 7 files
- Monitor metrics at each rollout stagein 14 of 779, across 5 files
- Create a GitHub releasein 14 of 779
Said here and by no other author read
- Inspect lockfiles and config to detect stack
- Run mandatory secret exposure scans
- Search source for dangerous code patterns
- Verify database access control policies
- Validate server-side input and error handling
- Review authentication and session failure cases
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.