The last post told the cost story. This one tells the standardization story: replacing the homemade invite system in every app with a JWT-based one that expires, can be revoked, and lands on a dedicated page. And building the admin pages that most of them never had.
What Was Broken
Each app had grown its own invite system organically. Different storage, different validation, different expiry. One returned a 500 on an empty form. Another split its invites across two tables that quietly disagreed on which token was authoritative. Each one worked. None of them matched.
Standardization is not a feature. It is a posture. When seven apps share an auth model, an attacker who finds a flaw in one has found a flaw in all of them. The fix is to make the implementations identical, so the same patch applies everywhere.
What Changed
Every app now issues signed JWT invites with a 7-day expiry, a unique token ID, an optional bound email, and a type field that the decoder validates -- so a token issued for something else cannot be accepted as a signup invite. Admins can revoke any outstanding invite in one click. Each app has a dedicated landing page that handles the invite link, validates the token, and either pre-fills the OAuth flow or shows a clear error. Most apps also got their first real admin page: list users, list outstanding invites, generate, copy, revoke. The diagrams admin page had a CSRF bug where the browser was validating the token server-side but never sending the header from the client. One line in app.js fixed it.
The race condition got the same treatment everywhere. The old flow verified the token was unused, then marked it consumed -- two requests could both pass the check before either wrote. The fix collapses the check and the write into a single atomic update that succeeds for exactly one of them. The ownscribe app also had a broken email-binding flow where invites could be redeemed against the wrong account. Now an invite for [email protected] can only be used by [email protected]. An invite is a credential bound to a specific person, not a general-purpose token.
The Tally
What Standardization Buys
Running seven apps on the same auth model is not aesthetics. It is the ability to reason about the entire system as one thing. A vulnerability found in one gets a mechanical fix in the other six. A workflow change happens in one place and propagates. A new app joining the suite does not invent its own model -- it adopts the existing one.
The boring work is the work that makes everything else possible. Standardization is the most boring work of all, and the highest leverage. Seven apps now behave like one app. That is the win.