hermes - 💡(How to fix) Fix [Feature]: Dashboard logout should redirect to the IdP end-session endpoint (RP-initiated logout)

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Fix Action

Fix / Workaround

  • Front-channel logout (iframe): Requires the dashboard to expose a front-channel logout endpoint. More complex, and the IdP must be configured for it. RP-initiated logout is simpler and already supported by all major OIDC providers.
  • Plugin monkey-patch of auth_logout: Works locally but the DashboardAuthProvider interface is the right place for this — it benefits all providers.

Code Example

class DashboardAuthProvider(ABC):
    # ... existing methods ...

    def get_end_session_url(self) -> Optional[str]:
        """Return the IdP end-session URL for RP-initiated logout, or None."""
        return None  # default: providers that don't support it do nothing

---

# After revoking tokens and clearing cookies:
for provider in list_providers():
    end_url = provider.get_end_session_url()
    if end_url:
        params = urlencode({"post_logout_redirect_uri": f"{prefix}/login"})
        return RedirectResponse(url=f"{end_url}?{params}", status_code=302)

return RedirectResponse(url=f"{prefix}/login", status_code=302)
RAW_BUFFERClick to expand / collapse

When a user logs out of the Hermes dashboard (POST /auth/logout), the handler:

  1. Revokes the refresh token via provider.revoke_session()
  2. Clears dashboard session cookies
  3. Redirects to /login

The user's session at the identity provider (Nous Portal, Authentik, Keycloak, etc.) is not terminated. On the next login attempt, the browser's IdP session cookie is still valid, so the OAuth flow re-authenticates automatically — the user never sees a credential prompt again.

This means logout is incomplete: the dashboard logs you out, but the IdP keeps you signed in. The only way to fully log out is to manually navigate to the IdP's end_session_endpoint.

Proposed Solution

The DashboardAuthProvider interface (base.py) has five abstract methods today. A sixth — get_end_session_url() — could allow providers to expose their OIDC end_session_endpoint for RP-initiated logout:

class DashboardAuthProvider(ABC):
    # ... existing methods ...

    def get_end_session_url(self) -> Optional[str]:
        """Return the IdP end-session URL for RP-initiated logout, or None."""
        return None  # default: providers that don't support it do nothing

The auth_logout handler in routes.py could then redirect to the IdP after clearing local cookies:

# After revoking tokens and clearing cookies:
for provider in list_providers():
    end_url = provider.get_end_session_url()
    if end_url:
        params = urlencode({"post_logout_redirect_uri": f"{prefix}/login"})
        return RedirectResponse(url=f"{end_url}?{params}", status_code=302)

return RedirectResponse(url=f"{prefix}/login", status_code=302)

Providers that support it (OIDC providers with end_session_endpoint in their discovery document) override the method. Others return None and the current behavior is unchanged.

The bundled Nous provider would return None by default (the Nous Portal doesn't currently expose end_session_endpoint). Custom OIDC providers (Authentik, Keycloak, etc.) that already have OIDC discovery can return their endpoint.

Prerequisite on the IdP side: operators must register the dashboard's /login URL in the IdP's allowed Logout Redirect URIs (standard OIDC requirement for post_logout_redirect_uri).

Alternatives Considered

  • Front-channel logout (iframe): Requires the dashboard to expose a front-channel logout endpoint. More complex, and the IdP must be configured for it. RP-initiated logout is simpler and already supported by all major OIDC providers.
  • Plugin monkey-patch of auth_logout: Works locally but the DashboardAuthProvider interface is the right place for this — it benefits all providers.

Feature Type

Gateway / messaging improvement

Scope

Small (single file, < 50 lines)

This issue was drafted by an AI assistant (GLaDOS, Aperture Science) under human supervision and reviewed by the reporter before submission.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix [Feature]: Dashboard logout should redirect to the IdP end-session endpoint (RP-initiated logout)