Files
openclaw/docs/gateway/operator-scopes.md
Peter Steinberger 938749180e refactor(nodes)!: retire arming leases for durable capability enablement (#114892)
* refactor(nodes): retire phone control leases

* fix(doctor): clean retired phone control state

* docs(nodes): document durable capability enablement

* docs(changelog): defer node enablement note

* fix(doctor): harden retired phone control cleanup

* fix(doctor): fail closed on unreadable lease state

* fix(doctor): validate retired lease journals

* fix(doctor): preserve deny-shadowed consent

* docs: refresh node authorization map

* fix(doctor): keep retirement helpers private
2026-07-27 23:51:30 -04:00

8.0 KiB

summary, read_when, title
summary read_when title
Operator roles, scopes, and approval-time checks for Gateway clients
Debugging missing operator scope errors
Reviewing device or node pairing approvals
Adding or classifying Gateway RPC methods
Operator scopes

Operator scopes gate what a Gateway client can do after it authenticates. They are a control-plane guardrail inside one trusted Gateway operator domain, not hostile multi-tenant isolation. For strong separation between people, teams, or machines, run separate Gateways under separate OS users or hosts.

Related: Security, Gateway protocol, Gateway pairing, Devices CLI.

Roles

Every Gateway WebSocket client connects with one role:

  • operator: control-plane clients such as CLI, Control UI, automation, and trusted helper processes.
  • node: capability hosts (macOS, iOS, Android, headless) that expose commands through node.invoke.

Operator RPC methods require the operator role; node-originated methods require the node role.

Scope levels

Scope Meaning
operator.read Read-only status, lists, catalog, logs, session reads, and other non-mutating calls.
operator.write Mutating operator actions: sending messages, invoking tools, updating talk/voice settings, node command relay. Also satisfies operator.read.
operator.admin Administrative access. Satisfies every operator.* scope. Required for config mutation, updates, native hooks, reserved namespaces, and high-risk approvals.
operator.pairing Device and node pairing management: list, approve, reject, remove, rotate, revoke.
operator.approvals Exec and plugin approval APIs.
operator.questions Listing, reading, answering, and resolving interactive questions.
operator.talk.secrets Reading Talk configuration with secrets included.

Unknown future operator.* scopes require an exact match unless the caller already holds operator.admin.

Method scope is only the first gate

Each Gateway RPC has a least-privilege method scope that decides whether a request reaches its handler. Params-aware methods derive that scope before dispatch so authorization failures have one canonical structured response:

  • agent needs operator.write for ordinary turns and operator.admin for /new or /reset session lifecycle commands.
  • node.invoke needs operator.write for ordinary relay commands and operator.admin for browser.proxy, fs.listDir, and terminal.upload.
  • talk.config needs operator.read; includeSecrets: true also needs operator.talk.secrets.

Some handlers then apply stricter checks based on the concrete thing being approved or mutated:

  • device.pair.approve is reachable with operator.pairing, but approving an operator device can only mint or preserve scopes the caller already holds.
  • node.pair.approve is reachable with operator.pairing, then derives extra approval scopes from the pending node's declared command list.
  • chat.send is a write-scoped method, but the /config set and /config unset chat commands require operator.admin on top of that, regardless of the caller's chat-send scope.

This lets lower-scope operators perform low-risk pairing actions without making all pairing approval admin-only.

Session mutation RPCs are authorized by their negotiated operator scopes, independent of the connecting client's client.id or client.mode. Client identity can still affect connection and device-auth policy, but it neither grants nor removes session mutation authority.

Device pairing approvals

Device pairing records are the durable source of approved roles and scopes. An already-paired device does not get broader access silently: a reconnect that asks for a broader role or broader scopes creates a new pending upgrade request.

Approving a device request:

  • A request with no operator role does not need operator scope approval.
  • A request for a non-operator device role (for example node) requires operator.admin, even though device.pair.approve itself only needs operator.pairing.
  • A request for operator.read, operator.write, operator.approvals, operator.questions, operator.pairing, or operator.talk.secrets requires the caller to already hold that scope, or operator.admin.
  • A request for operator.admin requires operator.admin.
  • A repair request with no explicit scopes can inherit the existing operator token's scopes; if that token is admin-scoped, approval still requires operator.admin.

Non-admin shared-secret and trusted-proxy sessions can only approve operator-device requests within their own declared operator scopes; approving non-operator roles is admin-only even when those sessions can otherwise use operator.pairing.

For paired-device token sessions, management is self-scoped unless the caller has operator.admin: a non-admin caller sees only its own pairing entries, and can approve, reject, rotate, revoke, or remove only its own device entry.

Node pairing approvals

Legacy node.pair.* methods use a separate Gateway-owned node pairing store. WS nodes use device pairing (role: node) instead, but the same approval vocabulary applies. See Gateway pairing for how the two stores relate.

node.pair.approve derives extra required scopes from the pending request's command list:

Declared commands Required scopes
none operator.pairing
ordinary node commands operator.pairing + operator.write
system.run, system.run.prepare, system.which, browser.proxy, fs.listDir, or system.execApprovals.get/set operator.pairing + operator.admin

Approving a node declaration records its command surface. For computer.act, the node advertises that surface only after Computer Control is enabled locally; once the pairing update is approved, invoking it through node.invoke requires write scope but not admin scope for each action. Commands classified as dangerous or privacy-heavy still require a persistent gateway.nodes.commands.allow entry in addition to pairing.

Node pairing establishes identity and trust; it does not replace a node's own system.run exec approval policy.

Shared-secret auth

Shared gateway token/password auth is treated as trusted operator access for that Gateway. OpenAI-compatible HTTP surfaces, /tools/invoke, and HTTP session-history endpoints restore the full default operator scope set for shared-secret bearer auth, even if a caller sends narrower declared scopes.

Identity-bearing modes, such as trusted proxy auth or private-ingress none, can still honor explicit declared scopes. Use separate Gateways for real trust boundary separation.