Skip to content

Dashboard Logout does not perform OIDC RP-initiated logout — users re-authenticated by silent renewal #617

@doublehelix46

Description

@doublehelix46

Environment

  • Dashboard: netbirdio/dashboard:latest (v2.36.0 at time of report)
  • Server: netbirdio/netbird:latest combined image, v0.69.0
  • IdP topology: embedded Dex federated (OIDC connector) to an external IdP (Authentik 2026.2.1)
  • Auth config: AUTH_AUTHORITY=https://<host>/oauth2 (Dex), USE_AUTH0=false

Summary

Clicking Logout in the dashboard clears local OIDC tokens client-side but never initiates RP-initiated logout against the configured authority. Because silent_renew / silent auth is still active, the SPA immediately re-authenticates against Dex (which still has a valid session cookie) and the user is returned to the dashboard as if nothing happened.

Steps to reproduce

  1. Sign in to the dashboard via an external IdP federated through the embedded Dex.
  2. Click the user menu → Logout.
  3. Observe: the page briefly flickers, then lands back at the dashboard, still authenticated.

What I found in the built bundle

In chunk bda14900bb28840a.js the OIDC config builder computes:

end_session_endpoint: new URL("v2/logout", I.authority).href

…but the actual Logout handler is:

logout: async () => t("/", { client_id: d.clientId })

It clears tokens and navigates to /. It never navigates to end_session_endpoint, never passes id_token_hint, and never sets post_logout_redirect_uri. The computed end-session URL is unused.

Expected behavior

Logout should perform RP-initiated logout per the OIDC spec:

GET {end_session_endpoint}?id_token_hint={last_id_token}&post_logout_redirect_uri={dashboard_origin}&client_id={client_id}

so the upstream (Dex, and transitively the federated IdP) can terminate the session.

Suggested fix

Either:

  • (a) Have the Logout handler navigate to the computed end_session_endpoint with id_token_hint + post_logout_redirect_uri; fall back to {authority}/v2/logout when the discovery doc doesn't advertise one.
  • (b) Add an optional AUTH_END_SESSION_URL env var (parallel to AUTH_AUTHORITY) so operators with external IdPs can point logout directly at the upstream end_session_endpoint, bypassing Dex.

Impact

Any self-hosted Netbird deployment where the embedded Dex federates to an external IdP: Logout is effectively a no-op as long as the upstream SSO cookie survives. Workarounds (JS shim, Traefik redirect on /v2/logout) exist but are fragile.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions