Keystone — Why This Deserves to Be the First Real Topic
Status: Written 2026-08-19, from a conversation working through RoundTrip's Entra identity problems. Not a decision — seed material for the future cross-product Architect conversation, so the reasoning isn't lost between now and whenever that conversation actually happens.
The problem this started from
RoundTrip has two real, currently-open tickets, both caused by the same underlying fact: Entra External ID isn't a standalone product, it's Entra ID wearing a consumer-facing hat — still fundamentally part of Microsoft's broader identity graph.
- TRA-384 — registration fails outright if a prospect's email already has any Entra identity (a real M365 account under that address).
- TRA-389 — even a completely fresh email fails differently: if the domain is verified anywhere on a real Microsoft tenant, Entra's home-realm discovery redirects the user to authenticate against their M365 instead of RoundTrip's own login.
Cross-tenant recognition is a genuine feature from Microsoft's perspective — seamless enterprise SSO. For a product whose whole point is a clean, isolated, per-tenant identity system, that same feature actively works against it.
Near-term fix, already planned, not blocked on anything below: finish the registration migration from InviteUserAsync (guest — the mechanism that collides and redirects) to CreateMemberUserAsync (local member account, the same mechanism team invites already use successfully). A local account inside RoundTrip's own roundtripapp.onmicrosoft.com tenant isn't a cross-tenant reference at all — it shouldn't trigger either bug. This was always the originally intended fix; it just never got finished. Worth proving this closes both tickets before treating anything below as necessary rather than merely nice-to-have.
The bigger question this raised: does Traxs One need its own identity layer?
OpenIddict came back into the conversation — a self-hosted identity provider, evaluated once before, early on, and deliberately set aside.
Why setting it aside then was the right call, not just caution
At that point, RoundTrip was the only real product. Building a shared identity system to serve a theoretical future platform, before knowing what Waypoint or Relay would actually need from auth, would have been solving a problem that didn't exist yet — premature abstraction, not foresight. Passing on it then was correct, not timid.
Why the calculus is different now
Three real things changed, not just a mood:
- Waypoint is real and in active development. Relay is planned. This is no longer a hypothetical platform.
- RoundTrip has now hit real, lived consequences of not having product-agnostic identity — TRA-384/389 aren't architectural speculation anymore, they're bugs that cost real debugging hours.
- The cost math changes with the denominator. Self-hosting a full identity provider is genuinely too expensive for one product to carry alone. Amortized across an entire platform — three or four products sharing one identity layer instead of each reinventing it — the same cost looks completely different. OpenIddict was never the wrong tool; it was being evaluated against too narrow a scope.
The real cost, honestly — not just the appeal
This isn't free, and worth naming plainly rather than only listing the upside:
- A full identity-foundation migration on live systems — RoundTrip already has real customers, real billing, real registered tenants. JWT claim parsing,
TenantScopingBehavior, the entire MSAL frontend flow are deeply Entra-shaped today. - Taking on security-critical responsibility currently owned by Microsoft — password resets, brute-force protection, session security, all currently just handled as a managed service. That's a real, meaningful shift in what a solo founder building evenings around a full-time job is on the hook for.
- Centralizing risk, not just infrastructure. Today, if RoundTrip's auth has a problem, Waypoint is completely unaffected — they're independent. A shared Keystone becomes a single point of failure for the entire platform at once. Not a reason to avoid it — most successful multi-product platforms work exactly this way — but it raises the bar on what "done" means before other products actually depend on it. This needs to be built with real care, not the pace of a quick fix.
Where this actually leads
- Fix RoundTrip's two tickets first, via the already-planned
CreateMemberUserAsyncmigration — proves out (or disproves) whether the near-term problem needs anything bigger than what's already scoped. - Bring Keystone to the Architect conversation as its first real topic, once that conversation actually exists — not because it's urgent, but because a decision this foundational deserves to be made with the whole platform in view, deliberately, rather than reasoned out in the middle of a bug fix.
- The original "chicken out" instinct and this new instinct are both right, for their own moments. The tool didn't change. What it's being asked to justify did — one product's convenience versus an entire platform's foundation. That's the actual argument worth carrying into that conversation, not just the conclusion.