skip to content

At federated login, what must your server record so that a later logout notice naming a provider session identifier maps onto local sessions?

level: middleimportance: must knowfreq 45%

answer

  1. the notice speaks the provider's identifiers
  2. written at login, never reconstructed later
  3. two index keys, two different fan-outs
  4. issuer belongs in both keys
  5. sid names one sign-in, sub names the person

basics

~20 s

Record the issuer, the subject and, when the provider issues one, the provider session identifier on every local session row you create at login. Without that index an arriving logout notice names nothing you hold, and your endpoint can only discard it.

solid answer

~40 s

A logout notice arrives in the provider's identifiers, not yours: a `sid` naming one provider-side sign-in, or only a `sub` naming the person. Your session store is keyed by your own opaque identifier, so unless the login path wrote the provider's values onto the row there is nothing to look up. At the point the callback hands you a verified subject and you mint the local session, persist `iss`, `sub` and `sid` when present, and index `(iss, sid)` and `(iss, sub)`. Those two keys give two very different fan-outs: a `sid` resolves to at most one local session — one browser on one library terminal — while a subject-only notice resolves to every session that researcher currently holds with you. Confusing them signs someone out of the laptop they are still working on.

code

json · 9 lines
json
{
  "sessionId": "b7f1c0b2-4a1e-4c33-9d2f-8f0a2f6e1d55",
  "userId": "u_18244",
  "iss": "https://idp.university.example/oidc",
  "sub": "9f3c1a77-5e5b-4a30-bf42-2c9d4d8e0a11",
  "sid": "s-7QkP2wZ0",
  "issuedAt": "2026-09-19T08:41:12Z",
  "lastSeenAt": "2026-09-19T11:02:44Z"
}

go deeper

for a junior

Recall that a federated sign-out reaches your server as a message from the identity provider, and that it can only affect sessions your own store already links to that provider's identifiers.

for a middle

Explain what the login path writes onto the session row — issuer, subject, and provider session identifier when present — and which of the two indexes each kind of notice is resolved through.

for a senior

Show the fan-out decision under real traffic: one provider session identifier ends at most one local session, a subject-only notice ends every session that person holds, and shared terminals make the difference visible to users.

for a principal

Weigh whether your service standardises on persisting the provider session identifier for every connection it supports, and what the store must fall back to for providers that never issue one — including what single-session logout can then honestly promise.

## What arrives, and why it names nothing you hold An academic reference manager that signs researchers in through their institution issues **its own session** when the federated login completes: a row in a session store keyed by an opaque identifier that only your service understands, and a cookie carrying that identifier back on every request. The institution's identity provider knows nothing about that row. When the researcher signs out at the institution — at a shared library terminal, before walking away from it — the provider can notify each application that person signed into, and the notification necessarily speaks **the provider's identifiers, not yours**: - `sub` — the subject: a stable identifier for the person, unique *within that issuer*. - `sid` — an identifier for one provider-side session: that particular sign-in, not that person. A notification may carry both, or only the subject. Neither is your session key. If your row recorded only "this session belongs to user 18244", no query turns an arriving `sid` into rows, and the endpoint you registered with the provider is decorative — it answers and ends nothing. **The index must already exist before any notice is useful, and the only place it can be built is the login path.** ## What the login path must write At the moment the callback hands you a verified subject and you create the local session, persist three values and index two pairs: 1. `iss` — the issuer that authenticated this login. It belongs in both lookup keys and is never optional. 2. `sub` — the subject exactly as that issuer spells it, copied verbatim, never normalised, trimmed or lower-cased. 3. `sid` — the provider session identifier, when the provider issues one. Absent is a legitimate state, not an error. Then index `(iss, sid)` and `(iss, sub)`. Three properties of that write are worth stating outright: - **It happens on every path that mints a session**, including a silent re-authentication that replaces one. A session created without the index is invisible to every later notice, and nothing will ever tell you it is. - **It is copied, not derived.** The local user identifier is yours; these three are the provider's, and the moment you map them onto your own primary key at login you have thrown away the ability to look up by what the notice actually carries. - **It is per session, not per user.** A researcher signed in on a library terminal and on their own laptop has two rows, and the whole point of storing `sid` is that those two rows can be told apart by something the provider can name. ## Two identifiers, two fan-outs | The notice names | Resolves through | Ends | Getting it wrong costs | |---|---|---|---| | `sid` — one provider session | `(iss, sid)` | at most one local session | widening it signs the researcher out of every device, mid-import | | `sub` only — the person | `(iss, sub)` | every local session that person holds here | narrowing it to one row leaves the library terminal signed in | This is the decision the index exists to support, and it is the part interviewers probe. A `sid` is the narrow instrument: exactly one row, or zero if that sign-in never produced a session here. A subject-only notice is the blunt one: it can only mean *this person is no longer signed in at the provider*, so it resolves to the whole set. Providers differ on which they send, and some never issue a session identifier at all — so the handler must resolve both shapes, and the design must be honest that against such a provider single-session logout is simply unavailable. ## Where the index lives, and what it costs - **On the session record itself** when sessions live in one store you control: two extra columns and two secondary indexes on a table already written once per login. - **In a separate mapping table** when a single provider sign-in can back more than one local session record — the join then carries the fan-out and the session rows stay narrow. - **The read side is cheap and rare:** a point lookup when a notice arrives, which happens once per sign-out, against a write on every login. The real cost is discipline, not throughput — one login path that forgets the write is a silent hole. - **The issuer belongs in the key even in a single-provider deployment.** Subjects are unique per issuer only, so a service that later accepts a second institution and indexed on the subject alone can resolve a notice from one provider onto sessions established through another. Adding the column later means backfilling rows whose issuer nobody recorded. ## What resolution deliberately is not Resolving a notice produces a **set of local session identifiers** and stops there. Destroying a session record, what dies with it and how the browser finds out on its next request are the session layer's concern; whether a standing grant your service holds for that researcher survives the sign-out is a separate, explicit decision. Keeping resolution as a pure lookup is what lets the same mapping serve a notice that names one sign-in and a notice that names a person, without either path growing its own special case.

  • Your provider never issues a session identifier. What changes about the index and about what you can promise?
    The row still carries `iss` and `sub`, and every notice resolves through `(iss, sub)` to all sessions that researcher holds here. You lose the ability to end exactly one: each notice is a per-person fan-out. That is a property to state in the design — a researcher signing out at a library terminal also loses the session on their own laptop — not something to discover from a support ticket.
  • A researcher can reach your service through two institutions' identity providers. Why must the issuer be part of the index?
    Subject values are unique only within an issuer, so two providers can legitimately emit the same `sub` for different people. Keying on the subject alone lets a notice from one institution resolve sessions established through another. Both keys therefore carry the issuer: `(iss, sid)` and `(iss, sub)`.
  • What does the index actually cost on the login path?
    Two extra columns and two secondary indexes on a row written once per login, read once per sign-out as a point lookup — negligible either way. The cost that matters is discipline: every path that mints a session must write it, including a re-authentication that silently replaces one, because a row without the index is unreachable by any later notice and nothing surfaces that.

A cloakroom writes nothing on its tickets about who left each coat. A message from the front desk — "Dr Ashcroft has gone home" — then matches no ticket, and the staff can act on it only by refusing to act at all. Recording the guest's name and the particular visit on the stub at check-in is what makes such a message actionable later, and it also fixes the fan-out: the name pulls every coat she left today, the visit reference pulls exactly one.

saying these in an interview costs you the question

  • Thinks an arriving notice can be matched without anything stored at login
  • Assumes the provider's subject is also the local session key
  • Treats a notice naming only the subject as ending a single session
  • Assumes every identity provider issues a session identifier
  • Keys the index on the subject alone, ignoring which issuer sent it
  • Keeps one session row per user, so other devices are unreachable