Skip to content

OpenClaw gateway integration: token auth sends wrong field + missing scopes for bridge #438

@artwist-polyakov

Description

@artwist-polyakov

Summary

The OpenClaw gateway integration (agent-deck openclaw) has several issues that prevent it from working with a real OpenClaw gateway (tested with OpenClaw v2026.3.24, gateway protocol v3, auth.mode = "token").

Issues Found

1. Token sent in wrong JSON field (critical)

In internal/openclaw/client.go:340, the gateway token is sent as password instead of token:

// current (broken)
Auth: &ConnectAuth{
    Password: c.password,
},

// fix
Auth: &ConnectAuth{
    Token: c.password,
},

Result: connect rejected: NOT_PAIRED: device identity required — gateway ignores the password field when auth.mode = "token".

2. Insufficient scopes requested

The client only requests operator.admin scope:

Scopes: []string{"operator.admin"},

But agents.list requires operator.read, and chat.send requires operator.write. Should be:

Scopes: []string{"operator.admin", "operator.read", "operator.write", "operator.approvals"},

3. agents.list fails with token auth — no snapshot fallback

Even after requesting operator.read, OpenClaw gateway with token auth does not grant it. The agent list IS available in the hello-ok snapshot (snapshot.health.agents), but the client has no fallback to use it.

Suggested fix: If agents.list RPC fails, extract agents from client.Hello().Snapshot.Health:

func (c *Client) agentsFromSnapshot() *AgentsListResult {
    var health struct {
        DefaultAgentID string `json:"defaultAgentId"`
        Agents []struct {
            AgentID string `json:"agentId"`
            Name    string `json:"name"`
        } `json:"agents"`
    }
    json.Unmarshal(c.hello.Snapshot.Health, &health)
    // ... map to AgentsListResult
}

4. Bridge TUI crashes on startup (panic: makeslice: len out of range)

BridgeModel.View() is called before WindowSizeMsg arrives. textInput.Width gets set to a negative value at line 139:

m.textInput.Width = m.width - len("openclaw> ") - 1  // m.width is 0 → -11

Fix: Clamp m.width to minimum 20 and tiWidth to minimum 1.

5. Token auth cannot get operator.write scope — bridge chat unusable

This is the main blocker. OpenClaw gateway intentionally limits token auth to operator.admin scope only. The chat.send RPC requires operator.write, which is only available to paired devices (Ed25519 keypair + deviceToken).

The current client has no device pairing support. The gateway's connect params JSON schema doesn't accept deviceId/publicKey/hasDeviceIdentity as top-level fields, and it's unclear where exactly the device identity should be placed in the connect request.

Questions for maintainer:

  • Is device pairing support planned for the OpenClaw integration?
  • How should the device identity be passed in the connect params? (The gateway schema rejects it at root level and inside client and auth)
  • Would it make sense to add a gateway.auth.tokenScopes config option on the OpenClaw side to allow full scopes for token auth on loopback connections?

Environment

  • agent-deck: v0.26.4
  • OpenClaw: v2026.3.24 (protocol v3)
  • Gateway auth mode: token, bind: loopback
  • macOS (darwin/arm64)
  • Connection via SSH tunnel to remote Mac Mini running OpenClaw

Workarounds Applied (in our fork)

  1. Fixed token field: PasswordToken in ConnectAuth
  2. Added operator.read + operator.write to requested scopes
  3. Added snapshot fallback for agents.list
  4. Fixed bridge TUI crash with width clamping
  5. openclaw status, list, sync work; bridge chat blocked by missing write scope

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions