Skip to content

[Bug]: Dashboard shows "Connected" and "Health OK" but "Error: missing scope: operator.read" - no data with token-only auth #17095

@Al3xand3r1987

Description

@Al3xand3r1987

Summary *

With token-only gateway auth (no device identity), the Control UI connects and shows "Connected" / "Health OK", but Overview, Instances, Sessions, etc. all show "Error: missing scope: operator.read" and no data. The server accepts the connection but leaves scopes empty, so every operator method call fails.

Steps to reproduce *

1. Configure gateway with token auth (e.g. gateway.auth.mode: "token", gateway.auth.token set).
2. Allow Control UI without device (e.g. gateway.controlUi.dangerouslyDisableDeviceAuth: true or allowInsecureAuth).
3. Open Control UI in browser (e.g. http://<host>:18789), enter gateway token, click Connect.
4. Open Overview, then Instances or Sessions.

Expected behavior *

Overview and Instances/Sessions load and show gateway data (instances count, uptime, session list, etc.). No "missing scope: operator.read" errors once connected with valid token.

Actual behavior *

Dashboard shows "Connected" and "Health OK", but Overview, Instances, Sessions, and other tabs show "Error: missing scope: operator.read" and no data. Only the connection succeeds; all subsequent API calls that require operator.read fail.

OpenClaw version *

2026.2.14

Operating system *

Linux (Debian 6.1) / Docker

(Adjust if you use e.g. macOS/Windows.)


Install method

Docker (openclaw:skills), gateway on port 18789

Logs, screenshots, and evidence

Screenshot: Dashboard with "Connected", "Health OK", and red "Error: missing scope: operator.read" on Overview/Instances.

Root cause (from code): In src/gateway/server/ws-connection/message-handler.ts, when the client has no device identity, scopes are set to [] (line ~433). So token-only Control UI connections get no scopes and every operator.* method returns "missing scope: operator.read".

Impact and severity

Affected: Users running Control UI with token-only auth (e.g. over HTTP, or from another machine without device pairing).
Severity: Medium–high (dashboard is effectively read-only and shows no useful data despite "Connected").
Frequency: 100% when connecting with token only and no device identity.
Consequence: Cannot use dashboard to monitor instances, sessions, or cron; misleading "Health OK" suggests everything is fine.

Proposed fix

Idea: When the client is the Control UI, sends no device, and token/password auth succeeded (canSkipDevice), grant full operator scopes instead of []. Then the Control UI can call all operator methods with token-only auth.

File: src/gateway/server/ws-connection/message-handler.ts
Place: After the block that rejects with "device required" (after if (!canSkipDevice) { ... return; }), only when !device and canSkipDevice and isControlUi.

Code to add:

// Token-only control UI: grant full operator scopes so dashboard can read data
if (isControlUi && scopes.length === 0) {
  scopes = [
    "operator.read",
    "operator.write",
    "operator.admin",
    "operator.approvals",
    "operator.pairing",
  ];
  connectParams.scopes = scopes;
}

Security: Only clients that (1) identify as Control UI, (2) send no device, and (3) have already authenticated with the correct token/password get these scopes. Tested locally and in Docker; existing test "allows control ui without device identity when insecure auth is enabled" still passes. Happy to open a PR if this direction is wanted.


Additional information

Proposed fix (for maintainer feedback): When the client is Control UI, there is no device, and shared-secret auth succeeded (canSkipDevice), grant full operator scopes instead of leaving them empty. That way token-only dashboard connections can read/write like a device-paired UI. Change is ~10 lines in message-handler.ts; I tested it locally and the dashboard then loads all data. Existing test "allows control ui without device identity when insecure auth is enabled" still passes. Happy to open a PR if this direction is wanted.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions