Skip to content

fix(dashboard): let CORS preflights bypass token gate - #59422

Open
kohoj wants to merge 1 commit into
NousResearch:mainfrom
kohoj:codex/fix-dashboard-cors-preflight-59052
Open

fix(dashboard): let CORS preflights bypass token gate#59422
kohoj wants to merge 1 commit into
NousResearch:mainfrom
kohoj:codex/fix-dashboard-cors-preflight-59052

Conversation

@kohoj

@kohoj kohoj commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Problem

Fixes #59052.

Loopback dashboard CORS allows localhost origins, but token-protected /api/* preflight requests never reached CORSMiddleware. A cross-port localhost SPA that sends X-Hermes-Session-Token triggers OPTIONS /api/... first; browsers do not include that token on preflight, so the legacy dashboard token middleware returned 401 with no CORS headers and the real request was never sent.

Root Cause

auth_middleware wraps the earlier-registered CORSMiddleware in loopback mode. It treated tokenless CORS preflights exactly like real protected API calls, even though preflights are only asking whether the configured CORS policy allows the follow-up request.

Fix

Detect true browser CORS preflights (OPTIONS + Origin + Access-Control-Request-Method) in the loopback token gate and pass them through to CORSMiddleware. The actual follow-up request still has to carry X-Hermes-Session-Token or the legacy bearer token.

Tests

  • $HOME/.hermes/hermes-agent/venv/bin/python -m pytest tests/hermes_cli/test_dashboard_auth_gate.py::test_loopback_cors_preflight_to_protected_api_uses_cors_policy -q
  • $HOME/.hermes/hermes-agent/venv/bin/python -m pytest tests/hermes_cli/test_dashboard_auth_gate.py -q
  • scripts/run_tests.sh tests/hermes_cli/test_dashboard_auth_gate.py
  • $HOME/.hermes/hermes-agent/venv/bin/python -m ruff check hermes_cli/web_server.py tests/hermes_cli/test_dashboard_auth_gate.py

Duplicate check: searched open/all PRs for #59052, CORS, preflight, and OPTIONS preflight before implementation; no competing PR found.

@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard comp/dashboard Web dashboard / control panel UI (dashboard/, landing) area/auth Authentication, OAuth, credential pools P2 Medium — degraded but workaround exists labels Jul 6, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Competing cluster for #59052 (dashboard OPTIONS preflight 401s because auth middleware sits outside CORS), all on hermes_cli/web_server.py:

Same goal, different/refined mechanisms — related_to, not duplicate. A maintainer should pick between the reorder (#59072) and short-circuit approaches; this PR's true-preflight guard is the tightest short-circuit.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused fix. Current main still registers CORSMiddleware at hermes_cli/web_server.py:299 before the later HTTP middleware decorators, while auth_middleware returns 401 for tokenless protected /api/ requests at hermes_cli/web_server.py:589-595. The reported loopback preflight path therefore remains affected.

Suggested changes

  • Consider adding a no-Origin regression case: OPTIONS plus Access-Control-Request-Method must still reach the token gate. The proposed _is_cors_preflight guard correctly requires both headers, but the added test currently covers only the allowed true-preflight case.

The change itself is narrowly scoped: it passes only real browser preflights through to the existing CORS policy, while the actual request still reaches the existing token checks.

Automated hermes-sweeper review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/cli CLI entry point, hermes_cli/, setup wizard comp/dashboard Web dashboard / control panel UI (dashboard/, landing) P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OPTIONS preflight returns 401 on /api/* — dashboard auth middleware ordered before CORS

3 participants