Skip to content

Dashboard WebSocket endpoints (/api/ws, /api/events) return 403 even with --insecure mode #34396

@yang-zhou

Description

@yang-zhou

Title:

Dashboard WebSocket endpoints (/api/ws, /api/events) return 403 even with --insecure mode
Body:

Description

Dashboard WebSocket endpoints /api/ws and /api/events return 403 Forbidden even when HERMES_DASHBOARD_INSECURE=1 is set. This affects both remote and localhost access. The HTTP pages and REST API work fine — only WebSocket connections are rejected.

Steps to Reproduce

  1. Run hermes-agent with the latest s6-overlay Docker image

  2. Set HERMES_DASHBOARD=1, HERMES_DASHBOARD_HOST=0.0.0.0, HERMES_DASHBOARD_INSECURE=1

  3. Access the dashboard — pages load normally

  4. Observe browser console errors:
    WebSocket connection to 'ws://:9119/api/ws?token=...' failed WebSocket connection to 'ws://:9119/api/events?token=...' failed

  5. Verify with curl from inside the container against localhost:

curl -i -N \
  -H "Connection: Upgrade" \
  -H "Upgrade: websocket" \
  -H "Sec-WebSocket-Version: 13" \
  -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
  "http://127.0.0.1:9119/api/ws"

Returns 403 Forbidden (after fixing the key format, returns 101 only without the token check).

Expected Behavior

When HERMES_DASHBOARD_INSECURE=1 is set, WebSocket endpoints should be accessible without OAuth authentication, same as the HTTP REST API endpoints.

Actual Behavior

HTTP pages: ✅ accessible
REST API (/api/status, /api/sessions, etc.): ✅ accessible
WebSocket (/api/ws, /api/events): ❌ 403 Forbidden

Impact

Chat tab (TUI in browser) is completely non-functional
Real-time event updates don't work
Affects all users running dashboard in Docker with --insecure on trusted LANs

Environment

Docker image: nousresearch/hermes-agent:latest (s6-overlay version)
OS: UGOS (UGREEN NAS)
HERMES_DASHBOARD_INSECURE=1 confirmed working for HTTP
Dashboard run script confirms --insecure flag is passed

Analysis

The --insecure flag appears to bypass the OAuth auth gate for HTTP requests but the WebSocket endpoint has a separate token verification path that is not affected by the --insecure flag. The frontend obtains a token and passes it as a query parameter, but the backend rejects it regardless.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existsarea/dockerDocker image, Compose, packagingcomp/cliCLI entry point, hermes_cli/, setup wizardtype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions