Safeguard
Security Guides•

OIDC back-channel logout: how to end sessions across apps

Back-channel logout lets an identity provider tell each app to end a user's session by server call. See the logout token, the checks and the limits.

Safeguard Security Team
3 min read

OIDC back-channel logout lets the identity provider call each app directly, server to server, to end a user's session. It does not depend on the user's browser reaching every app. The app validates a signed logout token, clears the session, and answers with HTTP 200.

Why logout is hard in single sign-on

With SSO, a user may hold sessions in many apps. Logging out of one app, or being disabled at the provider, does not automatically close the rest. Front-channel methods rely on the browser loading hidden pages for each app, which is fragile. Back-channel logout moves the signal to a direct HTTP call.

How it works

  1. Each app registers a backchannel_logout_uri, an absolute URI with no fragment. It should use https.
  2. The provider advertises backchannel_logout_supported, and optionally backchannel_logout_session_supported for session IDs.
  3. When a session ends, the provider POSTs a form encoded logout_token to each registered URI.

The logout token

A signed JWT, similar to an ID token. Required claims:

  • iss, aud, iat, exp, jti
  • events, containing the member http://schemas.openid.net/event/backchannel-logout
  • sub or sid, or both

The nonce claim is prohibited, so the token cannot be misused as an ID token. If sid is missing, the app should end all its sessions for that user, identified by iss and sub. Typing the token with typ of logout+jwt is recommended but may break existing deployments.

What the app must check

In order:

  1. Decrypt if needed. If encryption was negotiated and the token arrives unencrypted, reject it.
  2. Verify the signature. alg must not be none.
  3. Validate iss, aud, iat and exp.
  4. Confirm sub or sid is present.
  5. Confirm events has the backchannel logout member.
  6. Confirm nonce is absent.
  7. Optionally, detect replay with jti.

On failure, return HTTP 400. On success, clear the session state and return 200 with Cache-Control: no-store. If the user is already logged out, that still counts as success. The app should also revoke refresh tokens issued without offline_access.

Limits to plan for

  • Cookies and local storage are not available, so the app needs its own session store that it can look up by sid or sub. Stateless cookie only sessions cannot be ended this way without extra design.
  • The app's logout endpoint must be reachable from the provider. Apps behind a firewall or NAT cannot easily use public providers.
  • Delivery may be less reliable than expected, since retransmission is limited. Keep session lifetimes bounded as a backstop.

Design tips

  • Store the provider's sid with each session when you create it.
  • Make the logout endpoint idempotent.
  • Do not require user cookies on it.
  • Log accepted and rejected logout tokens.
  • Test by logging out at the provider and confirming each app drops the session within seconds.

Quick check

Does back-channel logout end the provider's own session?

It is a message from the provider to apps after a session ends. It tells apps to end their sessions. Handling of the provider session depends on the provider.

Why is nonce banned in the logout token?

So an attacker cannot present a logout token as an ID token to sign someone in.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.