hermes-agent/hermes_cli/dashboard_auth
Ben 884f0da82a feat(dashboard-auth): auth gate middleware + /auth/* routes + /login HTML
Phase 3, Tasks 3.2 + 3.3 + 3.4. These three pieces are mutually
dependent so they land together.

middleware.py - gated_auth_middleware engages when app.state.auth_required
is True.  Allowlists /login, /auth/*, /api/auth/providers, and static
asset paths; everything else demands a valid session_at cookie.  Verifies
by trying every registered provider's verify_session in turn (multi-
provider stack); attaches verified Session to request.state.session.
Returns 401 JSON for /api/* and 302 -> /login for HTML.  ProviderError
during verify -> 503.

routes.py - APIRouter with:
  GET  /login              server-rendered HTML
  GET  /auth/login?provider=N  302 to IDP + PKCE cookie
  GET  /auth/callback?code,state  completes login, sets session cookies
  POST /auth/logout        clears cookies + best-effort revoke
  GET  /api/auth/providers public bootstrap endpoint (503 if zero)
  GET  /api/auth/me        verified session as JSON (auth-required)

login_page.py - Inline-CSS HTML template, no React, no JavaScript.

web_server.py - Mounted gated_auth_middleware between host_header and
auth_middleware (FastAPI runs middlewares in registration order: host
check -> cookie auth -> token auth).  auth_middleware short-circuits
when auth_required so cookie auth is authoritative in gated mode.
Router is included before mount_spa so the catch-all doesn't swallow
/login or /auth/*.

17 new behavioural tests; loopback regression harness still green.
2026-05-21 15:19:44 +10:00
..
__init__.py feat(dashboard-auth): define DashboardAuthProvider ABC + Session dataclass 2026-05-21 15:07:02 +10:00
audit.py feat(dashboard-auth): json-lines audit log at $HERMES_HOME/logs/dashboard-auth.log 2026-05-21 15:10:55 +10:00
base.py feat(dashboard-auth): define DashboardAuthProvider ABC + Session dataclass 2026-05-21 15:07:02 +10:00
cookies.py feat(dashboard-auth): cookie helpers for session_at/session_rt/pkce 2026-05-21 15:14:56 +10:00
login_page.py feat(dashboard-auth): auth gate middleware + /auth/* routes + /login HTML 2026-05-21 15:19:44 +10:00
middleware.py feat(dashboard-auth): auth gate middleware + /auth/* routes + /login HTML 2026-05-21 15:19:44 +10:00
registry.py feat(dashboard-auth): define DashboardAuthProvider ABC + Session dataclass 2026-05-21 15:07:02 +10:00
routes.py feat(dashboard-auth): auth gate middleware + /auth/* routes + /login HTML 2026-05-21 15:19:44 +10:00