Skip to content

[P6.7.4] WebSocket auth ignores CODEFRAME_AUTH_REQUIRED — sessions/terminal UI broken in no-auth mode #676

Description

@frankbria

Problem

REST and WebSocket auth disagree about CODEFRAME_AUTH_REQUIRED=false (the documented local no-auth opt-out). When auth is disabled, the REST API works without credentials but the terminal and session-chat WebSockets still demand a JWT and close the connection, so the sessions UI and embedded terminal are partially unusable in no-auth mode.

Surfaced during the #643 review (codex). Deferred from PR #675 as a pre-existing inconsistency out of scope for the secret-validation fix.

Evidence

  • codeframe/auth/dependencies.pyrequire_auth() returns a synthetic local principal when auth_required() is false:
    if not auth_required():
        return {"type": "disabled", "user_id": None, "scopes": [...]}
    So every REST router admits unauthenticated requests in no-auth mode.
  • codeframe/ui/routers/terminal_ws.py_authenticate_websocket() closes with 4001 on a missing token unconditionally; it never consults auth_required().
  • codeframe/ui/routers/session_chat_ws.py — same: _authenticate_websocket() closes with 1008 on a missing token, no auth_required() check.

Net effect: CODEFRAME_AUTH_REQUIRED=false → REST 200, WS connections rejected → sessions chat + terminal don't work.

Note: this fails closed (WS denies rather than over-admits), so it is a usability/consistency bug, not an auth-bypass vulnerability. The secure default path (CODEFRAME_ALLOW_INSECURE_SECRET=1, which keeps auth ON) already works for WS; #675 updated the docs to steer local users toward it.

Fix options

  1. Honor auth_required() in the WS auth helpers (preferred): when auth is disabled, skip the token requirement and attach the same synthetic local principal REST uses (e.g. user_id=None / a local-admin id), keeping behavior symmetric with require_auth(). Factor the no-auth decision into one shared helper so REST and WS can't drift again.
  2. Alternatively, document explicitly that CODEFRAME_AUTH_REQUIRED=false does not disable WebSocket auth and is not a full local-dev mode (partly done in QUICKSTART by fix(security): hard-fail on default AUTH_SECRET whenever auth is enabled (#643) #675), and point users to CODEFRAME_ALLOW_INSECURE_SECRET=1 instead.

Acceptance criteria

  • With CODEFRAME_AUTH_REQUIRED=false, a terminal WS and a session-chat WS connect without a token and operate (matching REST behavior), OR the no-auth opt-out is clearly scoped in docs as REST-only with the recommended alternative.
  • REST and WS share a single source of truth for the no-auth decision (no duplicated auth_required() logic that can drift).
  • Tests: WS connects in no-auth mode (or is documented as intentionally rejecting), and still rejects a missing/invalid token when auth is enabled.

Source: #643 / PR #675 cross-family review (codex), 2026-06-14.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2-medium-betaMedium priority - nice to have for betaphase-6.7Phase 6.7: Frontend/UX hardening (post-beta-tag)securityux

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions