checklists / launch-ready

Launch Ready API security Checklist for client portal: Ready for app review in B2B service businesses?.

For a B2B service business, 'ready for app review' means the portal is safe to expose to real clients, stable enough to support onboarding and billing...

What "ready" means for a B2B client portal

For a B2B service business, "ready for app review" means the portal is safe to expose to real clients, stable enough to support onboarding and billing workflows, and locked down enough that one bad request cannot leak another customer's data.

I would call it ready only if a founder can answer yes to all of these:

  • Clients can sign in, reset passwords, and access only their own records.
  • API routes reject unauthorized access, malformed input, and brute-force attempts.
  • Secrets are not in the repo, browser bundle, or deployment logs.
  • Email deliverability is working with SPF, DKIM, and DMARC passing.
  • The domain, SSL, redirects, subdomains, and Cloudflare are configured correctly.
  • Monitoring will alert you before customers do.
  • The app review team can test the product without hitting broken flows, 500s, or blocked assets.

For this kind of product, "looks live" is not enough. If the portal has a weak auth boundary or broken environment setup, the business risk is direct: failed app review, delayed launch, support tickets from clients who cannot log in, and exposed customer data.

It covers domain, email, Cloudflare, SSL, deployment, secrets, monitoring, and handover so the portal is actually production-safe.

Quick Scorecard

| Check | Pass criteria | Why it matters | What breaks if it fails | |---|---|---|---| | Auth boundary | Users can only access their own org data | Prevents cross-customer data leaks | Data exposure and trust loss | | Session handling | Cookies are secure and expire correctly | Stops session theft and replay | Account takeover | | Input validation | All API inputs are validated server-side | Blocks injection and bad writes | Broken records and exploit paths | | Rate limiting | Login and sensitive APIs are rate limited | Reduces brute force and abuse | Credential stuffing and downtime | | Secrets handling | Zero secrets in repo or client bundle | Protects keys and tokens | Service compromise | | CORS policy | Only approved origins can call APIs | Prevents unwanted browser access | Data exfiltration from browsers | | Email auth | SPF/DKIM/DMARC all pass | Improves deliverability and trust | Emails land in spam or fail outright | | SSL + redirects | One canonical HTTPS domain works everywhere | Avoids mixed content and duplicate URLs | App review failures and SEO issues | | Monitoring | Uptime checks + error alerts active | Finds outages fast | Slow incident response | | Performance baseline | p95 API under 500ms on core actions | Keeps portal usable under load | Slow onboarding and support load |

The Checks I Would Run First

1. Authz on every object route

Signal: A user can change an ID in the URL or request body and see another client's record. That is a hard fail.

Tool or method: I test this with two accounts across list, detail, update, export, invoice, file download, and admin endpoints. I also inspect whether authorization happens at the route handler level or only in the UI.

Fix path: Enforce server-side authorization on every request using org-scoped queries. Never trust client-provided org_id or user_id alone. If this is multi-tenant SaaS behavior inside a service portal, I would add explicit ownership checks before any read or write.

2. Secret exposure scan

Signal: API keys appear in Git history, frontend env vars shipped to the browser, deployment logs, or preview URLs.

Tool or method: I run secret scanning across repo history plus a quick audit of build output and runtime config. I also check whether any third-party keys are public-facing by design.

Fix path: Rotate exposed secrets immediately. Move sensitive values to server-only environment variables. Add pre-commit secret scanning so this does not happen again. If a key was exposed publicly even once, I treat it as compromised.

3. Session and cookie security

Signal: Cookies lack HttpOnly or Secure flags, sessions never expire properly, or password reset flows are weak.

Tool or method: I inspect auth headers in browser devtools and verify cookie attributes on login/logout/reset flows. I also test idle timeout and forced logout after password change.

Fix path: Set Secure, HttpOnly, SameSite where appropriate. Use short-lived sessions with refresh logic if needed. Make password resets single-use and time-limited. For B2B portals that handle invoices or contracts, I prefer conservative session expiry over convenience.

4. API abuse controls

Signal: Login endpoints accept unlimited attempts; expensive endpoints can be spammed; file upload routes have no size/type limits.

Tool or method: I send repeated requests with a simple script and watch for lockouts or throttling behavior. I also check whether error messages reveal too much about users or internal state.

Fix path: Add rate limits per IP plus per account for login and password reset flows. Put size limits on uploads. Return generic auth errors. Add request validation before hitting downstream services so bad traffic dies early.

5. CORS plus browser exposure review

Signal: CORS allows wildcard origins with credentials enabled; frontend code calls private APIs directly when it should not; tokens live in localStorage without need.

Tool or method: I inspect network calls from the browser and test cross-origin requests from a hostile origin. I also confirm whether any admin-only endpoints are reachable from public pages.

Fix path: Restrict CORS to known domains only. Avoid wildcard origins when credentials are involved. Prefer HttpOnly cookies over localStorage for session material when possible. Keep privileged operations behind server-side checks even if the UI hides them.

6. Deployment health under real DNS

Signal: SSL works on one hostname but not others; redirects loop; subdomains break; email bounces; Cloudflare caches something it should not cache.

Tool or method: I test apex domain vs www vs subdomains vs preview URLs from multiple networks. I verify DNS propagation status plus certificate coverage plus caching headers on authenticated pages.

Fix path: Standardize one canonical domain with clean redirects. Put authenticated pages behind no-store rules unless there is a clear caching strategy. Confirm Cloudflare does not cache private API responses by accident.

## Example email DNS target state
SPF: pass
DKIM: pass
DMARC: pass
Policy: p=quarantine or p=reject after testing

Red Flags That Need a Senior Engineer

If I see any of these during an audit, I would not recommend DIY fixes unless someone experienced is already on hand:

1. Multi-tenant data model without clear ownership checks.

  • One bug here can expose every client's records.

2. Auth logic split across frontend hacks instead of server enforcement.

  • That creates false confidence and easy bypasses.

3. Secrets already leaked into GitHub commits or preview builds.

  • Rotation work becomes urgent because compromise may already have happened.

4. Production deploys are manual and undocumented.

  • This usually means repeat failures during app review windows.

5. Email deliverability is broken across SPF/DKIM/DMARC plus sending reputation.

  • If client notifications fail now, support load goes up immediately after launch.

DIY Fixes You Can Do Today

1. Create two test accounts.

  • Use them to verify that each account sees only its own data across all major screens.

2. Search your repo for secrets.

  • Look for API keys, private tokens, service credentials, webhook secrets, and `.env` files committed by mistake.

3. Check your login cookies.

  • Confirm they are Secure and HttpOnly in production.

4. Test your main domain paths.

  • Open `http`, `https`, `www`, apex domain, login page redirects back to dashboard flow through all variants without loops.

5. Send one real email through your system.

  • Confirm SPF/DKIM/DMARC pass before you invite clients into the portal.

Where Cyprian Takes Over

This is how I map checklist failures to Launch Ready deliverables:

| Failure found | What I fix in Launch Ready | |---|---| | Broken DNS or wrong canonical domain | Domain setup, DNS records, redirects | | SSL errors or mixed content warnings | SSL configuration plus secure asset delivery | | Bad subdomain routing | Subdomain mapping and routing cleanup | | Exposed secrets or unsafe env handling | Environment variables cleanup plus secret handling | | Unreliable deployment process | Production deployment hardening | | Weak email deliverability | SPF/DKIM/DMARC setup | | Missing monitoring | Uptime monitoring plus alerting setup | | Cache issues on private pages/assets | Caching rules tuned for public vs private content | | Cloudflare misconfiguration or lack of DDoS protection | Cloudflare setup plus edge protection | | No handover docs for founders or internal teams | Handover checklist with operational notes |

The delivery window is 48 hours because this work should be handled as a tight production sprint rather than a long redesign project. My goal is simple: remove launch blockers fast so app review does not get derailed by avoidable infrastructure mistakes.

My preferred order is:

1. Lock down security-critical items first. 2. Fix DNS/SSL/domain consistency next. 3. Verify email delivery. 4. Deploy production safely. 5. Add monitoring last so you have visibility from day one.

If your portal already works but fails app review because of security gaps or infrastructure issues, this is usually enough to get you live without rebuilding the product itself.

A simple decision path

References

  • roadmap.sh code review best practices: https://roadmap.sh/code-review-best-practices
  • roadmap.sh API security best practices: https://roadmap.sh/api-security-best-practices
  • roadmap.sh cyber security roadmap: https://roadmap.sh/cyber-security
  • OWASP API Security Top 10: https://owasp.org/API-Security/
  • Cloudflare SSL/TLS documentation: https://developers.cloudflare.com/ssl/

---

Take the next step

If this is a problem in your product right now, here is what to do next:

  • [Use the free Cyprian tools](/tools) - estimate cost, score app risk, check launch readiness, or pick the right service sprint.
  • [Book a discovery call](/contact) - I will tell you honestly whether you need a sprint or if you can DIY the next step.

*Written by Cyprian Tinashe Aarons - senior full-stack and AI engineer helping founders rescue, launch, automate, and scale AI-built products.*

Next steps
About the author

Cyprian Tinashe AaronsSenior Full Stack & AI Engineer

Cyprian helps founders rescue, secure, deploy, and automate AI-built apps with production-grade engineering, launch systems, and AI integration.