mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-11-06 13:26:40 +00:00
A token-only deployment (nix/agenix: backend.sessionTokenFile -> HERMES_DASHBOARD_SESSION_TOKEN=file:<path>) had no way to satisfy the June-2026 fail-closed gate: gated mode demands a registered DashboardAuthProvider, the interactive prompt then writes basic-auth credentials the deployment never asked for, and the provisioned token itself is rejected on every gated leg (REST 401, /api/ws 403) — the desktop's 'HTTP reachable but the WebSocket fails' incident. The bundled session_token plugin closes that: it registers whenever the session token is provisioned (skippable via dashboard.session_token_auth.enabled: false) and verify_session constant-time-compares the presented credential against it. Both legs a token-mode client uses — the REST bearer path and the /api/ws ?token= upgrade — run through that seam, so one provisioned token authorizes both. It is deliberately not an interactive login: a new interactive_login capability flag keeps it off the login page, /api/auth/providers, the auto-SSO redirect and the native provider chooser (a token-gated /login now renders a note explaining the credential channel), while supports_session stays True so the gate's verify loops consult it. Rotation semantics are pinned by tests: a saved client copy from before a secret redeploy must fail closed, not half-work.