KeySuiteTrousseau

SSO Logout

Implement RP-Initiated and Backchannel Logout with Trousseau.

Overview

Trousseau supports two logout mechanisms:

  1. RP-Initiated Logout — Your application redirects the user to Trousseau's end-session endpoint
  2. Backchannel Logout — Trousseau notifies your application when a user logs out from another app

RP-Initiated Logout

When your user clicks "Log out", you should:

  1. Clear your application session (cookies, server-side session store)
  2. Redirect to Trousseau's end-session endpoint to terminate the SSO session

End-session URL

GET https://auth.keysuite.app/application/o/{your-slug}/end-session/
  ?id_token_hint={id_token}
  &post_logout_redirect_uri=https://app.yourapp.com/signed-out
ParameterRequiredDescription
id_token_hintRecommendedThe ID token from the user's session. Helps Trousseau identify which session to invalidate.
post_logout_redirect_uriRecommendedWhere to redirect the user after logout. Must be a registered redirect URI.

Flow

User clicks "Log out"
  → Your app clears its own session
  → Redirect to Trousseau /end-session/
  → Trousseau invalidates the SSO session
  → Trousseau redirects to post_logout_redirect_uri
  → User sees your signed-out page

Example (Next.js)

export async function logout() {
  const session = await getSession();
  const idToken = session?.idToken;

  // Clear your application session
  await destroySession();

  // Redirect to Trousseau end-session
  const logoutUrl = new URL(
    `${process.env.OIDC_ISSUER}end-session/`
  );
  logoutUrl.searchParams.set("id_token_hint", idToken);
  logoutUrl.searchParams.set(
    "post_logout_redirect_uri",
    "https://app.yourapp.com/signed-out"
  );

  redirect(logoutUrl.toString());
}

Backchannel Logout

Backchannel Logout allows Trousseau to notify your application when a user logs out from another connected app (or directly from Trousseau).

How it works

  1. User logs out from another Trousseau-connected application
  2. Trousseau sends a signed JWT (logout_token) to your backchannel logout endpoint via POST
  3. Your application validates the token and destroys all sessions for that user

Setup

Register a backchannel logout URL during onboarding:

https://app.yourapp.com/api/auth/backchannel-logout

Endpoint implementation

export async function POST(request: Request) {
  const body = await request.formData();
  const logoutToken = body.get("logout_token") as string;

  // 1. Validate the JWT signature using Trousseau's JWKS
  const payload = await validateLogoutToken(logoutToken);

  // 2. Extract the user's sub claim
  const userId = payload.sub;

  // 3. Destroy all sessions for this user
  await destroyUserSessions(userId);

  return new Response(null, { status: 200 });
}

Logout token claims

ClaimDescription
issTrousseau issuer URL
subUser ID being logged out
audYour client ID
iatToken issuance time
jtiUnique token identifier (prevent replay)
eventsContains http://schemas.openid.net/event/backchannel-logout

Always validate the logout token signature before processing. An unvalidated token could be used to forcefully log out your users.

Best practices

  • Always implement RP-Initiated Logout at minimum
  • Store the id_token in the server session so it's available at logout time
  • Implement Backchannel Logout for the best user experience across the ecosystem
  • Return HTTP 200 from the backchannel endpoint even if the user has no active session (idempotent)