Skip to content
Blue Horizon Labs

Case study

Flagship Product·Cross-industry·

Blue Horizon Labs Client Portal — Multi-Tenant Client Access on Cloudflare

A client portal rebuilt in days, not months: Cloudflare Access OTP, ports-and-adapters Worker, tenant #1 live.

Measured

  • 97 tests green
  • 10-source frozen allowlist
  • 2 write targets, each pinned
  • Email-OTP, zero-trust
  • Tenant #1 live in production
The store is never constructed until the request has proven who it is.

The study

The problem

A client portal usually means a login screen, a database, a hosting bill, and a multi-month build. We wanted something narrower and harder: a client should be able to open a private workspace holding their own sensitive records, and the architecture — not a policy document — should be what makes a data leak structurally difficult.

The first tenant's data was genuinely sensitive. That set the bar. Access control could not be a feature bolted on at the end; it had to be load-bearing from the first commit, and it had to be the kind of thing a test could prove.

The architecture

The portal is built ports-and-adapters. Two ports define the boundary — an identity provider and a data store — and exactly one file in the whole codebase names the concrete adapters behind them. Swap the auth mechanism or the datastore there, and nothing else changes.

Three decisions do the security work:

  • Identity is verified before the store is constructed. Authentication runs at the edge as Cloudflare Access email-OTP: an unauthenticated request is turned away before any application code runs. Only after a request proves who it is — and which tenant it belongs to — is a data store built for it. A request that fails auth never causes a store to exist.
  • Writes are pinned per operation. Each write method is bound to exactly one data source. A daily check-in physically cannot write to the medication log, and vice versa — the binding is enforced in code and covered by tests, not left to reviewer discipline. The set of readable sources is a frozen allowlist.
  • Cancel is a status, never a deletion. Records move through a lifecycle — scheduled, completed, cancelled — and nothing is destroyed to represent a change of state. History stays intact; a reversal is always possible.

What we measured

97 tests run green, and the ones that matter most assert the security invariants directly: that a write to the wrong target is rejected, that an unauthenticated request gets a redirect to the login and never reaches the store. The deploy step ships a public bundle that excludes the private layer entirely — a leak guard that runs at build time, before anything reaches the edge. Tenant #1 is live in production behind one-time-PIN access.

The whole portal reached that state in days, not the months a bespoke auth-plus-database build usually takes — because the hard parts were architecture decisions, not code volume.

What transferred to the lab's method

The two load-bearing patterns — the ports-and-adapters seam and per-operation write pinning — are now a template the lab reuses. The same identity-before-store discipline anchors the appointment-tracker application the lab is building next.

The through-line: security you can test is security you can trust. Make the safe path the only path the code is able to take, and correctness stops depending on anyone remembering to be careful.

Begin

The next study could be yours.

Start with a diagnostic conversation — plain language, real numbers.

Schedule a conversation