mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 04:50:23 +00:00
docs(security): clarify node pairing trust boundary
This commit is contained in:
@@ -66,17 +66,20 @@ Notes:
|
||||
- `node.pair.request` is idempotent per node: repeated calls return the same
|
||||
pending request.
|
||||
- Repeated requests for the same pending node also refresh the stored node
|
||||
metadata and allowlisted command set, so reconnect-driven repair flows do not
|
||||
stay stuck on stale pending data.
|
||||
metadata and the latest allowlisted declared command snapshot for operator visibility.
|
||||
- Approval **always** generates a fresh token; no token is ever returned from
|
||||
`node.pair.request`.
|
||||
- Requests may include `silent: true` as a hint for auto-approval flows.
|
||||
|
||||
If a node is already paired but reconnects while declaring allowlisted commands
|
||||
that are missing from its approved node record, the gateway creates a repair
|
||||
pairing request. The current connection stays fail-closed on the previously
|
||||
approved command set until that repair request is approved and the node
|
||||
reconnects again.
|
||||
Important:
|
||||
|
||||
- Node pairing is a trust/identity flow plus token issuance.
|
||||
- It does **not** pin the live node command surface per node.
|
||||
- Live node commands come from what the node declares on connect after the
|
||||
gateway's global node command policy (`gateway.nodes.allowCommands` /
|
||||
`denyCommands`) is applied.
|
||||
- Per-node `system.run` allow/ask policy lives on the node in
|
||||
`exec.approvals.node.*`, not in the pairing record.
|
||||
|
||||
## Auto-approval (macOS app)
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ These patterns are commonly reported and are usually closed as no-action unless
|
||||
- Claims that classify normal operator read-path access (for example `sessions.list`/`sessions.preview`/`chat.history`) as IDOR in a shared-gateway setup.
|
||||
- Localhost-only deployment findings (for example HSTS on loopback-only gateway).
|
||||
- Discord inbound webhook signature findings for inbound paths that do not exist in this repo.
|
||||
- Reports that treat node pairing metadata as a hidden second per-command approval layer for `system.run`, when the real execution boundary is still the gateway's global node command policy plus the node's own exec approvals.
|
||||
- "Missing per-user authorization" findings that treat `sessionKey` as an auth token.
|
||||
|
||||
## Researcher preflight checklist
|
||||
@@ -370,10 +371,18 @@ stronger isolation between agents, run them under separate OS users or separate
|
||||
If a macOS node is paired, the Gateway can invoke `system.run` on that node. This is **remote code execution** on the Mac:
|
||||
|
||||
- Requires node pairing (approval + token).
|
||||
- Gateway node pairing is not a per-command approval surface. It establishes node identity/trust and token issuance.
|
||||
- The Gateway applies a coarse global node command policy via `gateway.nodes.allowCommands` / `denyCommands`.
|
||||
- Controlled on the Mac via **Settings → Exec approvals** (security + ask + allowlist).
|
||||
- The per-node `system.run` policy is the node's own exec approvals file (`exec.approvals.node.*`), which can be stricter or looser than the gateway's global command-ID policy.
|
||||
- Approval mode binds exact request context and, when possible, one concrete local script/file operand. If OpenClaw cannot identify exactly one direct local file for an interpreter/runtime command, approval-backed execution is denied rather than promising full semantic coverage.
|
||||
- If you don’t want remote execution, set security to **deny** and remove node pairing for that Mac.
|
||||
|
||||
This distinction matters for triage:
|
||||
|
||||
- A reconnecting paired node advertising a different command list is not, by itself, a vulnerability if the Gateway global policy and the node's local exec approvals still enforce the actual execution boundary.
|
||||
- Reports that treat node pairing metadata as a second hidden per-command approval layer are usually policy/UX confusion, not a security boundary bypass.
|
||||
|
||||
## Dynamic skills (watcher / remote nodes)
|
||||
|
||||
OpenClaw can refresh the skills list mid-session:
|
||||
|
||||
@@ -62,7 +62,8 @@ If you see `NODE_BACKGROUND_UNAVAILABLE`, bring the node app to the foreground a
|
||||
These are different gates:
|
||||
|
||||
1. **Device pairing**: can this node connect to the gateway?
|
||||
2. **Exec approvals**: can this node run a specific shell command?
|
||||
2. **Gateway node command policy**: is the RPC command ID allowed by `gateway.nodes.allowCommands` / `denyCommands` and platform defaults?
|
||||
3. **Exec approvals**: can this node run a specific shell command locally?
|
||||
|
||||
Quick checks:
|
||||
|
||||
@@ -74,12 +75,10 @@ openclaw approvals allowlist add --node <idOrNameOrIp> "/usr/bin/uname"
|
||||
```
|
||||
|
||||
If pairing is missing, approve the node device first.
|
||||
If pairing is fine but `system.run` fails, fix exec approvals/allowlist.
|
||||
If `nodes describe` is missing a command, check the gateway node command policy and whether the node actually declared that command on connect.
|
||||
If pairing is fine but `system.run` fails, fix exec approvals/allowlist on that node.
|
||||
|
||||
If `nodes describe` shows the node connected but the expected command is missing,
|
||||
the approved node-pair record may be stale. In that case, reconnecting the node
|
||||
should create a repair pairing request; approve it, then reconnect once more so
|
||||
the gateway can expose the refreshed command set.
|
||||
Node pairing is an identity/trust gate, not a per-command approval surface. For `system.run`, the per-node policy lives in that node's exec approvals file (`openclaw approvals get --node ...`), not in the gateway pairing record.
|
||||
|
||||
## Common node error codes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user