From f0f886ecc454e8e0574d0de6c7e052c1f73b8f58 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 24 Feb 2026 01:35:40 +0000 Subject: [PATCH] docs(security): clarify gateway-node trust boundary in docs --- SECURITY.md | 9 +++++++++ docs/gateway/security/index.md | 12 ++++++++++++ docs/tools/exec-approvals.md | 12 ++++++++++++ docs/tools/exec.md | 5 ++++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index dbe2ad84a97..809f7ba4fb0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -126,6 +126,15 @@ OpenClaw's security model is "personal assistant" (one trusted operator, potenti - Security boundaries come from host/config trust, auth, tool policy, sandboxing, and exec approvals. - Prompt injection by itself is not a vulnerability report unless it crosses one of those boundaries. +## Gateway and Node trust concept + +OpenClaw separates routing from execution, but both remain inside the same operator trust boundary: + +- **Gateway** is the control plane. If a caller passes Gateway auth, they are treated as a trusted operator for that Gateway. +- **Node** is an execution extension of the Gateway. Pairing a node grants operator-level remote capability on that node. +- **Exec approvals** (allowlist/ask UI) are operator guardrails to reduce accidental command execution, not a multi-tenant authorization boundary. +- For untrusted-user isolation, split by trust boundary: separate gateways and separate OS users/hosts per boundary. + ## Workspace Memory Trust Boundary `MEMORY.md` and `memory/*.md` are plain workspace files and are treated as trusted local operator state. diff --git a/docs/gateway/security/index.md b/docs/gateway/security/index.md index 69251914469..880f869ca7f 100644 --- a/docs/gateway/security/index.md +++ b/docs/gateway/security/index.md @@ -79,6 +79,18 @@ This is acceptable when everyone using that agent is in the same trust boundary If you mix personal and company identities on the same runtime, you collapse the separation and increase personal-data exposure risk. +## Gateway and node trust concept + +Treat Gateway and node as one operator trust domain, with different roles: + +- **Gateway** is the control plane and policy surface (`gateway.auth`, tool policy, routing). +- **Node** is remote execution surface paired to that Gateway (commands, device actions, host-local capabilities). +- A caller authenticated to the Gateway is trusted at Gateway scope. After pairing, node actions are trusted operator actions on that node. +- `sessionKey` is routing/context selection, not per-user auth. +- Exec approvals (allowlist + ask) are guardrails for operator intent, not hostile multi-tenant isolation. + +If you need hostile-user isolation, split trust boundaries by OS user/host and run separate gateways. + ## Trust boundary matrix Use this as the quick model when triaging risk: diff --git a/docs/tools/exec-approvals.md b/docs/tools/exec-approvals.md index 30eae3221c5..0e6d0f52899 100644 --- a/docs/tools/exec-approvals.md +++ b/docs/tools/exec-approvals.md @@ -25,6 +25,12 @@ Exec approvals are enforced locally on the execution host: - **gateway host** → `openclaw` process on the gateway machine - **node host** → node runner (macOS companion app or headless node host) +Trust model note: + +- Gateway-authenticated callers are trusted operators for that Gateway. +- Paired nodes extend that trusted operator capability onto the node host. +- Exec approvals reduce accidental execution risk, but are not a per-user auth boundary. + macOS split: - **node host service** forwards `system.run` to the **macOS app** over local IPC. @@ -119,6 +125,12 @@ When **Auto-allow skill CLIs** is enabled, executables referenced by known skill are treated as allowlisted on nodes (macOS node or headless node host). This uses `skills.bins` over the Gateway RPC to fetch the skill bin list. Disable this if you want strict manual allowlists. +Important trust notes: + +- This is an **implicit convenience allowlist**, separate from manual path allowlist entries. +- It is intended for trusted operator environments where Gateway and node are in the same trust boundary. +- If you require strict explicit trust, keep `autoAllowSkills: false` and use manual path allowlist entries only. + ## Safe bins (stdin-only) `tools.exec.safeBins` defines a small list of **stdin-only** binaries (for example `jq`) diff --git a/docs/tools/exec.md b/docs/tools/exec.md index 1123d3068d2..1dc5cc4fc1d 100644 --- a/docs/tools/exec.md +++ b/docs/tools/exec.md @@ -122,12 +122,15 @@ running after `tools.exec.approvalRunningNoticeMs`, a single `Exec running` noti ## Allowlist + safe bins -Allowlist enforcement matches **resolved binary paths only** (no basename matches). When +Manual allowlist enforcement matches **resolved binary paths only** (no basename matches). When `security=allowlist`, shell commands are auto-allowed only if every pipeline segment is allowlisted or a safe bin. Chaining (`;`, `&&`, `||`) and redirections are rejected in allowlist mode unless every top-level segment satisfies the allowlist (including safe bins). Redirections remain unsupported. +`autoAllowSkills` is a separate convenience path in exec approvals. It is not the same as +manual path allowlist entries. For strict explicit trust, keep `autoAllowSkills` disabled. + Use the two controls for different jobs: - `tools.exec.safeBins`: small, stdin-only stream filters.