Skip to content

fix: follow IdP end-session redirect on admin sign-out#69

Open
ahmedai1 wants to merge 1 commit into
ClickHouse:mainfrom
ahmedai1:fix/admin-logout-end-session
Open

fix: follow IdP end-session redirect on admin sign-out#69
ahmedai1 wants to merge 1 commit into
ClickHouse:mainfrom
ahmedai1:fix/admin-logout-end-session

Conversation

@ahmedai1
Copy link
Copy Markdown

@ahmedai1 ahmedai1 commented Jun 4, 2026

Problem

Fixes #68.

When the admin panel runs with ADMIN_SSO_ONLY=true against an OpenID provider using RP-initiated logout (OPENID_USE_END_SESSION_ENDPOINT=true on the LibreChat server), the Sign out button never actually signs you out. It clears the local session, returns to /login, and the page auto-redirects back to the IdP — which still has a live session — silently re-authenticating the same account. The user can never sign out or switch accounts.

Root cause

adminLogoutFn (src/server/auth.ts) POSTs to LibreChat's /api/auth/logout but ignores the response body. With OPENID_USE_END_SESSION_ENDPOINT=true, that endpoint returns the IdP end_session URL in { redirect }. Discarding it means only the local cookie is cleared and the IdP session survives.

LibreChat's own web client handles this correctly: its AuthContext logout handler reads data.redirect and follows it via window.location. This PR mirrors that behaviour in the admin panel.

Change

  • adminLogoutFn: parse the logout response and surface redirect.
  • Sidebar.handleLogout: when redirect is present, follow it via window.location; otherwise fall back to the existing /login navigation.

The response is parsed with a small zod schema (consistent with the existing refreshResponseSchema pattern in the same file) and the remote logout call stays wrapped in try/catch, so a failed/absent logout response still clears the local session as before.

Verification

  • tsc --noEmit clean.
  • eslint src/server/auth.ts src/components/Sidebar.tsx --max-warnings 0 clean.

Note

Medium Risk
Changes the logout path for SSO/OpenID deployments; behavior is gated on an optional redirect with the same local-session fallback as before.

Overview
Sign out now completes RP-initiated OpenID logout when the backend returns an IdP end-session URL.

adminLogoutFn parses the LibreChat /api/auth/logout JSON (optional redirect via zod) and returns it after clearing the local session. Sidebar handleLogout navigates with window.location.href when that URL is present; otherwise it keeps the existing invalidate + /login flow. Remote logout failures still only clear the admin cookie, unchanged.

Reviewed by Cursor Bugbot for commit 558f4c3. Bugbot is set up for automated code reviews on this repo. Configure here.

adminLogoutFn POSTs to LibreChat's /api/auth/logout but ignores the
response body. With OPENID_USE_END_SESSION_ENDPOINT=true, that endpoint
returns the IdP end_session URL in { redirect }. Because the response is
discarded, only the local session cookie is cleared and the IdP session
survives. With ADMIN_SSO_ONLY=true the /login page then auto-redirects
back to the IdP, which silently re-authenticates the same account — a
sign-out loop where the user can never sign out or switch accounts.

Parse the logout response and surface redirect; Sidebar.handleLogout
follows it via window.location when present, mirroring LibreChat's own
AuthContext logout handling.
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jun 4, 2026

CLA assistant check
All committers have signed the CLA.

@danny-avila
Copy link
Copy Markdown
Contributor

@ahmedai1
Copy link
Copy Markdown
Author

ahmedai1 commented Jun 5, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Admin panel sign-out does not terminate the IdP session (OpenID sign-out loop)

3 participants