mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-18 07:47:27 +00:00
feat(sandbox): block container namespace joins by default
This commit is contained in:
@@ -32,6 +32,7 @@ For webhook ingress, it warns when `hooks.defaultSessionKey` is unset, when requ
|
||||
It also warns when sandbox Docker settings are configured while sandbox mode is off, when `gateway.nodes.denyCommands` uses ineffective pattern-like/unknown entries, when `gateway.nodes.allowCommands` explicitly enables dangerous node commands, when global `tools.profile="minimal"` is overridden by agent tool profiles, when open groups expose runtime/filesystem tools without sandbox/workspace guards, and when installed extension plugin tools may be reachable under permissive tool policy.
|
||||
It also flags `gateway.allowRealIpFallback=true` (header-spoofing risk if proxies are misconfigured) and `discovery.mdns.mode="full"` (metadata leakage via mDNS TXT records).
|
||||
It also warns when sandbox browser uses Docker `bridge` network without `sandbox.browser.cdpSourceRange`.
|
||||
It also flags dangerous sandbox Docker network modes (including `host` and `container:*` namespace joins).
|
||||
It also warns when existing sandbox browser Docker containers have missing/stale hash labels (for example pre-migration containers missing `openclaw.browserConfigEpoch`) and recommends `openclaw sandbox recreate --browser --all`.
|
||||
It also warns when npm-based plugin/hook install records are unpinned, missing integrity metadata, or drift from currently installed package versions.
|
||||
It warns when channel allowlists rely on mutable names/emails/tags instead of stable IDs (Discord, Slack, Google Chat, MS Teams, Mattermost, IRC scopes where applicable).
|
||||
|
||||
@@ -1017,7 +1017,9 @@ Optional **Docker sandboxing** for the embedded agent. See [Sandboxing](/gateway
|
||||
|
||||
**`setupCommand`** runs once after container creation (via `sh -lc`). Needs network egress, writable root, root user.
|
||||
|
||||
**Containers default to `network: "none"`** — set to `"bridge"` if the agent needs outbound access.
|
||||
**Containers default to `network: "none"`** — set to `"bridge"` (or a custom bridge network) if the agent needs outbound access.
|
||||
`"host"` is blocked. `"container:<id>"` is blocked by default unless you explicitly set
|
||||
`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true` (break-glass).
|
||||
|
||||
**Inbound attachments** are staged into `media/inbound/*` in the active workspace.
|
||||
|
||||
|
||||
@@ -138,6 +138,12 @@ scripts/sandbox-browser-setup.sh
|
||||
By default, sandbox containers run with **no network**.
|
||||
Override with `agents.defaults.sandbox.docker.network`.
|
||||
|
||||
Security defaults:
|
||||
|
||||
- `network: "host"` is blocked.
|
||||
- `network: "container:<id>"` is blocked by default (namespace join bypass risk).
|
||||
- Break-glass override: `agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`.
|
||||
|
||||
Docker installs and the containerized gateway live here:
|
||||
[Docker](/install/docker)
|
||||
|
||||
@@ -154,6 +160,7 @@ Paths:
|
||||
Common pitfalls:
|
||||
|
||||
- Default `docker.network` is `"none"` (no egress), so package installs will fail.
|
||||
- `docker.network: "container:<id>"` requires `dangerouslyAllowContainerNamespaceJoin: true` and is break-glass only.
|
||||
- `readOnlyRoot: true` prevents writes; set `readOnlyRoot: false` or bake a custom image.
|
||||
- `user` must be root for package installs (omit `user` or set `user: "0:0"`).
|
||||
- Sandbox exec does **not** inherit host `process.env`. Use
|
||||
|
||||
@@ -244,6 +244,7 @@ High-signal `checkId` values you will most likely see in real deployments (not e
|
||||
| `hooks.request_session_key_prefixes_missing` | warn/critical | No bound on external session key shapes | `hooks.allowedSessionKeyPrefixes` | no |
|
||||
| `logging.redact_off` | warn | Sensitive values leak to logs/status | `logging.redactSensitive` | yes |
|
||||
| `sandbox.docker_config_mode_off` | warn | Sandbox Docker config present but inactive | `agents.*.sandbox.mode` | no |
|
||||
| `sandbox.dangerous_network_mode` | critical | Sandbox Docker network uses `host` or `container:*` namespace-join mode | `agents.*.sandbox.docker.network` | no |
|
||||
| `tools.exec.host_sandbox_no_sandbox_defaults` | warn | `exec host=sandbox` resolves to host exec when sandbox is off | `tools.exec.host`, `agents.defaults.sandbox.mode` | no |
|
||||
| `tools.exec.host_sandbox_no_sandbox_agents` | warn | Per-agent `exec host=sandbox` resolves to host exec when sandbox is off | `agents.list[].tools.exec.host`, `agents.list[].sandbox.mode` | no |
|
||||
| `tools.exec.safe_bins_interpreter_unprofiled` | warn | Interpreter/runtime bins in `safeBins` without explicit profiles broaden exec risk | `tools.exec.safeBins`, `tools.exec.safeBinProfiles`, `agents.list[].tools.exec.*` | no |
|
||||
@@ -299,8 +300,10 @@ schema:
|
||||
- `channels.mattermost.accounts.<accountId>.dangerouslyAllowNameMatching` (extension channel)
|
||||
- `agents.defaults.sandbox.docker.dangerouslyAllowReservedContainerTargets`
|
||||
- `agents.defaults.sandbox.docker.dangerouslyAllowExternalBindSources`
|
||||
- `agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin`
|
||||
- `agents.list[<index>].sandbox.docker.dangerouslyAllowReservedContainerTargets`
|
||||
- `agents.list[<index>].sandbox.docker.dangerouslyAllowExternalBindSources`
|
||||
- `agents.list[<index>].sandbox.docker.dangerouslyAllowContainerNamespaceJoin`
|
||||
|
||||
## Reverse Proxy Configuration
|
||||
|
||||
|
||||
@@ -368,6 +368,8 @@ precedence, and troubleshooting.
|
||||
- `"rw"` mounts the agent workspace read/write at `/workspace`
|
||||
- Auto-prune: idle > 24h OR age > 7d
|
||||
- Network: `none` by default (explicitly opt-in if you need egress)
|
||||
- `host` is blocked.
|
||||
- `container:<id>` is blocked by default (namespace-join risk).
|
||||
- Default allow: `exec`, `process`, `read`, `write`, `edit`, `sessions_list`, `sessions_history`, `sessions_send`, `sessions_spawn`, `session_status`
|
||||
- Default deny: `browser`, `canvas`, `nodes`, `cron`, `discord`, `gateway`
|
||||
|
||||
@@ -376,6 +378,9 @@ precedence, and troubleshooting.
|
||||
If you plan to install packages in `setupCommand`, note:
|
||||
|
||||
- Default `docker.network` is `"none"` (no egress).
|
||||
- `docker.network: "host"` is blocked.
|
||||
- `docker.network: "container:<id>"` is blocked by default.
|
||||
- Break-glass override: `agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`.
|
||||
- `readOnlyRoot: true` blocks package installs.
|
||||
- `user` must be root for `apt-get` (omit `user` or set `user: "0:0"`).
|
||||
OpenClaw auto-recreates containers when `setupCommand` (or docker config) changes
|
||||
@@ -445,7 +450,8 @@ If you plan to install packages in `setupCommand`, note:
|
||||
|
||||
Hardening knobs live under `agents.defaults.sandbox.docker`:
|
||||
`network`, `user`, `pidsLimit`, `memory`, `memorySwap`, `cpus`, `ulimits`,
|
||||
`seccompProfile`, `apparmorProfile`, `dns`, `extraHosts`.
|
||||
`seccompProfile`, `apparmorProfile`, `dns`, `extraHosts`,
|
||||
`dangerouslyAllowContainerNamespaceJoin` (break-glass only).
|
||||
|
||||
Multi-agent: override `agents.defaults.sandbox.{docker,browser,prune}.*` per agent via `agents.list[].sandbox.{docker,browser,prune}.*`
|
||||
(ignored when `agents.defaults.sandbox.scope` / `agents.list[].sandbox.scope` is `"shared"`).
|
||||
|
||||
Reference in New Issue
Block a user