Skip to content

Logging out of an OIDC session also ends the central Auth session - #1516

Merged
jzhao234 merged 3 commits into
mainfrom
feat/logout-ends-central-session
Sep 16, 2026
Merged

jzhao234 merged 3 commits into
mainfrom
feat/logout-ends-central-session

Conversation

@jzhao234

@jzhao234 jzhao234 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

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/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. 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

  • 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. Docs: central-auth-integration.md describes the flow.


  • The title and "What changed, and why" are written for the release notes they become
  • A design note added, if this ships a feature (docs/features/central-auth-integration.md updated)
  • An ADR added or superseded, if this adds, weakens or reverses an invariant (none touched)
  • The diff is scoped to one change

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.
@jzhao234
jzhao234 merged commit c43255f into main Sep 16, 2026
21 checks passed
@jzhao234
jzhao234 deleted the feat/logout-ends-central-session branch September 16, 2026 02:59
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.

1 participant