← CEO Desk
CyberGuard2 May 2026 · 7 min read

Building CyberGuard: Why I Refused to Ship With Mock Data

CyberGuard is a cyber-security SaaS platform I built from scratch on Next.js 15's App Router — feature-based architecture, Supabase Auth via `@supabase/ssr`, a full Postgres schema with row-level security, and a very light, Apple/Linear/Stripe-inspired theme, deliberately far from the dark, hacker-aesthetic that most security tools default to.

The feature list is long by design: email and PII breach checks, a URL and phishing scanner, WHOIS and DNS lookups, subdomain enumeration, SSL checking, IP reputation, VPN detection, password strength checks, a security score, and a threat intelligence feed — thirteen-plus distinct features, each wired to a real external API (RapidAPI/BreachDirectory, VirusTotal, IPInfo, IPQualityScore, WhoisXML) rather than a placeholder.

The rule I set early, and stuck to even when it slowed me down, was: no mock data in production, anywhere. It would have been faster to fake a breach-check response while I wired up the UI. I didn't, because a security tool that shows you fabricated results — even temporarily, even in a demo — is worse than a security tool that shows nothing. The moment fake data becomes acceptable 'just for now,' it has a way of quietly staying.

In practice, this meant every feature had a key-absent fallback state instead of a fake success state. If an API key wasn't configured yet, the UI says so plainly — 'this check isn't available right now' — instead of rendering a convincing-looking result built from nothing. It's a small UX decision that took real discipline to hold to across thirteen different features, especially the ones I built at 1am wanting to just see something render.

The RBAC layer (Admin/User roles), JWT with refresh tokens, and middleware-protected route groups — `(marketing)`, `(dashboard)`, `(auth)`, `(settings)` — came later, once the core checks were solid. I've learned to build the thing that has to be correct first, and the thing that has to be convenient second. Auth and access control are important, but a security tool that gives wrong answers is a worse problem than one that's briefly inconvenient to log into.

If there's a principle from CyberGuard I now apply everywhere: for anything touching security or trust, 'looks like it works' and 'actually works' have to be held to the same bar from day one, not reconciled later.