Skip to main content

Command policy

After device pairing, node commands must satisfy three requirements before they can be invoked:
  1. The node must declare the command in its authenticated connect metadata (connect.commands).
  2. The command must be in the node’s approved command surface on its paired-device record.
  3. The Gateway’s platform-and-approval-derived allowlist must include the declared command.
Use openclaw nodes pending and openclaw nodes approve <nodeRequestId> to approve a pending surface. This request ID differs from the device request ID. An initial unapproved surface has no effective commands. During a pending expansion, only previously approved commands that remain declared and allowed stay effective. Local exec approvals and operating-system permissions still apply after these checks. Default allowlists by platform (before plugin defaults and commands.allow/commands.deny overrides): These rows describe the Gateway policy ceiling, not the commands implemented by every node app. A command is usable only when the connected node also declares it. In particular, Android advertises mobile UI commands only while Accessibility Control is enabled, and desktop nodes advertise computer.act only while their local Computer Control fulfiller is enabled. The current macOS app does not declare the device and personal-data families listed in the macOS policy row. Plugin-owned defaults extend the platform table only for the plugin’s supported surface: The Canvas commands present hosted widget documents in the macOS app’s native panel. iOS, Android, Windows, Linux, and unknown platforms do not receive Canvas plugin defaults. talk.ptt.start, talk.ptt.stop, talk.ptt.cancel, and talk.ptt.once are allowed by default for any node that advertises the talk capability or declares talk.* commands, independent of platform label. Desktop host commands (system.run, system.run.prepare, system.which, browser.proxy, browser.proxy.upload.v1, mcp.tools.call.v1, and screen.snapshot on macOS/Windows/Linux) are not part of the static platform-default table above. They become available once the operator approves a pairing request that declares them, after which the node’s approved command set carries them forward on reconnect. Dangerous or privacy-heavy commands require a one-time persistent opt-in with gateway.nodes.commands.allow, even if a node declares them: camera.snap, camera.clip, camera.ptz.control, desktop.stream, screen.record, contacts.add, calendar.add, reminders.add, health.summary, sms.send, sms.search. gateway.nodes.commands.deny always wins over defaults and extra allowlist entries. See Paired node desktops, HealthKit summaries, and Computer use for the local enablement, pairing, capability, and tool-policy gates around desktop access. Plugin-owned node commands can add a Gateway node-invoke policy. That policy runs after the allowlist check and before forwarding to the node, so raw node.invoke, CLI helpers, and dedicated agent tools share the same plugin permission boundary. Dangerous plugin node commands still require explicit gateway.nodes.commands.allow opt-in. After a node expands its declared commands, capabilities, or permissions, reconnect it, inspect openclaw nodes pending, and approve the widened surface with openclaw nodes approve <nodeRequestId>. Removing declarations does not grant new access or require approval for an expansion.

Config (openclaw.json)

Node-related settings live under gateway.nodes and tools.exec:
Use exact node command names. commands.deny removes a command even when a platform default or commands.allow entry would otherwise allow it. Paired nodes may publish agent-visible plugin tool descriptors by default, but each descriptor’s command must still be in the node’s approved command surface. Set gateway.nodes.pluginTools.enabled: false to ignore all such descriptors. See Gateway configuration reference for gateway node pairing and command-policy field details. Per-agent exec node override:

Permissions map

Nodes may include a permissions map in node.list / node.describe, keyed by permission name (e.g. screenRecording, accessibility, location) with boolean values (true = granted).