Platform & Infrastructure

2026-10-01

Identity and Access · Part 2 of 4

How a Session Crosses Many Applications: The Architecture of One Login

Five layers, four flows, and one credential. A plain-language walkthrough of how an identity provider, a policy store, an application boundary and the network edge combine so that one sign-in serves many applications.


Platform & Infrastructure · Identity and Access, Part 2 of 4 · ~10 min read · prev: The Door · next: Building It · assumes Part 1: identity, authentication, authorization, session

Part 1 argued that identity is a platform capability — because authentication was centralised years ago and the access decision, the session and the review that follow it never were. This post is the machinery: which components exist, what each one holds, how a request travels between them, and why one sign-in can serve many applications at all.

The short answer is that no single component signs anyone in. Five layers cooperate, and each one is responsible for a different question. Understanding the split is what makes the rest of the series — building it, troubleshooting it, integrating with it — tractable.

Five Layers, and What Each Holds

Start with the distinction that decides where everything else lives: a layer can only refuse a request if it is asked before the content is delivered. A file server cannot refuse anybody, because serving the file is the answer.

What this shows: the four components a request can meet, and the one path that never reaches the application at all — the redirect to sign-in.

  • The network edge is the layer closest to the reader and furthest from your code: caching, rate limiting, bot mitigation, and whatever rules your provider lets you set in a dashboard. It knows nothing about your access model, and — importantly for Part 4 — its configuration is account state, not something a commit can review.
  • The gateway is the component that fronts your applications. It reads the session, asks the identity service whether it is good, and either serves the application or sends the reader to sign in. It is the place where "may this person see this page?" is answered before the page exists in the browser.
  • The application is a bundle of static files. It holds nothing and can refuse nobody; every protection it appears to have comes from the layer in front of it.
  • The identity service signs people in, verifies their sessions, and issues the one credential the whole estate accepts — the session.
  • The policy store holds the grants — the durable record of who may do what, to which resource, until when.

The gateway is the layer that checks a page request; each application's own service is the layer that checks its data — the same job, in two places. That checking layer is what this series means by the boundary.

One boundary in that picture is worth making explicit: the interface where an operator administers access is an application, and it belongs behind the door with every other application. The host that serves sign-in and the session serves no application at all — the door's host is not a place an operator interface lives.

The last two are often confused, so keep them apart: the service answers "is this person signed in?" and the store answers "may this person do this?". Different question, different owner, different failure.

The Four Flows

Authentication is not a page; it is four short flows built on one session. Reading them in order is the fastest way to understand why the cookie exists and what it carries.

What this shows: one sign-in, four flows — sign-in, a page refused before it is served, the call that reads data, and the cookie that makes all three possible.

Sign-in exchanges a credential for a proof. In a good design the exchange happens on the server, so the password never reaches page JavaScript, and what comes back is a signed statement rather than a password or a permission.

A page refused before it is served. The important detail is the return address: the reader is sent to sign-in carrying the page they actually asked for, so that after signing in they land where they intended rather than on a default screen. Getting that wrong is the single most common "the login is broken" report — the sign-in worked, and the reader was put somewhere else.

The call that reads data repeats the check for every request. It carries the same cookie, and the boundary — the layer that checks a request before it reaches a resource — checks it again rather than trusting that a previous page load proved anything about this one.

Sign-out ends the session for every application at once. That is only possible because of the next decision.

One rule holds those flows together: sign-in and sign-out are the same round trip in opposite directions. Both carry the address of the page the reader came from, so signing out returns them to the application they left rather than to a waiting screen. The door is never a destination a reader browses; it is a detour on the way to one. And because every factor of authentication is established at the door, an application never learns how the reader proved who they are — only the assurance the session carries.

Browser storage is per-origin. A session kept in one application's storage is invisible to every other application — which is why a framework's built-in login is always a login for that application. Single-sign-on products solve this for the applications they connect, by placing a session in front of them. For the applications you build yourself — the internal tools, the dashboards, the APIs — the same structural requirement returns: the credential must live somewhere every one of them can see it. That reach has a boundary: beyond the applications you build — inside software you do not control — the cookie is not the mechanism, and the other side trusts a signed assertion — a statement about who the person is, signed by your issuer — instead.

What this shows: why the cookie's scope, not the framework, is what makes one login serve many applications.

That scope decision carries three consequences worth stating plainly, because each one is a design choice rather than a detail.

Attributes are policy. A session cookie should be unreadable by page scripts — that is what HttpOnly means. Without it, script injected into your page (a cross-site scripting, or XSS, attack) could read the credential or send it elsewhere. It should also be sent only over HTTPS (Secure), and restricted in when a browser attaches it to cross-site requests (SameSite) — because a cookie the browser attaches automatically is what makes a forged request (cross-site request forgery, or CSRF) possible from another site. Those three attributes are the difference between a credential and a souvenir that any injected script can post elsewhere.

Lifetime is a trade. A long session is convenient and dangerous; a short one is safe and irritating. The honest position is that the cookie's lifetime should be bounded by the token inside it, and that a session must be endable before it expires — which is a requirement on the policy store, not on the cookie.

Scope crosses environments. If staging and production share a parent domain, a cookie set by one is presented to the other. That is not a bug in the cookie; it is the direct consequence of choosing the parent domain for convenience. The options are to give each environment its own cookie name, or to accept that both environments will see a credential that only one of them issued — and to make sure the consequences of that are understood rather than discovered.

The Standards Behind These Words

The vocabulary above is not invented here; it is standardised. You do not have to implement these standards, but you do have to recognise them, because they are what keep a choice reversible.

StandardWhat it is forWhat it does not do
OIDC (OpenID Connect)Standard sign-in: proves identity and returns a standard identity tokenIt says nothing about what the person may do
OAuth 2.0Delegated access: lets an application call an API on someone's behalfIt is not a login protocol — "sign in with…" is the identity layer above it
SAMLEnterprise single sign-on against an existing corporate directoryIt does not provision accounts, and it is heavier than OIDC
SCIMLifecycle: creating, updating and disabling accounts from a directoryNothing about sessions or permissions
JWT (JSON Web Token)A signed, verifiable token format with standard fieldsA token cannot be un-issued — it is not a session store
JWKS (JSON Web Key Set)The issuer's published public keys, so verifiers need no shared secretIt does not tell you whether a person should have access
PKCEProtects the step where a browser hands a code back to an applicationNothing about server-side flows, where the secret stays on the server
WebAuthnStrong credentials: a device-held key instead of a passwordIt is not an authorization model

The practical takeaway is short. If your integration is shaped by these standards, your identity provider is replaceable; if it is shaped by a vendor's SDK, it is not. That is the whole argument of Part 3's build-or-buy section, and it is the reason this post spends its middle on vocabulary rather than on a diagram of boxes.

How a Token Is Verified

A session carries a token, and a token is only useful because anyone holding the issuer's public keys can check it without asking the issuer a question. That property is what makes a stateless check possible at every boundary.

What this shows: verification is local — the boundary checks a signature against published keys, then checks the claims, and never asks the issuer per request.

Three fields do most of the work in practice. The issuer says who created the token, and a boundary that accepts tokens from the wrong issuer is trusting a stranger. The audience says who the token was made for. In this estate that is the applications as a group — one trust domain, meaning they accept the same session — which is what stops a token minted for one of them from being replayed against an unrelated service. The expiry bounds the damage of a stolen token — and is precisely why revocation must be a separate mechanism, because a token that expires in an hour cannot be recalled in a minute.

The Authorization Decision

Verification establishes who. The decision that follows asks whether that identity may do this specific thing, and it is made from data rather than from code.

What this shows: a decision made of four parts — principal, role, resource, assignment — where the assignment is data that can be inspected, expire and be revoked.

Two properties follow, and both are load-bearing for the rest of the series. First, the decision lives in the policy store, not in the application, so an access review is a query rather than a code reading. Second, an assignment carries validity — it can start later, end sooner, or be revoked now — which is what makes "remove this person's access" an operation rather than a deployment.

That is the model. Part 3 is the order to build it in: what to choose first, what to keep replaceable, and what the lifecycle of a grant actually requires.

The Orchestrator's Takeaway

  • Five layers, five questions. The edge filters, the gateway fronts, the application serves files, the identity service proves identity, the store decides access. Design them as separate owners and each failure has a name.
  • The session is a scope decision. One login across many applications is possible because the credential lives where every application can see it — and the attributes, lifetime and environment consequences of that choice are policy, not detail.
  • Standards are the exit route. OIDC-shaped integration keeps the identity provider replaceable; an SDK-shaped one makes the vendor permanent. Buy the standards, then the vendor.
  • Verification is local; authorization is data. Checking a token needs only the issuer's published keys. Deciding what it may do needs a store you can query, expire and revoke.

Software Architecture
Platform Engineering
Quality & Governance