What
The intelligent agent's WebSocket, /api/intelligent_agent/stream (autobot-backend/api/intelligent_agent.py, websocket_stream, around line 254), accepts any client without authentication and runs the goal it is sent:
if not await enforce_ws_origin(websocket):
return
await websocket.accept()
...
data = await websocket.receive_json()
...
async for chunk in agent.process_natural_language_goal(goal, context=context):
enforce_ws_origin is the only check. By its own docstring it returns True when the handshake origin is allowed or absent, and a non-browser client simply omits the Origin header.
intelligent_agent.router is APIRouter(tags=[...]) with no dependencies, and its registry entry (initialization/router_registry/core_routers.py, _get_agent_routers) adds none.
- The HTTP twin of this operation,
POST /api/intelligent_agent/process, does require Depends(get_current_user). The WebSocket is therefore a direct unauthenticated bypass of an authenticated route. The endpoint's docstring says clients "send natural language goals and receive real-time updates as the agent processes and executes commands".
The deployed backend runs the same code (host evidence, read-only, 2026-09-18).
Found during the independent review of #16939 (WebSocket subprotocol auth), which enumerated the raw websocket.accept() sites that call no authenticator.
Acceptance criteria
Related
What
The intelligent agent's WebSocket,
/api/intelligent_agent/stream(autobot-backend/api/intelligent_agent.py,websocket_stream, around line 254), accepts any client without authentication and runs the goal it is sent:enforce_ws_originis the only check. By its own docstring it returns True when the handshake origin is allowed or absent, and a non-browser client simply omits theOriginheader.intelligent_agent.routerisAPIRouter(tags=[...])with no dependencies, and its registry entry (initialization/router_registry/core_routers.py,_get_agent_routers) adds none.POST /api/intelligent_agent/process, does requireDepends(get_current_user). The WebSocket is therefore a direct unauthenticated bypass of an authenticated route. The endpoint's docstring says clients "send natural language goals and receive real-time updates as the agent processes and executes commands".The deployed backend runs the same code (host evidence, read-only, 2026-09-18).
Found during the independent review of #16939 (WebSocket subprotocol auth), which enumerated the raw
websocket.accept()sites that call no authenticator.Acceptance criteria
/streamauthenticates before processing anything, with at least the same principal requirement asPOST /process(a verified user). An unauthenticated or invalid-token handshake is closed with a policy-violation close code before anyreceive_json./processpasses it, never anonymously.process_natural_language_goal(negative control).Related