Skip to content

feat(web_server): allow remote WebSocket connection via HERMES_DASHBOARD_ALLOW_REMOTE_WS - #33099

Closed
0BVer wants to merge 1 commit into
NousResearch:mainfrom
0BVer:fix/websocket-ip-check
Closed

feat(web_server): allow remote WebSocket connection via HERMES_DASHBOARD_ALLOW_REMOTE_WS#33099
0BVer wants to merge 1 commit into
NousResearch:mainfrom
0BVer:fix/websocket-ip-check

Conversation

@0BVer

@0BVer 0BVer commented May 27, 2026

Copy link
Copy Markdown

Description

Recently, WebSocket client validation in the dashboard was hardened to loopback-only hosts. While this enhances security, it blocks normal dashboard operations in containerized (Docker bridge networks) or proxied (Caddy, Nginx, Cloudflare Tunnel) setups since the client IP appears as a gateway/non-loopback IP.

This PR introduces an optional environment variable HERMES_DASHBOARD_ALLOW_REMOTE_WS. If enabled, it allows WebSocket connections from non-loopback hosts. By default (unset), it remains loopback-only to maintain the hardened security baseline.

Proposed Changes

  1. hermes_cli/web_server.py: Updated _ws_client_is_allowed to check env_var_enabled('HERMES_DASHBOARD_ALLOW_REMOTE_WS') and return True if enabled.
  2. hermes_cli/config.py: Registered HERMES_DASHBOARD_ALLOW_REMOTE_WS in OPTIONAL_ENV_VARS for UI and configuration visibility.
  3. tests/hermes_cli/test_web_server.py: Added a dedicated unit test test_ws_client_is_allowed_bypasses_loopback_when_remote_ws_enabled.

@0BVer
0BVer force-pushed the fix/websocket-ip-check branch from 3e978ad to 071b5ea Compare May 27, 2026 07:41
@0BVer
0BVer force-pushed the fix/websocket-ip-check branch from 071b5ea to c0a5674 Compare May 27, 2026 07:48
@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard area/config Config system, migrations, profiles labels May 27, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Competing with #32614 (fix(dashboard): allow websocket clients for public binds) which takes a different approach — respecting the existing public bind/--insecure flag rather than adding a new env var. Also related: #25072 (broader 3-bug fix), #32953 (TRUST_LAN env var approach). The area is saturated with open PRs addressing the same regression from #30741 loopback hardening.

@0BVer

0BVer commented May 27, 2026

Copy link
Copy Markdown
Author

Hi @alt-glitch, thank you for pointing out the other PRs addressing this regression!

While respecting the existing --insecure / public bind flags (as in #32614) is a straightforward approach, we believe this environment variable approach provides better granular security control.

The Tradeoff with --insecure

Using --insecure forces the HTTP API server to expose itself completely, which increases the attack surface.

In many containerized or proxied environments (like running behind Caddy, Nginx, or a Cloudflare Tunnel inside a Docker bridge network), users want to keep their HTTP API secured behind session tokens, but only need to bypass the strict loopback-only client check for WebSockets (because Docker gateways translate the client IP).

If we rely solely on --insecure to fix the WebSocket issue, users will be forced to expose their entire HTTP API publicly just to make the dashboard's chat/events feed function properly.

Why this PR (HERMES_DASHBOARD_ALLOW_REMOTE_WS) is safer:

  1. Principle of Least Privilege: It allows users to selectively bypass the WebSocket loopback check in proxied environments without having to publicize their HTTP API endpoints.
  2. Backward Compatibility: It defaults to the hardened loopback-only configuration unless explicitly opted in.
  3. Fully Tested: This PR includes dedicated unit tests verifying both the allowed and blocked states.

We'd love to hear your thoughts on this tradeoff!

@alt-glitch alt-glitch added the comp/dashboard Web dashboard / control panel UI (dashboard/, landing) label Jun 26, 2026
@teknium1

teknium1 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Superseded by the fix already on main. --insecure + a non-loopback --host bind now allows remote WebSocket peers directly in ws_client_is_allowed() (via app.state.bound_host), so a separate HERMES_DASHBOARD_ALLOW_REMOTE_WS env var is not needed. We also avoid adding new HERMES* env vars for non-secret behavioral config as a matter of policy — the operator intent is expressed through --insecure. Closing as redundant; thanks for the contribution.

@teknium1 teknium1 closed this Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/cli CLI entry point, hermes_cli/, setup wizard comp/dashboard Web dashboard / control panel UI (dashboard/, landing) P2 Medium — degraded but workaround exists type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants