#sandboxed agent crashing gateway

63 messages · Page 1 of 1 (latest)

vast path
#

Sandbox + workspaceAccess: "rw" + user: "0:0" crashes gateway

I'm running a multi-agent setup with Docker sandboxes. Sandboxed agents need full root exec inside their containers (install packages, run tools, etc). Config:

  "mode": "all",
  "workspaceAccess": "rw",
  "docker": {
    "user": "0:0",
    "network": "bridge"
  }
}```


The problem: When the sandbox agent writes files (e.g. daily memory logs), they're created as root:root 0600 on the host via the bind-mounted workspace. The gateway (uid 1000) then tries to watch these files and crashes:

```[openclaw] Unhandled promise rejection: Error: EACCES: permission denied, 
  watch '/home/server/.openclaw/workspace-discord-coding-sandbox/memory/2026-04-14.md'
    at createFsWatchInstance (chokidar/handler.js:126:16)
    at setFsWatchListener (chokidar/handler.js:171:19)
    at NodeFsHandler._watchWithNodeFs (chokidar/handler.js:327:22)```

Also hits on read:
```[tools] read failed: EACCES: permission denied, 
  open '/home/server/.openclaw/workspace-discord-coding-sandbox/memory/2026-04-14.md'```

My sandbox config:

 ```        "id": "discord-coding-sandbox",

        "sandbox": {
          "mode": "all",
          "workspaceAccess": "rw",
          "scope": "agent",
          "docker": {
            "user": "0:0",
            "setupCommand": "pip3 install --break-system-packages yt-dlp",
            "dangerouslyAllowExternalBindSources": true
          }
        },

Questions:
Is there a recommended way to run sandboxed agents with full root exec + workspaceAccess: "rw" without this issue? My goal is to have an agent in sandbox docker that has full access to install packages, tools etc, read/write it's own workspace files. How can I achieve that?

#

@craggy swift

craggy swiftBOT
#

I’m checking the actual sandbox implementation too, because this smells like a real host/container ownership mismatch rather than just a docs issue.

#

First, can you paste openclaw --version?

Short version: I do not think workspaceAccess: "rw" + docker.user: "0:0" is a clean/recommended combo today.

What is happening:

  • with workspaceAccess: "rw", OpenClaw bind-mounts the agent workspace into /workspace
  • if the container runs as root, writes land on the host as root:root
  • new files created by the sandbox write path are 0600, so the gateway user cannot read/watch them

So the permission mismatch is real, and your EACCES makes sense.

What I found in docs/source:

#

Recommended setup:

  1. If you want workspaceAccess: "rw", run the sandbox as the same UID:GID as the gateway/workspace owner, for example 1000:1000.
  2. Put your tools/packages in a custom sandbox image instead of relying on a root runtime.
  3. If you need occasional root inside the container, use a custom image with sudo for that non-root user, but keep normal workspace writes non-root.
  4. After changing config/image, recreate the sandbox:
    openclaw sandbox recreate --agent discord-coding-sandbox

If you truly need the whole agent runtime as root, I would switch to workspaceAccess: "none" or "ro" and keep writes in container-local paths or a separate scratch bind, not the watched agent workspace.

Two more notes:

Useful checks:

#
  • openclaw --version
  • openclaw sandbox explain --agent discord-coding-sandbox

Temporary mitigation while testing:

  • set agents.defaults.memorySearch.sync.watch: false

That may stop the chokidar crash path, but it will not fix read on existing root-owned 0600 files.

If you paste your version, I can suggest the cleanest config shape for your exact setup.

#

Yep, I checked this. Short answer, I do not think there is a clean supported way to do workspaceAccess: "rw" + docker.user: "0:0" today.

That combo conflicts with how the workspace mount works:

  • /workspace is a bind mount to the host workspace
  • root in the container creates host files as root:root
  • new files end up unreadable/unwatchable by the gateway user (uid 1000), so read and chokidar blow up

So the recommended path is:

Best setup

  • keep workspaceAccess: "rw"
  • set docker.user to the same UID:GID as the gateway/workspace owner (for example 1000:1000)
  • bake tools like yt-dlp into a custom sandbox image
  • if you need occasional root inside the container, add sudo for that non-root user

Example config shape:

#
{
  agents: {
    list: [{
      id: "discord-coding-sandbox",
      sandbox: {
        mode: "all",
        scope: "agent",
        workspaceAccess: "rw",
        docker: {
          image: "my-openclaw-sandbox:latest",
          user: "1000:1000",
          network: "bridge"
        }
      }
    }]
#
  }
}

If you truly need full-time root

Then I would not use workspaceAccess: "rw". Use:

  • workspaceAccess: "none" or "ro"
  • root inside the container
  • write to container-local paths or a separate scratch mount, not the watched agent workspace

Important nuance

A custom image is the clean fix for package installs. setupCommand + root + rw workspace is exactly the footgun you found.

Temporary mitigation

You can disable memory file watching:

#

If you want, I can sketch a tiny Dockerfile for the “non-root runtime + sudo + preinstalled tools” approach.

vast path
#

my goal is for agent to have its own workspace that sits outside the container so files persist, but have its own runtime in docker in which it can install tools etc
i dont want to use memorysync false. so is rw, with sudo the right way?

craggy swiftBOT
#

Yeah, for your goal, workspaceAccess: "rw" + non-root runtime user that matches the host workspace owner + sudo for occasional privileged ops is the closest thing to the right pattern today.

So, yes, rw with sudo is the approach I’d use, with one important rule:

  • normal file writes to /workspace must happen without sudo
  • use sudo only for system locations, package installs, apt/pip/npm globals, etc.
  • if the agent does sudo tee /workspace/... or otherwise writes workspace files as root, you are back in the same broken state

Best current setup

  • workspaceAccess: "rw"
  • docker.user: "<gateway uid>:<gateway gid>" (often 1000:1000)
  • custom image with most tools preinstalled
  • optional passwordless sudo for that user

Why this fits your goal

#

You want:

  1. persistent workspace on the host
  2. isolated runtime in Docker
  3. ability to install/use tools in the container

That works fine as long as the workspace owner inside the container matches the host owner.

Better than runtime installs

If the tool is something predictable like yt-dlp, I would strongly prefer baking it into the image instead of setupCommand. That is more stable, survives recreates cleanly, and avoids privilege weirdness.

Practical caveat

If you need the agent to have constant full root for arbitrary commands, then no, I would not trust workspaceAccess: "rw" with that. At that point root will eventually touch /workspace and break ownership again.

So my recommendation

  • Default: non-root runtime user + rw
#
  • Prefer: preinstall tools in image
  • Allow: sudo for rare admin actions
  • Avoid: root as the container default user when /workspace is host-mounted rw

And after changing it:

openclaw sandbox recreate --agent discord-coding-sandbox

If you want, I can give you a tiny Dockerfile for:

  • yt-dlp preinstalled
  • non-root runtime user
  • passwordless sudo
  • safe for workspaceAccess: "rw"
vast path
#

so this means the memory will work within workspace, files created by agent will be able to be created and red. and if i tell agent to install say react, it can elevate and install it?

craggy swiftBOT
#

Yes, if the sandbox runs as the same UID:GID as the workspace owner, then:

  • memory files in the workspace should be readable/writable normally
  • files the agent creates in /workspace should persist on the host
  • read/watching should work again

The big caveat is what kind of install you mean:

If you mean project deps like React

For react, next, vite, etc, the agent should not elevate.

It should just run the normal workspace install, for example pnpm add react or npm install react.

That writes into the persistent workspace (package.json, lockfile, node_modules if present), which is exactly what you want.

If you mean system-level installs

For things like:

#
  • apt-get install ...
  • pip install into system Python
  • global npm installs
  • writing to /usr/local, /opt, etc

then yes, that is where sudo makes sense.

Very important rule

Do not use sudo for commands that write into /workspace.

If the agent does a root-owned write inside the mounted workspace, you can break ownership again and end up back at the same EACCES problem.

So the pattern is:

  • /workspace writes: normal user
  • system/container writes: sudo
#

One more nuance:

  • workspace installs persist
  • container rootfs installs only persist until that sandbox is recreated/pruned

So for reusable tools, I still prefer baking them into the image.

If you switch to this model, also make sure you fix any existing root-owned files in that workspace first, otherwise memory/read can still stay broken from old files.

vast path
#

can you summarise this into instructions my agent can follow to set this up for me

craggy swiftBOT
#

Yep, paste this to your local agent:

Set up my OpenClaw sandbox so the agent has:

1. a persistent workspace on the host
2. a Docker runtime for isolation
3. normal read/write access to its workspace without breaking gateway memory/watchers
4. optional privilege escalation inside the container for system-level installs only

Important constraints:

- Do NOT run the sandbox container as root for normal operation.
- Do NOT use `docker.user: "0:0"` with `workspaceAccess: "rw"`.
- The sandbox runtime user must match the host workspace owner UID:GID.
- Normal writes to `/workspace` must stay non-root.
#
- Only system-level installs should use `sudo`.
- Project-level installs inside `/workspace` (for example `pnpm add react`) must NOT use sudo.
- Prefer baking common tools into the image instead of using `setupCommand`.

Tasks:

1. Check my OpenClaw version and effective sandbox config.
   - Run:
     - `openclaw --version`
     - `openclaw sandbox explain --agent discord-coding-sandbox`

2. Determine the UID:GID that owns the persistent agent workspace on the host.
   - Use that UID:GID for `sandbox.docker.user`.

3. Create a custom sandbox image for this agent/runtime.
#
   Requirements for the image:
   - based on an OpenClaw sandbox image
   - has the tools I want preinstalled, for example `yt-dlp`
   - has `sudo` installed
   - has a non-root runtime user that can use passwordless sudo
   - normal shell sessions run as the non-root user

4. Update the OpenClaw config for `discord-coding-sandbox`.
   Desired shape:
   - `sandbox.mode: "all"`
   - `sandbox.scope: "agent"`
   - `sandbox.workspaceAccess: "rw"`
   - `sandbox.docker.image: "<custom image>"`
   - `sandbox.docker.user: "<workspace uid>:<workspace gid>"`
   - remove the root-based `setupCommand` if the tool is baked into the image
#
   - keep network settings only if actually needed

5. Repair existing permissions in the current persistent workspace.
   - Any files previously created as `root:root` in that agent workspace need to be restored to the gateway/workspace owner before testing again.

6. Recreate the sandbox runtime so config/image changes take effect.
   - Run:
     - `openclaw sandbox recreate --agent discord-coding-sandbox`

7. Verify the final behavior.
   Acceptance tests:
   - the agent can create and read files in `/workspace`
   - memory files under `memory/` are readable by the gateway
   - no `EACCES` watcher/read errors occur
   - a normal project install like `pnpm add react` works without sudo and persists in the host workspace
#
   - a system-level install can be done with sudo inside the container when needed
   - after tests, newly created workspace files are NOT owned by root

8. Add a safety note to the agent instructions:
   - Never use sudo for commands that write into `/workspace`
   - Only use sudo for system paths like `/usr`, `/usr/local`, apt, system pip, global package managers, etc.

Goal:
A persistent host workspace with correct permissions, plus an isolated Docker runtime where normal workspace work is non-root and rare system-level actions can be elevated safely.

If you want, I can also turn that into a shorter “just do it” prompt or a step-by-step checklist.

vast path
#

my agent said this, is this accurate, why wont sudo work

Good news and bad news.

✅ File permissions work perfectly — container runs as 1000:1000, files created on host as server:server, no EACCES, gateway can watch everything. yt-dlp works. Memory will work.

❌ Sudo doesn't work — OpenClaw hardcodes --security-opt no-new-privileges on every sandbox container. This prevents setuid binaries (including sudo) from escalating to root. It's not configurable — baked into the source at container creation.

sudo: The "no new privileges" flag is set, which prevents sudo from running as root.

#

@craggy swift

craggy swiftBOT
#

Let me verify that in the code/docs so I don’t hand-wave this.

#

Yes, that part is accurate. I’m glad your agent checked the source, I missed that nuance earlier.

On current source, OpenClaw’s Docker sandbox unconditionally adds:

--security-opt no-new-privileges

and I do not see a config knob for disabling it.

Why sudo fails:

  • sudo needs to gain root via setuid/capabilities
  • no-new-privileges tells the kernel “this process and its children may not gain any extra privileges”
  • so even a correctly-installed sudo binary cannot elevate, and it errors exactly like that

So the practical answer is:

#

Yes

  • workspaceAccess: "rw" + docker.user: "1000:1000" (or matching host owner) is the right way to make workspace files, memory, and gateway watching work

No

  • sudo is not a viable workaround inside the current Docker sandbox runtime

So the workable patterns today are:

  1. Best for persistent workspace

    • workspaceAccess: "rw"
    • non-root docker.user matching host workspace owner
    • preinstall tools in a custom image
    • no runtime sudo expectation
  2. If you truly need root inside the sandbox

    • run as root
    • but then do not use host rw workspace the same way, or you get the root-owned file problem again
#

So your agent’s conclusion is basically right:

  • persistent host workspace + good permissions: yes
  • runtime sudo escalation inside the sandbox: no
  • therefore the clean current answer is custom image, not “non-root + sudo”

For things like react, that is fine anyway, because project installs should run as the normal workspace user, not root.

If you want, I can condense this into a final “recommended architecture” for this use case, basically: rw workspace + non-root runtime + custom image for tools.

#

Your agent is right, and sorry, I steered you wrong on sudo.

Final answer, as I understand current OpenClaw Docker sandbox behavior:

  • Persistent host workspace + working memory/watch/read
    → use workspaceAccess: "rw" + docker.user matching the host workspace owner

  • Ad-hoc root escalation inside that same sandbox
    → not really supported today (no-new-privileges blocks sudo)

  • Run the whole sandbox as root instead
    → breaks host workspace ownership again when it writes files

So today you can cleanly have 2 out of 3, but not all 3 at once:

  1. persistent host workspace
  2. correct non-root file ownership for gateway/memory
#
  1. runtime root escalation inside the Docker sandbox

Recommended architecture

For your use case, I’d treat this as the supported shape:

  • workspaceAccess: "rw"
  • docker.user: "<host uid>:<host gid>"
  • custom sandbox image with the tools you want preinstalled
  • no expectation of sudo inside the sandbox

If you need more tools later, rebuild the image and recreate the sandbox.

If having runtime root installs inside the sandbox is important, I think that is a real feature gap worth filing as an issue:
https://github.com/openclaw/openclaw/issues

Glad you caught the no-new-privileges bit, that was the missing piece. 🎯

#

If this cleared it up, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it.

vast path
#

but i thought you said i could use sudo, this is very annoying, i need it to allow the agent to install tools, thats the whole point of sandbox for me. full access but only within sandbox

#

what do the docs say about this. was this sudo thing added recently, any older version i can rollback to to get it working. send me all the relevant doc pages

craggy swiftBOT
#

You’re right to be annoyed. I was wrong about sudo in this sandbox shape. Let me check whether one of the other sandbox backends is a better fit for the “full access, but only inside the sandbox” model.

#

You’re right, and I get why that’s annoying. I was wrong to suggest sudo would save this in the Docker sandbox path.

The blunt version is:

With the current Docker sandbox backend, I do not think you can cleanly get all of these at once:

  1. host-persistent workspaceAccess: "rw"
  2. correct non-root ownership for gateway/memory
  3. ad-hoc root installs inside the sandbox at runtime

Why:

  • docker.user: "0:0" gives you root, but breaks host workspace ownership
  • non-root docker.user fixes workspace ownership, but sudo is blocked by no-new-privileges

So yes, for the Docker backend, this is a real limitation.

#

If you stay on Docker

The practical answer is:

  • use workspaceAccess: "rw"
  • run as the host UID:GID
  • preinstall tools in a custom image
  • rebuild/recreate the sandbox when you need more tools

If your real goal is “full access, but only inside the sandbox”

Then honestly I would look at a different sandbox backend, especially:

  • backend: "openshell"
  • or backend: "ssh"

Docs:

#

Why that may fit better:

  • it avoids the direct Docker bind-mount ownership fight
  • OpenShell has mirror mode, where host workspace stays canonical and syncs back after exec
  • OpenShell has remote mode, where the sandbox workspace itself becomes canonical

That is much closer to the model you actually want.

So my updated recommendation is:

  • Docker backend if you are okay with custom images and no runtime root installs
  • OpenShell or SSH backend if you really want a more fully-controlled sandbox runtime

If you want, I can help you sketch the smallest OpenShell config for this exact use case.

vast path
#

yes but will openshell stuff stay in a container, i dont want sandbox thigns touching my host os

craggy swiftBOT
#

I’m going to check the docs plus git history so I can tell you whether this is documented and whether it looks recent.

#

I checked both the docs and git history.

What the docs currently say

1. Docker sandbox permission errors
Docs explicitly say to match docker.user to the mounted workspace owner.

2. workspaceAccess: "rw" behavior
Docs say rw mounts the agent workspace read/write at /workspace.

3. setupCommand expectations
Docs say setupCommand runs once after container creation, and package installs need root.

#

4. Other sandbox backends
Docs say ssh and openshell are valid sandbox backends, both with workspaceAccess: "rw" support.

5. Sandbox inspection/recreate
Useful for checking the effective config and recreating runtimes.

6. General FAQ
Worth keeping handy, but it does not really explain this specific sudo limitation.

#

What the docs do not clearly say

They do not seem to explicitly say:

  • Docker sandbox containers are created with --security-opt no-new-privileges
  • that this breaks runtime sudo escalation inside the sandbox

That is the missing piece that makes the current docs a bit confusing for your use case.

Was this added recently?

From git history, the sandbox Docker create path has:

#
args.push("--security-opt", "no-new-privileges");

in src/agents/sandbox/docker.ts, and the blame for that line points to:

  • commit bcbfb357bec
  • date: 2026-01-14

From tags in this checkout, that line is present in tagged releases starting at v2026.3.7 and later.

So:

  • yes, it looks like this behavior is not ancient
  • older versions may predate it
  • but I would not recommend rollback as the fix without careful testing, because you would be giving up later fixes and I have not validated that older versions cleanly support the exact combo you want
#

If you want, I can also turn this into a GitHub issue draft you can paste, because I think there are really two issues here:

  1. docs do not clearly warn that Docker sandbox runtime sudo is blocked
  2. the current Docker sandbox cannot cleanly satisfy your “full access only inside sandbox” use case
#

I want to be precise here, because OpenShell is a different model from the local Docker sandbox. Let me check how the docs describe its isolation boundary.

#

Short version:

  • OpenShell sandboxed commands do not run on your host OS
  • but OpenShell is not the same thing as a local Docker container managed by OpenClaw

The docs describe OpenShell as an “OpenShell-managed remote environment” reached over SSH:
https://docs.openclaw.ai/gateway/openshell

So think of it as:

  • not host execution
  • not local Docker sandbox
  • remote sandbox environment managed by OpenShell

If your requirement is specifically:

“I want the agent fully isolated, and I do not want sandbox commands touching my host OS”

#

then OpenShell does fit that better than the Docker bind-mount path, because execution happens in the remote sandbox, not on your host.

If your requirement is instead:

“I want a sandbox that is specifically a local Docker container I control”

then Docker backend is the right model, but that is also the one hitting the current rw + root/sudo limitation.

Best mental model

  • Docker backend = local container, but host workspace bind mounts are involved
  • OpenShell backend = remote sandbox, not host OS, optional sync back to host workspace
  • SSH backend = arbitrary SSH-accessible machine/container/VM you control

Honestly, if you want full root inside an isolated environment without touching the host OS, the cleanest fit may actually be:

  • backend: "ssh" to a dedicated VM/container
vast path
#

what best matches my goal:

Goal:
Agent runs in sandbox environment
Agent workspace is accessible on host so it persists
Agent has full exec within sandbox. Can install tools, software, packages
Agent has its own memory.md, agents.md etc, completely isolated from Main host agent

craggy swiftBOT
#

I’m going to check the SSH/OpenShell workspace behavior one more time, because your goal is specific enough that the distinction matters.

#

I do not think there is a perfect 1:1 match for all four goals in the local Docker sandbox today.

Best overall match

OpenShell + mode: "mirror" + scope: "agent" + workspaceAccess: "rw"

Why this is the closest match:

  • Agent runs in a sandbox environment
    yes, execution happens in the OpenShell remote sandbox, not on your host OS

  • Workspace is accessible on host and persists
    yes, in mirror mode the local host workspace stays canonical and syncs back after exec

  • Agent has its own isolated workspace / memory / AGENTS.md
    yes, a separate agent with scope: "agent" gets its own sandbox/runtime/workspace boundary

  • Does not touch host OS for exec

#

yes, better than the local Docker bind-mount path for that concern

The caveat

The docs do not clearly promise “unrestricted root/package-install freedom” inside OpenShell, so I cannot honestly say it guarantees the “install anything” part.

If that last part is non-negotiable

If you mean:

I want truly full exec, I control the sandbox, and it must be able to install system packages/tools

then the strongest match is probably:

backend: "ssh" to your own dedicated VM/container you control

That gives you the most control over root/sudo/packages.
But it is remote-canonical, so it does not automatically keep the host workspace in sync the way OpenShell mirror does.

#

So my ranking would be

  1. OpenShell mirror = best match to your full goal list overall
  2. SSH backend to your own isolated VM/container = best if “full install anything” matters most
  3. Docker backend = worst match for this exact use case right now

And for the isolation part, yes, a separate agent already gives you its own memory.md, AGENTS.md, etc. scope: "agent" keeps its sandbox runtime separate too.

If you want, I can sketch the exact config I’d try first for OpenShell mirror, since that seems like the closest fit.

vast path
#

i just patched it myself, removed the no-new-privileges in my own version

#

that solved it

craggy swiftBOT
#

Ah, got it. Yeah, that would explain it.

If you removed no-new-privileges, then your original model can work much more like you expected:

  • sandbox runs as non-root UID:GID matching the host workspace owner
  • normal workspace writes stay readable by the gateway
  • sudo can elevate inside the sandbox again
  • tools/packages can be installed inside the sandbox runtime

The main caution is security, not functionality.

no-new-privileges is there specifically to stop privilege escalation via setuid/capabilities, so removing it makes that sandbox meaningfully less locked down. If you keep the patch, I’d strongly suggest:

  • use it only for a dedicated agent
  • do not expose that agent to untrusted chats/users
  • keep scope: "agent"
  • still avoid sudo for writes into /workspace, otherwise you can recreate the root-owned file problem
#

So the safe-ish pattern becomes:

  • normal file/project work in /workspace as the non-root runtime user
  • sudo only for container/system installs
  • never sudo commands that write workspace files

If this is the setup you actually need, I think it is worth filing a feature request for a configurable opt-out instead of carrying a permanent local patch:
https://github.com/openclaw/openclaw/issues

And honestly, nice catch. That was the missing blocker the whole time.

#

Nice, glad you got it working. 🎉

So the working shape for your case is basically:

  • sandbox user matches host workspace ownership
  • sudo allowed again in the sandbox
  • avoid sudo writes into /workspace

I’d still treat that patch as a deliberate security tradeoff, so I’d keep it scoped to that dedicated agent only.

If you want this upstream, please file it as a feature/docs issue:
https://github.com/openclaw/openclaw/issues

And if this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it.

vast path
#

privilege escalation within sandbox is ok for me, only im using it. its neccesary to install tools and let agents do work