docs(policy): document gateway node command policy

This commit is contained in:
Gio Della-Libera
2026-07-02 20:51:13 -07:00
parent 144e5894f6
commit fa8f10e6cd
2 changed files with 46 additions and 14 deletions
+40 -13
View File
@@ -18,13 +18,13 @@ report drift through `doctor --lint`. The final conformance signal is a clean
instead of creating a separate health gate.
Policy currently manages configured channels, MCP servers, model providers,
network SSRF posture, ingress/channel access posture, Gateway exposure posture, agent workspace posture,
network SSRF posture, ingress/channel access posture, Gateway exposure and node command posture, agent workspace posture,
data-handling posture, OpenClaw config secret provider/auth profile posture, and governed tool
declarations. For example, IT or a workspace operator can record that Telegram
is not an approved channel provider, restrict MCP servers and model refs to
approved entries, require private-network fetch/browser access to remain
disabled, require direct-message session isolation and channel ingress posture
to stay within reviewed bounds, require Gateway bind/auth/HTTP exposure to stay within reviewed
to stay within reviewed bounds, require Gateway bind/auth/HTTP exposure and privileged node commands to stay within reviewed
bounds, require agent workspace access and tool denies to stay in a reviewed
posture, require OpenClaw config SecretRefs to use managed providers, require
config auth profiles to carry provider/mode metadata, require governed tools to
@@ -114,6 +114,9 @@ file posture, and tool metadata looks like this:
"denyEndpoints": ["chatCompletions", "responses"],
"requireUrlAllowlists": true,
},
"nodes": {
"denyCommands": ["system.run"],
},
},
"agents": {
"workspace": {
@@ -181,7 +184,7 @@ when a concrete rule is present. OpenClaw reads current `channels.*` settings
`mcp.servers.*`, `models.providers.*`, selected agent model refs, network SSRF
settings, direct-message session scope, channel DM policy, channel group policy,
channel/group mention gates, Gateway bind/auth/Control UI/Tailscale/remote/HTTP
posture, OpenClaw config agent sandbox workspace access and tool deny posture,
posture, Gateway node command posture, OpenClaw config agent sandbox workspace access and tool deny posture,
data-handling config posture, config secret
provider and SecretRef provenance, config auth profile metadata, configured
global/per-agent tool posture, and `TOOLS.md` declarations as evidence, then
@@ -361,16 +364,23 @@ Every scope present in `policy.jsonc` must be valid and enforceable.
#### Gateway
| Policy field | Observed state | Use when |
| --------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------ |
| `gateway.exposure.allowNonLoopbackBind` | `gateway.bind` | Set to `false` to require loopback Gateway binding. |
| `gateway.exposure.allowTailscaleFunnel` | Tailscale serve/funnel Gateway posture | Set to `false` to deny Tailscale Funnel exposure. |
| `gateway.auth.requireAuth` | `gateway.auth.mode` | Set to `true` to reject disabled Gateway auth. |
| `gateway.auth.requireExplicitRateLimit` | `gateway.auth.rateLimit` | Set to `true` to require explicit auth rate-limit config. |
| `gateway.controlUi.allowInsecure` | Control UI insecure auth/device/origin toggles | Set to `false` to deny insecure Control UI exposure toggles. |
| `gateway.remote.allow` | Remote Gateway mode/config | Set to `false` to deny remote Gateway mode. |
| `gateway.http.denyEndpoints` | Gateway HTTP API endpoints | Deny endpoint ids such as `chatCompletions` or `responses`. |
| `gateway.http.requireUrlAllowlists` | Gateway HTTP URL-fetch inputs | Set to `true` to require URL allowlists on URL-fetch inputs. |
| Policy field | Observed state | Use when |
| --------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------ |
| `gateway.exposure.allowNonLoopbackBind` | `gateway.bind` | Set to `false` to require loopback Gateway binding. |
| `gateway.exposure.allowTailscaleFunnel` | Tailscale serve/funnel Gateway posture | Set to `false` to deny Tailscale Funnel exposure. |
| `gateway.auth.requireAuth` | `gateway.auth.mode` | Set to `true` to reject disabled Gateway auth. |
| `gateway.auth.requireExplicitRateLimit` | `gateway.auth.rateLimit` | Set to `true` to require explicit auth rate-limit config. |
| `gateway.controlUi.allowInsecure` | Control UI insecure auth/device/origin toggles | Set to `false` to deny insecure Control UI exposure toggles. |
| `gateway.remote.allow` | Remote Gateway mode/config | Set to `false` to deny remote Gateway mode. |
| `gateway.http.denyEndpoints` | Gateway HTTP API endpoints | Deny endpoint ids such as `chatCompletions` or `responses`. |
| `gateway.http.requireUrlAllowlists` | Gateway HTTP URL-fetch inputs | Set to `true` to require URL allowlists on URL-fetch inputs. |
| `gateway.nodes.denyCommands` | `gateway.nodes.denyCommands` | Require exact node command ids such as `system.run` to be denied in OpenClaw config. |
`gateway.nodes.denyCommands` is an exact, case-sensitive deny-superset rule.
Use it when policy must prove that privileged node commands are explicitly
denied by OpenClaw config. A deployment that intentionally allows a privileged
node command should update `policy.jsonc` after review instead of relying on
`gateway.nodes.allowCommands` alone.
#### Agent workspace
@@ -815,6 +825,7 @@ Policy currently verifies:
| `policy/gateway-remote-enabled` | Gateway remote mode is active when policy denies it. |
| `policy/gateway-http-endpoint-enabled` | A Gateway HTTP API endpoint is enabled while denied by policy. |
| `policy/gateway-http-url-fetch-unrestricted` | Gateway HTTP URL-fetch input lacks a required URL allowlist. |
| `policy/gateway-node-command-denied` | A node command denied by policy is not denied by OpenClaw config. |
| `policy/agents-workspace-access-denied` | Agent sandbox mode or workspace access is outside the policy allowlist. |
| `policy/agents-tool-not-denied` | An agent or default config does not deny a tool required by policy. |
| `policy/tools-profile-unapproved` | A configured global or per-agent tool profile is outside the allowlist. |
@@ -955,6 +966,22 @@ Example Gateway exposure finding:
}
```
Example Gateway node command finding:
```json
{
"checkId": "policy/gateway-node-command-denied",
"severity": "error",
"message": "Gateway node command 'system.run' is denied by policy but not denied by OpenClaw config.",
"source": "policy",
"path": "openclaw config",
"ocPath": "oc://openclaw.config/gateway/nodes/denyCommands",
"target": "oc://openclaw.config/gateway/nodes/denyCommands",
"requirement": "oc://policy.jsonc/gateway/nodes/denyCommands",
"fixHint": "Add 'system.run' to gateway.nodes.denyCommands or update policy after review."
}
```
Example agent workspace finding:
```json
+6 -1
View File
@@ -26,7 +26,7 @@ The Policy plugin contributes doctor health checks for policy-managed OpenClaw
settings and governed workspace declarations. Policy currently covers channel
conformance, governed tool metadata, MCP server posture, model-provider posture,
private-network access posture, Gateway exposure posture, agent workspace/tool
posture, configured global/per-agent tool posture, configured sandbox runtime
and node command posture, configured global/per-agent tool posture, configured sandbox runtime
posture, ingress/channel access posture, data-handling posture, and OpenClaw config secret
provider/auth profile posture.
@@ -48,6 +48,11 @@ additive `alsoAllow` entries because they can widen effective tool posture.
These checks observe config conformance only; they do not read runtime approval
state or add runtime enforcement.
Gateway node command rules can require exact, case-sensitive command ids such
as `system.run` to be present in OpenClaw config
`gateway.nodes.denyCommands`. These checks observe config conformance only;
they do not add runtime enforcement or change the gateway command allowlist.
Sandbox posture rules can require approved sandbox modes/backends, deny host
container networking, deny container namespace joins, require read-only container
mounts, deny container runtime socket mounts and unconfined container profiles,