Skip to content

fix(dashboard-auth): skip auto-SSO redirect for password-only providers - #54887

Closed
sjfkai wants to merge 1 commit into
NousResearch:mainfrom
sjfkai:fix/password-provider-auto-sso-redirect
Closed

fix(dashboard-auth): skip auto-SSO redirect for password-only providers#54887
sjfkai wants to merge 1 commit into
NousResearch:mainfrom
sjfkai:fix/password-provider-auto-sso-redirect

Conversation

@sjfkai

@sjfkai sjfkai commented Jun 29, 2026

Copy link
Copy Markdown

Summary

Fix a NotImplementedError crash when the dashboard is bound to a
non-loopback host with a password-only auth provider (e.g.
BasicAuthProvider).

Background

PR #54846 introduced _auto_sso_response() to silently bounce
unauthenticated users through the portal OAuth flow when exactly one
interactive provider is registered. The assumption was that a single
provider would always be an OAuth provider — but BasicAuthProvider
sets supports_password = True and has no OAuth redirect flow. Its
start_login() raises NotImplementedError:

File "hermes_cli/dashboard_auth/routes.py", line 197, in auth_login
    ls = p.start_login(redirect_uri=_redirect_uri(request))
File "plugins/dashboard_auth/basic/__init__.py", line 230, in start_login
    raise NotImplementedError(
NotImplementedError: BasicAuthProvider is password-only; there is no
OAuth redirect flow. The login page POSTs to /auth/password-login instead.

This only triggers when all of the following hold:

  1. Dashboard binds to a non-loopback address (--host 0.0.0.0)
  2. Auth gate is active (auth_required = True)
  3. Only BasicAuthProvider is registered (no OAuth provider)
  4. User has no existing session cookie

Fix

In _auto_sso_response(), check supports_password before attempting
the OAuth redirect. When the sole provider is password-only, return
None so the caller falls through to the normal /login interstitial
which renders the username/password form.

Testing

Verified locally:

  • --host 0.0.0.0 with BasicAuthProvider only → login page renders
    correctly (was: 500 NotImplementedError)
  • --host 127.0.0.1 → auth gate inactive, unaffected
  • Multiple providers → already returns None at the len != 1 check,
    unaffected

_auto_sso_response unconditionally redirects a single provider to
/auth/login (the OAuth PKCE entry point).  BasicAuthProvider is the
only registered provider in password-only setups, and its
start_login() raises NotImplementedError because it has no OAuth
redirect flow.

Check supports_password before attempting the OAuth redirect; when
True, fall through to the normal /login interstitial which renders
the username/password form wired to /auth/password-login.
@alt-glitch alt-glitch added type/bug Something isn't working comp/dashboard Web dashboard / control panel UI (dashboard/, landing) area/auth Authentication, OAuth, credential pools P2 Medium — degraded but workaround exists labels Jun 29, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: LGTM — clean fix for dashboard auth with password-only providers.

Small, targeted fix that correctly skips auto-SSO redirect for password-only providers.


Reviewed by Hermes Agent

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: LGTM

Clean, well-scoped change with no concerns.

--- Reviewed by Hermes Agent

@thesunofdog

Copy link
Copy Markdown

Confirmed independently on a macOS + Tailscale dashboard setup.

Setup:

  • current main
  • hermes dashboard --host 0.0.0.0 --port 9119
  • dashboard.basic_auth.username/password_hash/secret configured
  • no OAuth provider registered

Before the fix, unauthenticated / redirected to /auth/login?provider=basic, where BasicAuthProvider.start_login() raised NotImplementedError, producing HTTP 500 instead of the login form.

We independently landed on the same supports_password=True guard in _auto_sso_response(). Applying it locally fixed the live setup: unauthenticated / reaches the login form, password login succeeds, and authenticated / returns 200.

+1 from another real-world setup that this PR fixes the right failure mode.

This was referenced Jul 4, 2026
@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Closing as superseded by #61330 (merged to main as commit 4734071).

Your supports_password auto-SSO guard in middleware.py was the correct fix — #61330 (salvaging @shannonsands' #61281) includes the same guard plus the sibling routes.py/auth_login redirect site, the hosted/mobile cookie-auth OAuth path, and device-code copy fixes, so it fully covers what this PR addressed. Credit to you for the guard — thanks @sjfkai!

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

Labels

area/auth Authentication, OAuth, credential pools comp/dashboard Web dashboard / control panel UI (dashboard/, landing) P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants