Logging out of an OIDC session also ends the central Auth session - #1516
Merged
Merged
Conversation
TLDR Signing out of Fleet used to clear only Fleet's cookies. A user signed in through central Auth still had a live Auth session, so with silent SSO auto-start the next page load signed them straight back in and "log out" looked broken. For OIDC-minted sessions the logout now hands the browser to the provider's sign-out endpoint, which on Elcano Auth ends the central session, tells every application to drop its sessions, and lands on Auth's login page. What changed, and why POST /api/auth/logout still clears elcano_session and both shapes of the legacy elcano_auth cookie. It now also verifies the presented session cookie: when its source is "oidc" and FLEET_OIDC_* is configured, the 303 targets `<issuer>/logout?client_id=<client id>` (OpenID Connect RP-Initiated Logout, implemented by Elcano Auth in ElcanoTek/auth#36) instead of /login. Password sessions, and any request without a verifiable cookie, keep landing on /login exactly as before. Auth's back-channel fan-out then rotates Fleet's external epoch; the cookie is already gone, so that is belt and braces. How you verified it - Vitest (logout route, 7 tests): an OIDC session token → 303 to https://auth.example.com/logout?client_id=fleet with elcano_session cleared; a password session token with OIDC configured → /login; the existing cookie-shape tests unchanged. npm run lint and npm run typecheck clean; build and Playwright left to CI. Scope and deviations No change to the legacy elcano_auth handling or to password logout. Requires Auth with RP-initiated logout deployed first; an older Auth answers 405 to the GET. No ADR: no invariant touched.
…SSO transactions Review follow-ups (design critique by the second reviewer): - Every non-OIDC logout (password session, no or unverifiable cookie) now lands on /login?manual=1 instead of /login, so FLEET_OIDC_AUTO_START cannot silently sign the browser back in when an Auth cookie happens to exist. - The three OIDC transaction cookies (state, nonce, verifier) are cleared with the session cookies, so a callback still in flight cannot mint a fresh session after the user asked to leave. - The provider logout URL is built with the URL API rather than string concatenation, and the response carries Cache-Control: no-store. Tests updated for the new landing and the extra deletions; lint and typecheck clean.
A malformed FLEET_OIDC_ISSUER made new URL() throw before the response was built, turning logout into a 500 that left every cookie in place. Logout now still clears the cookies and lands on /login?manual=1 in that case; test added.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed, and why
Signing out of Fleet used to clear only Fleet's cookies. A user signed in through central Auth still had a live Auth session, so with silent SSO auto-start (#1514) the next page load signed them straight back in and "log out" looked broken.
POST /api/auth/logoutstill clearselcano_sessionand both shapes of the legacyelcano_authcookie. It now also verifies the presented session cookie: when its source isoidcandFLEET_OIDC_*is configured, the 303 targets<issuer>/logout?client_id=<client id>(OpenID Connect RP-Initiated Logout, implemented by Elcano Auth in ElcanoTek/auth#36) instead of/login. On Elcano Auth that ends the central session, fans a back-channel logout out to every registered application, and lands on Auth's login page. Password sessions, and any request without a verifiable cookie, land on/login?manual=1: the card with both options and no silent SSO attempt, so a logout cannot be undone by auto-start while an Auth cookie happens to exist. The three OIDC transaction cookies are cleared too, and a malformed issuer falls back to the same local landing instead of failing. Auth's back-channel fan-out then rotates Fleet's external epoch; the cookie is already gone, so that is belt and braces.How you verified it
https://auth.example.com/logout?client_id=fleetwithelcano_sessioncleared; a password session token with OIDC configured →/login; the existing cookie-shape tests unchanged.npm run lintandnpm run typecheckclean; build and Playwright left to CI.Scope and deviations
No change to the legacy
elcano_authhandling or to password logout. Requires Auth with RP-initiated logout deployed first; an older Auth answers 405 to the GET. No ADR: no invariant touched. Docs:central-auth-integration.mddescribes the flow.docs/features/central-auth-integration.mdupdated)