← Back to PRs

#20991: fix(sandbox): fall back to gateway UID:GID when no user is configured (#20979)

by cluster2600 open 2026-02-19 14:39 View on GitHub →
agents size: M
## Summary Fixes #20979 When `agents.defaults.sandbox.docker.user` is not set, the container runs as root (UID 0) with `--cap-drop ALL` which strips `DAC_OVERRIDE`. Without `DAC_OVERRIDE`, root inside the container cannot write to workspace directories owned by the non-root gateway user — the recommended git-based install pattern. This silently breaks the Read, Write, Edit, and `apply_patch` file tools for all sandboxed sessions. ## Root Cause Three default values combine to create a UID mismatch (as detailed in #20979): 1. **No default `user`** — `resolveSandboxDockerConfig()` resolves `user` from agent or global config with no fallback, so container runs as root (UID 0) when unset. 2. **`capDrop: ["ALL"]`** — strips `DAC_OVERRIDE` from root. 3. **`--user` conditionally omitted** — `buildSandboxCreateArgs()` only passes `--user` when `cfg.user` is truthy. ## Fix In `buildSandboxCreateArgs()` in `src/agents/sandbox/docker.ts`, when `cfg.user` is not explicitly set, fall back to `process.getuid():process.getgid()` on POSIX platforms so the container's effective user matches the gateway's file ownership: ```typescript const effectiveUser = params.cfg.user || (typeof process.getuid === "function" ? `${process.getuid()}:${typeof process.getgid === "function" ? process.getgid() : process.getuid()}` : null); if (effectiveUser) { args.push("--user", effectiveUser); } ``` **Behavior:** - ✅ Explicit `user` config: unchanged (always takes precedence) - ✅ Non-root gateway (UID 1003): container gets `--user 1003:1003` - ✅ Root gateway (UID 0): container gets `--user 0:0` (same as before — no regression) - ✅ Windows (no `process.getuid`): no `--user` flag passed (same as before) ## Tests Added `src/agents/sandbox/docker.sandbox-create-args.test.ts` covering: - Explicit user config takes precedence - Non-root gateway falls back to UID:GID - Root gateway falls back to 0:0 ## Workaround (no longer needed) Users on affected setups can still manually configure: ```bash openclaw config set agents.defaults.sandbox.docker.user "$(id -u):$(id -g)" openclaw sandbox recreate --all ``` <!-- greptile_comment --> <h3>Greptile Summary</h3> Fixes file tool access issues for non-root gateway users by falling back to the gateway process UID:GID when `agents.defaults.sandbox.docker.user` is not configured. The root cause was that containers ran as root with `--cap-drop ALL`, which stripped `DAC_OVERRIDE` capability, preventing write access to workspace directories owned by non-root gateway users. - Implemented automatic fallback to `process.getuid():process.getgid()` on POSIX platforms in `buildSandboxCreateArgs()` - Added comprehensive tests covering explicit config, non-root fallback, and root fallback scenarios - Updated CHANGELOG.md with fix details - Test coverage is thorough but missing Windows/non-POSIX platform test case <h3>Confidence Score: 4/5</h3> - This PR is safe to merge with minimal risk - it fixes a legitimate bug without introducing breaking changes - The fix is well-designed and follows existing codebase patterns for POSIX detection. Tests cover the main scenarios. Score of 4 (not 5) due to missing Windows test coverage, though the implementation itself handles Windows correctly by design. - No files require special attention - the implementation is straightforward and safe <sub>Last reviewed commit: 2451865</sub> <!-- greptile_other_comments_section --> <sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub> <!-- /greptile_comment -->

Most Similar PRs