mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-09 08:21:50 +00:00
fix(dashboard): honor injected HERMES_DASHBOARD_SESSION_TOKEN
The desktop shell mints a session token and signs its /api + /api/ws calls with it via HERMES_DASHBOARD_SESSION_TOKEN, but the main-merge restored a web_server.py that ignored the env var and minted its own random _SESSION_TOKEN -- so every desktop request 401'd and the UI reported "gateway offline". Read the injected token (fall back to a fresh random one) so loopback HTTP + WS auth line up. Adds a regression test so a future merge can't silently drop the read.
This commit is contained in:
parent
5335869de4
commit
960ea8a849
2 changed files with 35 additions and 3 deletions
|
|
@ -85,10 +85,13 @@ app = FastAPI(title="Hermes Agent", version=__version__)
|
|||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Session token for protecting sensitive endpoints (reveal).
|
||||
# Generated fresh on every server start — dies when the process exits.
|
||||
# Injected into the SPA HTML so only the legitimate web UI can use it.
|
||||
# The desktop shell mints the token and injects it via
|
||||
# HERMES_DASHBOARD_SESSION_TOKEN so its main process can authenticate the
|
||||
# /api calls it makes on the user's behalf; otherwise we generate one fresh
|
||||
# on every server start. Either way it dies when the process exits and is
|
||||
# injected into the SPA HTML so only the legitimate web UI can use it.
|
||||
# ---------------------------------------------------------------------------
|
||||
_SESSION_TOKEN = secrets.token_urlsafe(32)
|
||||
_SESSION_TOKEN = os.environ.get("HERMES_DASHBOARD_SESSION_TOKEN") or secrets.token_urlsafe(32)
|
||||
_SESSION_HEADER_NAME = "X-Hermes-Session-Token"
|
||||
|
||||
# In-browser Chat tab (/chat, /api/pty, …). Off unless ``hermes dashboard --tui``
|
||||
|
|
|
|||
|
|
@ -89,6 +89,35 @@ class TestRedactKey:
|
|||
assert "not set" in result.lower() or result == "***" or "\x1b" in result
|
||||
|
||||
|
||||
class TestSessionTokenInjection:
|
||||
"""The desktop shell mints HERMES_DASHBOARD_SESSION_TOKEN and signs its
|
||||
/api + /api/ws calls with it. The backend must adopt that token, else every
|
||||
desktop request 401s ("gateway is offline"). A main-merge once silently
|
||||
dropped this read — this guards the contract, not a literal value.
|
||||
"""
|
||||
|
||||
def test_honors_injected_token(self, monkeypatch):
|
||||
import importlib
|
||||
import hermes_cli.web_server as ws
|
||||
|
||||
monkeypatch.setenv("HERMES_DASHBOARD_SESSION_TOKEN", "desktop-seeded-token")
|
||||
try:
|
||||
importlib.reload(ws)
|
||||
assert ws._SESSION_TOKEN == "desktop-seeded-token"
|
||||
finally:
|
||||
monkeypatch.delenv("HERMES_DASHBOARD_SESSION_TOKEN", raising=False)
|
||||
importlib.reload(ws)
|
||||
|
||||
def test_falls_back_to_random_token(self, monkeypatch):
|
||||
import importlib
|
||||
import hermes_cli.web_server as ws
|
||||
|
||||
monkeypatch.delenv("HERMES_DASHBOARD_SESSION_TOKEN", raising=False)
|
||||
importlib.reload(ws)
|
||||
|
||||
assert ws._SESSION_TOKEN and len(ws._SESSION_TOKEN) >= 32
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# web_server tests (FastAPI endpoints)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue