Skip to content

bug: WebSocket connections rejected with 403 despite correct auth exclude path #549

@Aureliolo

Description

@Aureliolo

Summary

All WebSocket connections to /api/v1/ws?ticket=... are rejected with 403 Forbidden. The WS icon in the dashboard is permanently red. No real-time updates reach the frontend.

Investigation Findings

The ticket-based WS auth flow works partially:

  1. POST /api/v1/auth/ws-ticket succeeds (200, ticket issued, logged as api.ws.ticket_issued)
  2. WebSocket /api/v1/ws?ticket=... is rejected with 403 before the handler runs
  3. No api.ws.ticket_invalid, api.ws.connected, or any WS handler log lines appear -- the rejection happens at the Litestar framework level

What was ruled out

  • Auth middleware exclude path: ^/api/v1/ws$ correctly matches scope["path"] (path without query string). Verified with build_exclude_path_pattern -- returns bypass=True for /api/v1/ws.
  • Router guard: require_password_changed returns immediately when user is None (line 198-199 of auth/controller.py). Not the cause.
  • Channels plugin: create_ws_route_handlers=False -- plugin doesn't create competing routes.
  • Route registration: WebSocketRoute at /api/v1/ws is registered with a valid route_handler.
  • Nginx proxy: WS connections go directly to backend (port 8000), not through nginx. The 403 is from Litestar/uvicorn.

What needs investigation

The 403 comes from the Litestar ASGI pipeline itself, somewhere between the middleware stack and the WS handler. Possible causes:

  • Litestar's internal WS upgrade handling may require a non-None user scope even when middleware is excluded
  • The ScopeType.WEBSOCKET in the auth middleware scopes may cause an unexpected interaction
  • A Litestar version-specific behavior with WS + auth middleware exclusion

Reproducer

synthorg start
# Open http://localhost:3000 -- WS icon is red
# Backend logs show repeated:
# INFO: 172.18.0.3:NNNNN - "WebSocket /api/v1/ws?ticket=..." 403
# INFO: connection rejected (403 Forbidden)

Acceptance Criteria

  • WebSocket connections succeed when a valid ticket is provided
  • WS handler logs show api.ws.connected after successful ticket validation
  • Dashboard WS icon turns green
  • Real-time events (tasks, agents, budget) flow to the dashboard

Metadata

Metadata

Assignees

No one assigned

    Labels

    prio:highImportant, should be prioritizedscope:medium1-3 days of workspec:human-interactionDESIGN_SPEC Section 13 - Human Interaction Layerspec:securityDESIGN_SPEC Section 12 - Security & Approval Systemtype:fixBug fixes and corrections

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions