What does the `logout_token` in a back-channel logout POST carry, and why can that notification never sign the browser out?
answer
- server to server, no browser
- one form-encoded parameter
- an events claim declares what it is
- sub or sid, at least one
- no nonce, so never an ID token
basics
~20 sThe provider POSTs a signed logout_token to the relying party's backchannel_logout_uri, carrying iss, aud, iat, jti, an events claim naming the back-channel logout event, and sub or sid. It travels server to server, so nothing in the browser is touched.
solid answer
~40 sBack-channel logout is a **direct server-to-server POST** from the provider to the relying party's registered `backchannel_logout_uri`, form-encoded with a single `logout_token` parameter. The token is a signed JWT — its container and signature checks are generic JWT work — whose claims include `iss`, `aud` naming the relying party's client, `iat`, `jti`, and an `events` claim containing `http://schemas.openid.net/event/backchannel-logout`. It MUST carry `sub` or `sid` and MAY carry both: `sub` means every session for that user at that issuer, `sid` names **one provider session**. It MUST NOT carry a `nonce`, so it can never be mistaken for an ID token. What it cannot do follows from the delivery path: the user agent is not involved at any point, so no cookie anywhere is cleared by it.
code
http · 8 linesPOST /oidc/backchannel-logout HTTP/1.1
Host: roster.example
Content-Type: application/x-www-form-urlencoded
logout_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjE3In0.eyJpc3Mi...
HTTP/1.1 200 OK
Cache-Control: no-storego deeper
Recall that the provider can tell an application directly, server to server, that a session has ended, and that this message never passes through the user's browser.
Explain the claim set: what events declares, why sub or sid must be present, what each scopes the action to, and why a nonce is prohibited.
Demonstrate the limit as clearly as the mechanism: the notification is observable and confirmable, and still cannot clear anything the browser holds.
The design question is what you can measure. Back-channel outcomes are visible to the provider, which makes them the only part of estate-wide sign-out you can put a number on.
## The exchange When a provider ends a session and a relying party has registered a `backchannel_logout_uri`, the provider makes the request itself, from its own servers, to that URI. The body is form-encoded and carries exactly one parameter, `logout_token`. The relying party answers with a success status; there is no redirect, no frame, and no browser anywhere in the exchange. That is the whole shape, and everything interesting about the mechanism follows from it in one direction or the other. ## Inside the logout token The token is a signed JWT. Verifying its container and its signature is ordinary JWT work and belongs to that subject; what is specific here is the claim set and the rules that make a logout token distinguishable from every other token the same issuer signs: - `iss` — the issuer, matched against the provider the relying party is registered with. - `aud` — the relying party's client identifier, so a token addressed to another client is rejected. - `iat` and `exp` — issued-at and expiry; a logout token is short-lived by design. - `jti` — a unique identifier, which is what makes replay detectable at all. - `events` — an object whose member name is `http://schemas.openid.net/event/backchannel-logout`, with an empty object as its value. Its presence is what declares the token to be a logout notification. - `sub`, `sid`, or both — **at least one MUST be present**. And one prohibition that is worth knowing by name: a logout token **MUST NOT contain a `nonce` claim**. That, together with the `events` member, is what stops a logout token being replayed to a relying party as though it were an ID token from a fresh sign-in. A relying party that treated an unprompted notification as proof of authentication would be signing a user in on the provider's say-so at a moment nobody asked to log in. ## `sub` versus `sid` These two say different things and the difference is operational: | Claim present | What the provider is saying | Reasonable scope of the action | |---|---|---| | `sub` only | This user, at this issuer, is being logged out | Every session the relying party holds for that `(iss, sub)` pair | | `sid` only | This one provider session has ended | Only the relying-party session bound to that `sid` | | both | This session, for this user | The named session, with the user identified for logging or policy | `backchannel_logout_session_required`, registered by the relying party, is how it tells the provider it needs a `sid` in the token — which it does whenever one user may hold several sessions at that provider and the relying party is expected to end only one of them. ## What the notification cannot do This is the half candidates skip, and it is the reason the two logout mechanisms exist side by side. 1. **It never touches the user agent.** The POST goes provider-to-relying-party. No cookie in anybody's browser is cleared by it, and the browser holding a session cookie a second ago is still holding it a second later. 2. **It reaches only registered relying parties.** A relying party that published no `backchannel_logout_uri` is not in the list, and nothing about the logout tells anyone that it was missed. 3. **It is not a guaranteed delivery.** Nothing in the exchange promises the notification arrives; a provider may or may not retry a POST that failed. What it does have, unlike the front channel, is an **observable outcome** — the provider sees the response status, so failures can at least be measured. That third point is the honest comparison. Back-channel notification is the reliable one in the sense that it can be confirmed and instrumented; it is not reliable in the sense of being guaranteed, and it is completely unable to act on browser state. ## Where it sits beside the front channel A framed front-channel request runs in the browser, so it can act on what the browser holds, and it is unobservable. A back-channel POST is observable, and it cannot touch the browser at all. Neither is a superset of the other, which is why a provider that supports both renders frames **and** posts tokens, and why an estate that wants sign-out to mean something asks its relying parties to register both. What the relying party then does with the notice — how it records that a session is dead so that the next request from that browser is refused — is the relying party's own design problem and a separate subject with its own owner. The protocol's part ends at the POST and the response to it.
- What is the difference between a logout token carrying only `sub` and one carrying only `sid`?`sub` names the user at that issuer, so the relying party is being told every session it holds for that person there has ended. `sid` names one provider session, so only the relying-party session bound to it is meant. A token must carry at least one and may carry both.
- Why is a `logout_token` forbidden from carrying a `nonce` claim?To keep it unusable as an ID token. A `nonce` belongs to a token answering an authentication request the client started; a relying party that accepted a logout token as evidence of a fresh sign-in would be authenticating a user on an unprompted notification. The `events` member serves the same separation.
- The provider gets a success response from the relying party. What has that confirmed?That the notification was delivered and accepted by that relying party's server — which is more than the front channel ever confirms. It says nothing about the browser: the user's cookie is untouched, and any screen already open stays open until that relying party refuses the next request.
saying these in an interview costs you the question
- Expects the back-channel POST to clear a cookie in the user's browser
- Treats the logout token as an ID token and looks for a nonce in it
- Assumes sid names the user rather than one provider session
- Believes every relying party is notified, including unregistered ones
- Thinks a success response means every device has been signed out