02/Architecture deep-dive
Federating identity across products without a shared user database
- Status
- Accepted
- Written
- July 4, 2026
- Topic
- OIDC sign-on and identity federation
- Seen in
- Issara Authorizer
Three products, one person, no shared database. Why the identity gateway federates at login and treats the provider's own metadata as the correlation ledger, instead of building a central user store everyone syncs to.
Context
Issara runs three products for the same community of people: Golden Dreams for workers, and ILM and Cascade for labor-rights monitoring. A single person often exists in more than one of them. Each product had, or would have, its own login, its own user model, and its own session handling. So the same human showed up as two or three disconnected accounts, with no shared notion of who they were and nowhere to revoke a compromised session across products.
The obvious fix is a central identity service. The trap is what kind. The moment that service owns a database of users that each product must stay in sync with, it becomes a second source of truth for identity, and every product now has to reconcile against it. It also sits on the login path for all three products, which means any database it owns is a stateful dependency that can be slow, stale, or down at the worst possible moment.
So the real constraint was not just single sign-on. It was single sign-on that unifies a person across products without introducing a new stateful system to keep consistent, and without becoming a single point of failure on a path every product depends on.
Decision
Federate identity at login rather than centralize it in storage. The gateway authenticates the user once through the identity provider, enriches by fetching each product's own profile at that moment, merges them into one authorization payload, and writes the cross-product correlation back into the provider's user metadata. That metadata, not a database the gateway owns, is the shared ledger of who this person is across products.
Options considered
A central user database the products sync to
Stand up a users table in the gateway. Every product writes its users into it and keeps them updated, and the gateway reads identity from there.
It creates a second source of truth. Each product now owns the same user in two places and has to reconcile drift forever. It also makes the gateway stateful on the login path, so its availability and its migrations become everyone's problem. This is the capable-looking answer that is the most expensive to keep correct.
Auth left inside each product
Skip the gateway. Let each product keep its own OAuth, its own JWT verification, and its own sessions.
Three divergent security implementations instead of one, no place to sign a user out everywhere, and no unified identity at all. The person stays fragmented across accounts, which was the problem to begin with.
Federate at login, correlate in provider metadata (chosen)
ChosenAuthenticate once at the provider. Pull each product's profile at login, merge into one payload, and persist the correlation IDs into the provider's user metadata as the shared record.
Chosen. It adds a per-login enrichment cost and leans on the provider's metadata as the ledger, but it introduces no new stateful system and keeps each product the owner of its own profile data.
What it bought
- No new database to own. The provider's user metadata carries the cross-product correlation, so there is no users table to migrate, reconcile, or keep consistent.
- Each product stays the authority on its own profile. The gateway reads product data at login instead of mastering a copy of it, so there is no drift to fight.
- The gateway can be stateless. Because it holds no session state of its own, it deploys as a serverless function and scales without coordinating shared state.
- Central session control becomes possible. One place authenticates, so one place can revoke a single session or sign a user out of every other session at once, which no per-product design could offer.
What it cost
- Login does more work. The callback fetches a profile from each product before it can answer, so enrichment latency is now part of sign-on. This is why every downstream call has a timeout and why a failed fetch degrades to partial identity instead of a failed login, and why those calls should run in parallel rather than in sequence.
- The provider's metadata is now load-bearing. Treating it as the correlation ledger means its shape and its limits are part of the architecture, and the write is kept non-blocking so a metadata failure never breaks a login.
- Correlation is eventual, not transactional. A person newly added to a second product is unified on their next enrichment, not instantly, which is the right trade for this domain but is a real property to state rather than hide.
When to revisit
Reopen this if a product ever needs identity data that cannot live in provider metadata, or if per-login enrichment latency stops being acceptable even parallelized and cached. At that point a read-optimized correlation store, owned by the gateway but never the source of truth, is the next step to weigh, not a full central user database.