checklists / launch-ready

Launch Ready API security Checklist for client portal: Ready for handover to a small team in B2B service businesses?.

For a B2B client portal, 'ready' does not mean the app just loads and the login button works. It means a small team can take it over without exposing...

What "ready" means for a client portal handover

For a B2B client portal, "ready" does not mean the app just loads and the login button works. It means a small team can take it over without exposing customer data, breaking email delivery, or creating support chaos the first time real clients use it.

I would call Launch Ready successful when the portal is production deployed, DNS is clean, SSL is valid, secrets are not in the codebase, API auth is enforced on every sensitive route, email authentication passes SPF/DKIM/DMARC, uptime monitoring is live, and the team can explain who owns what after handover. If any one of those is missing, the business is not ready for clients yet.

For a founder self-assessment, use this standard: no critical auth bypasses, zero exposed secrets, p95 API latency under 500ms for core portal actions, and no broken redirects or email deliverability issues after deployment. If you cannot confidently answer "yes" to those four items, I would treat the launch as risky.

Quick Scorecard

| Check | Pass criteria | Why it matters | What breaks if it fails | |---|---|---|---| | Auth on all portal routes | Every private endpoint requires verified session or token | Stops unauthorized client access | Data leaks and account takeover | | Role-based access control | Users only see their own org data | Prevents cross-client exposure | Legal risk and trust loss | | Input validation | All API inputs are schema-validated server-side | Blocks bad data and injection paths | Broken records and exploit risk | | Secrets handling | No secrets in repo, logs, or client bundle | Protects production credentials | Full environment compromise | | CORS policy | Only approved origins can call APIs | Reduces browser-based abuse | Token theft and cross-site misuse | | Rate limiting | Sensitive endpoints are throttled | Prevents brute force and abuse spikes | Downtime and support load | | Email auth setup | SPF, DKIM, DMARC all pass | Ensures portal emails land in inboxes | Password reset and invite failures | | Deployment safety | Production deploy has rollback path | Limits blast radius of bad releases | Extended outage or broken onboarding | | Monitoring coverage | Uptime and error alerts are active | Detects failures before customers do | Slow incident response | | Redirect and domain hygiene | www/non-www, apex, subdomains resolve correctly over SSL | Avoids duplicate content and login confusion | Broken links and failed sign-in |

The Checks I Would Run First

1. Verify auth on every sensitive API route

Signal: I can hit an endpoint for invoices, files, messages, or profile data without a valid session or bearer token. That is a hard fail.

Tool or method: I use Postman or curl with no token, an expired token, and a token from another user. I also inspect server logs to confirm rejected requests are recorded without leaking secrets.

Fix path: Put authorization checks in the backend middleware first, then add route-level guards for org ownership. Do not rely on frontend hiding buttons; that only protects the UI, not the data.

2. Check object-level access control

Signal: A user from Client A can change an ID in the URL or request body and see Client B's records. This is one of the most common portal failures.

Tool or method: I test direct object references on endpoints like `/api/documents/:id`, `/api/messages/:id`, and `/api/projects/:id`. I try swapping IDs between two test accounts.

Fix path: Every read/write must verify `resource.org_id === current_user.org_id` or equivalent server-side ownership logic. If you have multi-tenant data, this check belongs in every query path.

3. Audit secrets exposure

Signal: API keys, SMTP passwords, JWT secrets, Stripe keys, or Cloudflare tokens exist in `.env` files committed to Git history or printed in browser code.

Tool or method: I scan the repo with `gitleaks`, check deployment env vars in Vercel/Netlify/Fly/Railway/etc., and review build output plus source maps if they are public.

Fix path: Rotate any exposed secret immediately. Move all runtime secrets to platform environment variables and keep them out of frontend bundles unless they are explicitly public keys.

4. Validate CORS and origin rules

Signal: Any website can call your authenticated API from a browser context because CORS is set to `*` or too broad.

Tool or method: I inspect response headers with browser dev tools and test requests from an unapproved origin. I confirm preflight behavior on login and file upload routes.

Fix path: Allow only known app origins such as your main domain and admin subdomain. Keep credentialed requests strict. If you need multiple environments, list them explicitly.

5. Confirm email deliverability setup

Signal: Invite emails land in spam or fail entirely because SPF/DKIM/DMARC are missing or misaligned.

Tool or method: I test with Mail-Tester style checks plus real inboxes at Gmail and Outlook. I verify DNS records at Cloudflare and check message headers after sending invites or password resets.

Fix path: Publish correct SPF includes for your provider, enable DKIM signing at the sender level, then set DMARC to `p=none` first if you need monitoring before enforcement.

6. Measure production behavior under real load

Signal: Portal pages feel slow after login, API calls exceed 500ms p95 on common actions, uploads time out, or dashboards freeze under normal usage.

Tool or method: I run Lighthouse for key pages plus simple load tests against core endpoints using k6 or similar tools. I also inspect database query plans if latency spikes show up on list views.

Fix path: Add indexes to common filters like `org_id`, `user_id`, `status`, and `created_at`. Cache safe reads where possible, move slow work into queues, and strip unnecessary third-party scripts from the app shell.

Red Flags That Need a Senior Engineer

1. You have multiple customer organizations in one database but no clear tenant boundary This usually turns into accidental cross-account access later. It is cheaper to fix now than after one client sees another client's documents.

2. The app uses ad hoc auth checks scattered across components If each page decides its own permissions differently, you will miss an edge case. Centralized authorization is safer than patchwork logic.

3. Secrets were ever committed publicly Even if you deleted them later, assume they may be compromised until rotated everywhere. This includes email keys, webhook secrets, database passwords, and cloud tokens.

4. You cannot explain how invites,password resets,and notifications are delivered That means support tickets will spike as soon as users try to log in for real. In B2B service businesses that often becomes a sales blocker within 24 hours of launch.

5. There is no rollback plan for deployment A bad release should be recoverable in minutes, not hours. If your team cannot roll back safely, do not launch without senior help.

DIY Fixes You Can Do Today

1. Rotate every secret you can name

Start with database credentials,email provider keys,JW T signing secrets,and payment webhooks if they exist. Assume anything that touched chat logs,screenshots,and shared docs should be rotated too.

2. Turn on Cloudflare protections

Put DNS behind Cloudflare,enforce SSL,and enable basic DDoS protection plus caching rules for static assets. This reduces downtime risk before you even touch application code.

3. Publish email authentication records

Make sure SPF,DKIM,and DMARC exist for your sending domain.

v=spf1 include:_spf.yourprovider.com -all

4. Test private routes with two accounts

Use one account from each client organization and try to view/edit each other's records by changing IDs in URLs,payloads,and query strings. If that works,you have an urgent authorization bug.

5. Set up basic monitoring

Add uptime checks for homepage login,and core API health endpoints plus error alerts to Slack,email ,or both . If nobody gets notified when login breaks,you will find out from customers first .

Where Cyprian Takes Over

If these checks fail,I would map them directly into Launch Ready deliverables instead of trying to "patch around" them piecemeal .

  • DNS , redirects , subdomains

I clean up apex/www routing , set canonical redirects ,and make sure staging/admin/client subdomains do not conflict . Timeline: hours 1-6 .

  • Cloudflare , SSL , caching , DDoS protection

I put the domain behind Cloudflare , verify certificates , set cache rules ,and reduce avoidable origin traffic . Timeline: hours 4-12 .

  • SPF / DKIM / DMARC

I configure mail authentication so invites,password resets,and notifications actually reach users . Timeline: hours 8-16 .

  • Production deployment + environment variables + secrets

I deploy the app safely , move secrets into managed environment variables ,and rotate anything exposed . Timeline: hours 10-24 .

  • Monitoring + handover checklist

I add uptime monitoring,error visibility,and a practical handover doc so a small team knows what to watch after launch . Timeline: hours 20-48 .

My recommendation is simple: if your portal touches client records,billing,messages,file uploads ,or approvals,you should not hand it over until these controls are verified by someone who has shipped this before .

References

  • roadmap.sh - API Security Best Practices: https://roadmap.sh/api-security-best-practices
  • roadmap.sh - Cyber Security Roadmap/Topics: https://roadmap.sh/cyber-security
  • OWASP API Security Top 10: https://owasp.org/www-project-api-security/
  • Cloudflare Docs - DNS/SSL/Security Basics: https://developers.cloudflare.com/
  • Google Workspace Admin Help - Email Authentication (SPF,DKIM,and DMARC): https://support.google.com/a/topic/2759254

---

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.