Multiple folders for one agent
Use Docker bind mounts when one sandboxed agent needs more than its primary workspace. Each entry maps a host folder to a container path with an explicit access mode:romakes the mounted folder read-only inside the sandbox.rwlets sandboxed tools and processes change the host folder.- The container path is the path the agent uses. Host paths are not exposed automatically.
research agent a writable primary workspace, read-only reference material at /reference, and a separate writable output folder at /drafts:
workspaceAccess and bind modes are independent:
Changing
workspaceAccess does not change an additional bind from ro to rw, or vice versa. Global and per-agent docker.binds are merged. Keep scope: "agent" or "session" for per-agent binds; scope: "shared" ignores all per-agent Docker overrides and uses only global binds.
Bind mounts are the supported multi-folder boundary because Docker constructs the container’s filesystem view with mount isolation, and the ro/rw mode applies to every process in the sandbox. That boundary covers exec, filesystem tools, child processes, and libraries without duplicating path-authorization checks across each OpenClaw code path. A host-side path allowlist cannot provide the same complete boundary when an allowed shell or dependency can access files directly.
The opt-in dangerouslyAllowExternalBindSources only permits sources outside the workspace roots. It does not disable OpenClaw’s blocked system, credential, Docker socket, symlink-parent, or reserved-target checks. Prefer the smallest folder, use ro unless writes are required, and recreate the sandbox after changing mounts:
Other bind behavior
agents.defaults.sandbox.docker.binds configures global mounts. The format is the same host:container:mode form (for example, "/home/user/source:/source:rw").
agents.defaults.sandbox.browser.binds mounts additional host directories into the sandbox browser container only. When set (including []), it replaces docker.binds for the browser container; when omitted, the browser container falls back to docker.binds.