Building for the Client We Wanted
We had a client ready to split into 34 organizations, with two administrators who needed access to all of them. Under the existing architecture that wasn’t possible without internal workarounds that didn’t scale. Rather than wait for enterprise to arrive and scramble, we got ahead of it. Authentication and authorization were the foundation that had to be rebuilt first.
Starting in the Right Place
We were using the strangler pattern to modernize the monolith, replacing Ember components and routes with React equivalents one module at a time. Identity was the deliberate starting point. Get it right first and everything built on top of it inherits that foundation. What looked like a login screen turned into nine interconnected capabilities.
Google First, But Not Google Only
SSO was the capability that unlocked enterprise. I started with Google because it’s the best documented, the most forgiving to implement, and the most likely to surface edge cases early. But the architecture was designed from day one to support ENTRA and OKTA as well. Not as future additions to bolt on later, but as first-class paths the system was built to accommodate. The difference between designing for one provider and designing for many is the difference between a feature and a foundation.
Authentication Is Not Authorization
Knowing who someone is doesn’t tell you what they’re allowed to see. That distinction sounds obvious until you’re designing the system that has to enforce it. A user could authenticate successfully through Google SSO and still have no authorization to access any organization in Captivated. The system needed to resolve both, in sequence, before routing the user anywhere. Authentication first. Authorization second. Routing third.
The Multi-Org Problem
Once a user could belong to more than one organization, a new question surfaced: where do they land when they log back in? Making them navigate there every time adds friction. Making them designate a primary org puts the burden on them to maintain something they’ll forget. The right answer was to return them to wherever they were last. No configuration required, no friction added. The system just remembers.
Email-First as the Routing Mechanism
The login screen was the one place all of this complexity had to become invisible to the user. Email-first solved that. By identifying the user before showing any authentication inputs, the system could determine the right path silently, password login, Google SSO, ENTRA, OKTA, and present only what was appropriate. One clean input. No confusing choices. The complexity lives in the system, not in front of the user.
Putting It on Paper
Nine Capability Briefs. One for each interconnected piece of the identity system. Writing them was the next problem to solve.