SSO Logout
Implement RP-Initiated and Backchannel Logout with Trousseau.
Overview
Trousseau supports two logout mechanisms:
- RP-Initiated Logout — Your application redirects the user to Trousseau's end-session endpoint
- 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:
- Clear your application session (cookies, server-side session store)
- 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| Parameter | Required | Description |
|---|---|---|
id_token_hint | Recommended | The ID token from the user's session. Helps Trousseau identify which session to invalidate. |
post_logout_redirect_uri | Recommended | Where 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 pageExample (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
- User logs out from another Trousseau-connected application
- Trousseau sends a signed JWT (
logout_token) to your backchannel logout endpoint via POST - 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-logoutEndpoint 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
| Claim | Description |
|---|---|
iss | Trousseau issuer URL |
sub | User ID being logged out |
aud | Your client ID |
iat | Token issuance time |
jti | Unique token identifier (prevent replay) |
events | Contains 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_tokenin 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)