feat(docker): add opt-in sandbox support for Docker deployments#29974
feat(docker): add opt-in sandbox support for Docker deployments#29974vincentkoc merged 16 commits intoopenclaw:mainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 64256e8ebe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Greptile SummaryThis PR adds comprehensive opt-in Docker sandbox support with strong backward compatibility guarantees. The implementation spans three files with a well-designed architecture that defers security-sensitive operations (Docker socket mounting) until all prerequisites are validated. Key implementation details:
Error handling and safety:
Backward compatibility:
Confidence Score: 5/5
Last reviewed commit: bded88a |
Additional Comments (1)
Because Fix: add Prompt To Fix With AIThis is a comment left during a code review.
Path: docker-setup.sh
Line: 357-367
Comment:
**`OPENCLAW_SANDBOX` and `DOCKER_GID` not persisted — `group_add` lost on re-runs**
`OPENCLAW_EXTRA_MOUNTS` is saved to `.env` (line 365), so the Docker socket bind-mount correctly survives re-runs. However, `OPENCLAW_SANDBOX`, `DOCKER_GID`, and `OPENCLAW_INSTALL_DOCKER_CLI` are **not** saved.
Because `write_extra_compose` only injects `group_add` when `SANDBOX_ENABLED` and `DOCKER_GID` are non-empty (line 233), any subsequent run of `./docker-setup.sh` without `OPENCLAW_SANDBOX=1` will regenerate `docker-compose.extra.yml` *without* the `group_add` stanza. The container will still have `/var/run/docker.sock` mounted (from `OPENCLAW_EXTRA_MOUNTS`), but the `node` user won't have the Docker group membership needed to access it — silently breaking sandbox.
Fix: add `OPENCLAW_SANDBOX`, `DOCKER_GID`, and `OPENCLAW_INSTALL_DOCKER_CLI` to the `upsert_env` call, or re-derive `DOCKER_GID` whenever the socket mount is already present in `OPENCLAW_EXTRA_MOUNTS` regardless of `SANDBOX_ENABLED`.
```suggestion
upsert_env "$ENV_FILE" \
OPENCLAW_CONFIG_DIR \
OPENCLAW_WORKSPACE_DIR \
OPENCLAW_GATEWAY_PORT \
OPENCLAW_BRIDGE_PORT \
OPENCLAW_GATEWAY_BIND \
OPENCLAW_GATEWAY_TOKEN \
OPENCLAW_IMAGE \
OPENCLAW_EXTRA_MOUNTS \
OPENCLAW_HOME_VOLUME \
OPENCLAW_DOCKER_APT_PACKAGES \
OPENCLAW_SANDBOX \
DOCKER_GID \
OPENCLAW_INSTALL_DOCKER_CLI
```
How can I resolve this? If you propose a fix, please make it concise. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6caec4c9a6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 406c8711b2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
This already exists |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bded88ad53
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@thewilloftheshadow Could you clarify what you mean by "this already exists"? I'm aware that This PR addressed a different scenario: Docker-in-Docker — when the gateway itself runs inside a Docker container (e.g. via
The PR added:
None of this exists today in the Docker deployment path. Did you read the PR description? It specifically explains the Docker-in-Docker gap. See also issue #29933 for the real-world context (Hostinger VPS template). |
|
Ahh this went on the wrong docker pr! |
|
@thewilloftheshadow No worries! Could you take a look when you get a chance? Greptile gave it 5/5 confidence, all previous review issues have been fixed (4 commits total). The only failing CI check is the Would appreciate a review/approval if it looks good to you. Thanks! |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 06a8e8289a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@vincentkoc @steipete Would appreciate a review on this one when you have a moment. This enables sandbox isolation for Docker-based deployments ( Changes are fully opt-in ( Closes #29933. |
06a8e82 to
dbe3ef8
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dbe3ef8240
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Enable Docker-based sandbox isolation via OPENCLAW_SANDBOX=1 env var in docker-setup.sh. This is a prerequisite for agents.defaults.sandbox to function in any Docker deployment (self-hosted, Hostinger, DigitalOcean). Changes: - Dockerfile: add OPENCLAW_INSTALL_DOCKER_CLI build arg (~50MB, opt-in) - docker-compose.yml: add commented-out docker.sock mount with docs - docker-setup.sh: auto-detect Docker socket, inject mount, detect GID, build sandbox image, configure sandbox defaults, add group_add All changes are opt-in. Zero impact on existing deployments. Usage: OPENCLAW_SANDBOX=1 ./docker-setup.sh Closes openclaw#29933 Related: openclaw#7575, openclaw#7827, openclaw#28401, openclaw#10361, openclaw#12505, openclaw#28326 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Persist OPENCLAW_SANDBOX, DOCKER_GID, OPENCLAW_INSTALL_DOCKER_CLI to .env via upsert_env so group_add survives re-runs - Show config set errors instead of swallowing them silently; report partial failure when sandbox config is incomplete - Warn when Dockerfile.sandbox is missing but sandbox config is still applied (sandbox image won't exist) - Fix non-canonical whitespace in apt sources.list entry by using printf instead of echo with line continuation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…CLI check - Remove `local` keyword from top-level `sandbox_config_ok` assignment which caused script exit under `set -euo pipefail` (bash `local` outside a function is an error) - Add Docker CLI prerequisite check for pre-built (non-local) images: runs `docker --version` inside the container and skips sandbox setup with a clear warning if the CLI is missing - Split sandbox block so config is only applied after prerequisites pass Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move Docker socket mounting from the early setup phase (before image build/pull) to a dedicated compose overlay created only after: 1. Docker CLI is verified inside the container image 2. /var/run/docker.sock exists on the host Previously the socket was mounted optimistically at startup, leaving the host Docker daemon exposed even when sandbox setup was later skipped due to missing Docker CLI. Now the gateway starts without the socket, and a docker-compose.sandbox.yml overlay is generated only when all prerequisites pass. The gateway restart at the end of sandbox setup picks up both the socket mount and sandbox config. Also moves group_add from write_extra_compose() into the sandbox overlay, keeping all sandbox-specific compose configuration together. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dbe3ef8 to
085cee5
Compare
|
Addressed the remaining sandbox hardening/review concerns and pushed updates. What changed:
Validation run:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 085cee56ff
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Addressed both of these review concerns in latest commits:
Additional hardening shipped now:
Validation:
|
|
@aisle-research-bot review |
🔒 Aisle Security AnalysisWe found 2 potential security issue(s) in this PR:
1. 🟡 Unverified Docker APT GPG key download during image build (trust-on-first-use)
DescriptionThe Dockerfile optionally installs Docker CLI by downloading a repository signing key at build time and trusting it without verifying an expected fingerprint.
Vulnerable code: curl -fsSL https://download.docker.com/linux/debian/gpg | \
gpg --dearmor -o /etc/apt/keyrings/docker.gpgNote: using RecommendationVerify the Docker APT key by fingerprint (allowlist) before trusting it, and fail the build if it does not match. Example (illustrative): RUN if [ -n "$OPENCLAW_INSTALL_DOCKER_CLI" ]; then \
apt-get update && apt-get install -y --no-install-recommends ca-certificates curl gnupg && \
install -m 0755 -d /etc/apt/keyrings && \
curl -fsSL https://download.docker.com/linux/debian/gpg -o /tmp/docker.gpg && \
gpg --no-default-keyring --keyring /tmp/docker.gpg --list-keys --with-fingerprint && \
gpg --dearmor -o /etc/apt/keyrings/docker.gpg /tmp/docker.gpg && \
rm -f /tmp/docker.gpg && \
...; \
fiAdditionally (hardening / reproducibility):
2. 🟡 docker.sock may be mounted despite failed sandbox policy due to
|
| Property | Value |
|---|---|
| Severity | Medium |
| CWE | CWE-269 |
| Location | docker-setup.sh:478-521 |
Description
In docker-setup.sh, the sandbox flow tries to avoid exposing the host Docker socket unless sandbox prerequisites and policy configuration succeed. However, the script adds the sandbox compose overlay (which mounts docker.sock) to COMPOSE_ARGS before running a series of docker compose run openclaw-cli config set ... commands.
Because openclaw-cli is defined with depends_on: openclaw-gateway and network_mode: "service:openclaw-gateway", docker compose run may start (or potentially recreate) the openclaw-gateway service to satisfy dependencies using the current project configuration — which now includes the sandbox overlay with the Docker socket mount.
Impact if any sandbox config step fails (or the gateway container is not running/crashes between steps):
openclaw-gatewaycan end up running with/var/run/docker.sockmounted even though sandbox policy was only partially applied or rolled back.- The rollback path deletes
docker-compose.sandbox.yml, but does not force-recreate/restart the gateway without the mount, so an already-started gateway container can keep the socket mount.
This is effectively an unintended privilege escalation surface: any compromise of the gateway container while it has docker.sock mounted typically permits host root-equivalent control via the Docker API.
Recommendation
Prevent docker compose run from implicitly starting/recreating openclaw-gateway with the sandbox overlay until after policy config has succeeded.
Recommended changes:
- Run config commands with
--no-depsso Compose does not start/recreateopenclaw-gatewayusing the overlay:
docker compose "${COMPOSE_ARGS[@]}" run --rm --no-deps openclaw-cli \
config set agents.defaults.sandbox.mode "non-main" >/dev/null- In the partial-failure rollback path, explicitly ensure the gateway is running without the sandbox overlay (and therefore without the docker.sock mount). For example, keep a separate
BASE_COMPOSE_ARGS(without the sandbox-f) and do:
# After failure/rollback:
docker compose "${BASE_COMPOSE_ARGS[@]}" up -d --force-recreate openclaw-gateway- Optionally add a
trapto removedocker-compose.sandbox.ymlon unexpected exits so the filesystem state is always cleaned up.
Analyzed PR: #29974 at commit b26fcf0
Last updated on: 2026-03-02T06:58:07Z
|
Addressed the Aisle security findings in the latest commits:
Validation:
Commits: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ab19e40e5a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if ! docker compose "${COMPOSE_ARGS[@]}" run --rm openclaw-cli \ | ||
| config set agents.defaults.sandbox.mode "off" >/dev/null; then |
There was a problem hiding this comment.
Restart gateway after resetting sandbox mode to off
In the non-sandbox path, this config set agents.defaults.sandbox.mode off runs after the gateway has already been started, so it does not fix the live process state for this run. Fresh evidence: src/gateway/config-reload.ts marks the agents prefix as kind: "none", so changing agents.defaults.sandbox.* is not hot-reloaded; if the previous config was non-main, the running gateway keeps sandbox mode without the docker.sock mount and agent exec remains broken until a restart.
Useful? React with 👍 / 👎.
…claw#29974) * feat(docker): add opt-in sandbox support for Docker deployments Enable Docker-based sandbox isolation via OPENCLAW_SANDBOX=1 env var in docker-setup.sh. This is a prerequisite for agents.defaults.sandbox to function in any Docker deployment (self-hosted, Hostinger, DigitalOcean). Changes: - Dockerfile: add OPENCLAW_INSTALL_DOCKER_CLI build arg (~50MB, opt-in) - docker-compose.yml: add commented-out docker.sock mount with docs - docker-setup.sh: auto-detect Docker socket, inject mount, detect GID, build sandbox image, configure sandbox defaults, add group_add All changes are opt-in. Zero impact on existing deployments. Usage: OPENCLAW_SANDBOX=1 ./docker-setup.sh Closes openclaw#29933 Related: openclaw#7575, openclaw#7827, openclaw#28401, openclaw#10361, openclaw#12505, openclaw#28326 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address code review feedback on sandbox support - Persist OPENCLAW_SANDBOX, DOCKER_GID, OPENCLAW_INSTALL_DOCKER_CLI to .env via upsert_env so group_add survives re-runs - Show config set errors instead of swallowing them silently; report partial failure when sandbox config is incomplete - Warn when Dockerfile.sandbox is missing but sandbox config is still applied (sandbox image won't exist) - Fix non-canonical whitespace in apt sources.list entry by using printf instead of echo with line continuation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove `local` outside function and guard sandbox behind Docker CLI check - Remove `local` keyword from top-level `sandbox_config_ok` assignment which caused script exit under `set -euo pipefail` (bash `local` outside a function is an error) - Add Docker CLI prerequisite check for pre-built (non-local) images: runs `docker --version` inside the container and skips sandbox setup with a clear warning if the CLI is missing - Split sandbox block so config is only applied after prerequisites pass Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: defer docker.sock mount until sandbox prerequisites pass Move Docker socket mounting from the early setup phase (before image build/pull) to a dedicated compose overlay created only after: 1. Docker CLI is verified inside the container image 2. /var/run/docker.sock exists on the host Previously the socket was mounted optimistically at startup, leaving the host Docker daemon exposed even when sandbox setup was later skipped due to missing Docker CLI. Now the gateway starts without the socket, and a docker-compose.sandbox.yml overlay is generated only when all prerequisites pass. The gateway restart at the end of sandbox setup picks up both the socket mount and sandbox config. Also moves group_add from write_extra_compose() into the sandbox overlay, keeping all sandbox-specific compose configuration together. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs(docker): fix sandbox docs URL in setup output * Docker: harden sandbox setup fallback behavior * Tests: cover docker-setup sandbox edge paths * Docker: roll back sandbox mode on partial config failure * Tests: assert sandbox mode rollback on partial setup * Docs: document Docker sandbox bootstrap env controls * Changelog: credit Docker sandbox bootstrap hardening * Update CHANGELOG.md * Docker: verify Docker apt signing key fingerprint * Docker: avoid sandbox overlay deps during policy writes * Tests: assert no-deps sandbox rollback gateway recreate * Docs: mention OPENCLAW_INSTALL_DOCKER_CLI in Docker env vars --------- Co-authored-by: Jakub Karwowski <jakubkarwowski@Mac.lan> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…claw#29974) * feat(docker): add opt-in sandbox support for Docker deployments Enable Docker-based sandbox isolation via OPENCLAW_SANDBOX=1 env var in docker-setup.sh. This is a prerequisite for agents.defaults.sandbox to function in any Docker deployment (self-hosted, Hostinger, DigitalOcean). Changes: - Dockerfile: add OPENCLAW_INSTALL_DOCKER_CLI build arg (~50MB, opt-in) - docker-compose.yml: add commented-out docker.sock mount with docs - docker-setup.sh: auto-detect Docker socket, inject mount, detect GID, build sandbox image, configure sandbox defaults, add group_add All changes are opt-in. Zero impact on existing deployments. Usage: OPENCLAW_SANDBOX=1 ./docker-setup.sh Closes openclaw#29933 Related: openclaw#7575, openclaw#7827, openclaw#28401, openclaw#10361, openclaw#12505, openclaw#28326 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address code review feedback on sandbox support - Persist OPENCLAW_SANDBOX, DOCKER_GID, OPENCLAW_INSTALL_DOCKER_CLI to .env via upsert_env so group_add survives re-runs - Show config set errors instead of swallowing them silently; report partial failure when sandbox config is incomplete - Warn when Dockerfile.sandbox is missing but sandbox config is still applied (sandbox image won't exist) - Fix non-canonical whitespace in apt sources.list entry by using printf instead of echo with line continuation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove `local` outside function and guard sandbox behind Docker CLI check - Remove `local` keyword from top-level `sandbox_config_ok` assignment which caused script exit under `set -euo pipefail` (bash `local` outside a function is an error) - Add Docker CLI prerequisite check for pre-built (non-local) images: runs `docker --version` inside the container and skips sandbox setup with a clear warning if the CLI is missing - Split sandbox block so config is only applied after prerequisites pass Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: defer docker.sock mount until sandbox prerequisites pass Move Docker socket mounting from the early setup phase (before image build/pull) to a dedicated compose overlay created only after: 1. Docker CLI is verified inside the container image 2. /var/run/docker.sock exists on the host Previously the socket was mounted optimistically at startup, leaving the host Docker daemon exposed even when sandbox setup was later skipped due to missing Docker CLI. Now the gateway starts without the socket, and a docker-compose.sandbox.yml overlay is generated only when all prerequisites pass. The gateway restart at the end of sandbox setup picks up both the socket mount and sandbox config. Also moves group_add from write_extra_compose() into the sandbox overlay, keeping all sandbox-specific compose configuration together. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs(docker): fix sandbox docs URL in setup output * Docker: harden sandbox setup fallback behavior * Tests: cover docker-setup sandbox edge paths * Docker: roll back sandbox mode on partial config failure * Tests: assert sandbox mode rollback on partial setup * Docs: document Docker sandbox bootstrap env controls * Changelog: credit Docker sandbox bootstrap hardening * Update CHANGELOG.md * Docker: verify Docker apt signing key fingerprint * Docker: avoid sandbox overlay deps during policy writes * Tests: assert no-deps sandbox rollback gateway recreate * Docs: mention OPENCLAW_INSTALL_DOCKER_CLI in Docker env vars --------- Co-authored-by: Jakub Karwowski <jakubkarwowski@Mac.lan> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…claw#29974) * feat(docker): add opt-in sandbox support for Docker deployments Enable Docker-based sandbox isolation via OPENCLAW_SANDBOX=1 env var in docker-setup.sh. This is a prerequisite for agents.defaults.sandbox to function in any Docker deployment (self-hosted, Hostinger, DigitalOcean). Changes: - Dockerfile: add OPENCLAW_INSTALL_DOCKER_CLI build arg (~50MB, opt-in) - docker-compose.yml: add commented-out docker.sock mount with docs - docker-setup.sh: auto-detect Docker socket, inject mount, detect GID, build sandbox image, configure sandbox defaults, add group_add All changes are opt-in. Zero impact on existing deployments. Usage: OPENCLAW_SANDBOX=1 ./docker-setup.sh Closes openclaw#29933 Related: openclaw#7575, openclaw#7827, openclaw#28401, openclaw#10361, openclaw#12505, openclaw#28326 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address code review feedback on sandbox support - Persist OPENCLAW_SANDBOX, DOCKER_GID, OPENCLAW_INSTALL_DOCKER_CLI to .env via upsert_env so group_add survives re-runs - Show config set errors instead of swallowing them silently; report partial failure when sandbox config is incomplete - Warn when Dockerfile.sandbox is missing but sandbox config is still applied (sandbox image won't exist) - Fix non-canonical whitespace in apt sources.list entry by using printf instead of echo with line continuation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove `local` outside function and guard sandbox behind Docker CLI check - Remove `local` keyword from top-level `sandbox_config_ok` assignment which caused script exit under `set -euo pipefail` (bash `local` outside a function is an error) - Add Docker CLI prerequisite check for pre-built (non-local) images: runs `docker --version` inside the container and skips sandbox setup with a clear warning if the CLI is missing - Split sandbox block so config is only applied after prerequisites pass Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: defer docker.sock mount until sandbox prerequisites pass Move Docker socket mounting from the early setup phase (before image build/pull) to a dedicated compose overlay created only after: 1. Docker CLI is verified inside the container image 2. /var/run/docker.sock exists on the host Previously the socket was mounted optimistically at startup, leaving the host Docker daemon exposed even when sandbox setup was later skipped due to missing Docker CLI. Now the gateway starts without the socket, and a docker-compose.sandbox.yml overlay is generated only when all prerequisites pass. The gateway restart at the end of sandbox setup picks up both the socket mount and sandbox config. Also moves group_add from write_extra_compose() into the sandbox overlay, keeping all sandbox-specific compose configuration together. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs(docker): fix sandbox docs URL in setup output * Docker: harden sandbox setup fallback behavior * Tests: cover docker-setup sandbox edge paths * Docker: roll back sandbox mode on partial config failure * Tests: assert sandbox mode rollback on partial setup * Docs: document Docker sandbox bootstrap env controls * Changelog: credit Docker sandbox bootstrap hardening * Update CHANGELOG.md * Docker: verify Docker apt signing key fingerprint * Docker: avoid sandbox overlay deps during policy writes * Tests: assert no-deps sandbox rollback gateway recreate * Docs: mention OPENCLAW_INSTALL_DOCKER_CLI in Docker env vars --------- Co-authored-by: Jakub Karwowski <jakubkarwowski@Mac.lan> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…claw#29974) * feat(docker): add opt-in sandbox support for Docker deployments Enable Docker-based sandbox isolation via OPENCLAW_SANDBOX=1 env var in docker-setup.sh. This is a prerequisite for agents.defaults.sandbox to function in any Docker deployment (self-hosted, Hostinger, DigitalOcean). Changes: - Dockerfile: add OPENCLAW_INSTALL_DOCKER_CLI build arg (~50MB, opt-in) - docker-compose.yml: add commented-out docker.sock mount with docs - docker-setup.sh: auto-detect Docker socket, inject mount, detect GID, build sandbox image, configure sandbox defaults, add group_add All changes are opt-in. Zero impact on existing deployments. Usage: OPENCLAW_SANDBOX=1 ./docker-setup.sh Closes openclaw#29933 Related: openclaw#7575, openclaw#7827, openclaw#28401, openclaw#10361, openclaw#12505, openclaw#28326 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address code review feedback on sandbox support - Persist OPENCLAW_SANDBOX, DOCKER_GID, OPENCLAW_INSTALL_DOCKER_CLI to .env via upsert_env so group_add survives re-runs - Show config set errors instead of swallowing them silently; report partial failure when sandbox config is incomplete - Warn when Dockerfile.sandbox is missing but sandbox config is still applied (sandbox image won't exist) - Fix non-canonical whitespace in apt sources.list entry by using printf instead of echo with line continuation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove `local` outside function and guard sandbox behind Docker CLI check - Remove `local` keyword from top-level `sandbox_config_ok` assignment which caused script exit under `set -euo pipefail` (bash `local` outside a function is an error) - Add Docker CLI prerequisite check for pre-built (non-local) images: runs `docker --version` inside the container and skips sandbox setup with a clear warning if the CLI is missing - Split sandbox block so config is only applied after prerequisites pass Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: defer docker.sock mount until sandbox prerequisites pass Move Docker socket mounting from the early setup phase (before image build/pull) to a dedicated compose overlay created only after: 1. Docker CLI is verified inside the container image 2. /var/run/docker.sock exists on the host Previously the socket was mounted optimistically at startup, leaving the host Docker daemon exposed even when sandbox setup was later skipped due to missing Docker CLI. Now the gateway starts without the socket, and a docker-compose.sandbox.yml overlay is generated only when all prerequisites pass. The gateway restart at the end of sandbox setup picks up both the socket mount and sandbox config. Also moves group_add from write_extra_compose() into the sandbox overlay, keeping all sandbox-specific compose configuration together. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs(docker): fix sandbox docs URL in setup output * Docker: harden sandbox setup fallback behavior * Tests: cover docker-setup sandbox edge paths * Docker: roll back sandbox mode on partial config failure * Tests: assert sandbox mode rollback on partial setup * Docs: document Docker sandbox bootstrap env controls * Changelog: credit Docker sandbox bootstrap hardening * Update CHANGELOG.md * Docker: verify Docker apt signing key fingerprint * Docker: avoid sandbox overlay deps during policy writes * Tests: assert no-deps sandbox rollback gateway recreate * Docs: mention OPENCLAW_INSTALL_DOCKER_CLI in Docker env vars --------- Co-authored-by: Jakub Karwowski <jakubkarwowski@Mac.lan> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…claw#29974) * feat(docker): add opt-in sandbox support for Docker deployments Enable Docker-based sandbox isolation via OPENCLAW_SANDBOX=1 env var in docker-setup.sh. This is a prerequisite for agents.defaults.sandbox to function in any Docker deployment (self-hosted, Hostinger, DigitalOcean). Changes: - Dockerfile: add OPENCLAW_INSTALL_DOCKER_CLI build arg (~50MB, opt-in) - docker-compose.yml: add commented-out docker.sock mount with docs - docker-setup.sh: auto-detect Docker socket, inject mount, detect GID, build sandbox image, configure sandbox defaults, add group_add All changes are opt-in. Zero impact on existing deployments. Usage: OPENCLAW_SANDBOX=1 ./docker-setup.sh Closes openclaw#29933 Related: openclaw#7575, openclaw#7827, openclaw#28401, openclaw#10361, openclaw#12505, openclaw#28326 * fix: address code review feedback on sandbox support - Persist OPENCLAW_SANDBOX, DOCKER_GID, OPENCLAW_INSTALL_DOCKER_CLI to .env via upsert_env so group_add survives re-runs - Show config set errors instead of swallowing them silently; report partial failure when sandbox config is incomplete - Warn when Dockerfile.sandbox is missing but sandbox config is still applied (sandbox image won't exist) - Fix non-canonical whitespace in apt sources.list entry by using printf instead of echo with line continuation * fix: remove `local` outside function and guard sandbox behind Docker CLI check - Remove `local` keyword from top-level `sandbox_config_ok` assignment which caused script exit under `set -euo pipefail` (bash `local` outside a function is an error) - Add Docker CLI prerequisite check for pre-built (non-local) images: runs `docker --version` inside the container and skips sandbox setup with a clear warning if the CLI is missing - Split sandbox block so config is only applied after prerequisites pass * fix: defer docker.sock mount until sandbox prerequisites pass Move Docker socket mounting from the early setup phase (before image build/pull) to a dedicated compose overlay created only after: 1. Docker CLI is verified inside the container image 2. /var/run/docker.sock exists on the host Previously the socket was mounted optimistically at startup, leaving the host Docker daemon exposed even when sandbox setup was later skipped due to missing Docker CLI. Now the gateway starts without the socket, and a docker-compose.sandbox.yml overlay is generated only when all prerequisites pass. The gateway restart at the end of sandbox setup picks up both the socket mount and sandbox config. Also moves group_add from write_extra_compose() into the sandbox overlay, keeping all sandbox-specific compose configuration together. * docs(docker): fix sandbox docs URL in setup output * Docker: harden sandbox setup fallback behavior * Tests: cover docker-setup sandbox edge paths * Docker: roll back sandbox mode on partial config failure * Tests: assert sandbox mode rollback on partial setup * Docs: document Docker sandbox bootstrap env controls * Changelog: credit Docker sandbox bootstrap hardening * Update CHANGELOG.md * Docker: verify Docker apt signing key fingerprint * Docker: avoid sandbox overlay deps during policy writes * Tests: assert no-deps sandbox rollback gateway recreate * Docs: mention OPENCLAW_INSTALL_DOCKER_CLI in Docker env vars --------- Co-authored-by: Jakub Karwowski <jakubkarwowski@Mac.lan> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Summary
agents.defaults.sandboxin Docker deploymentsProblem
The current Docker setup (
Dockerfile,docker-compose.yml,docker-setup.sh) does not include Docker socket access or Docker CLI. This makes OpenClaw's sandbox feature completely non-functional in any Docker deployment. Without sandbox, agent code execution shares the gateway container's filesystem, network, and credentials — a significant security gap when agents process untrusted input (Telegram, WhatsApp, web).See #29933 for detailed security analysis and list of ~20 related issues this unblocks.
Changes
DockerfileOPENCLAW_INSTALL_DOCKER_CLI(same pattern as existingOPENCLAW_INSTALL_BROWSER)docker-compose.ymldocker.sockvolume mount with documentationgroup_addwithDOCKER_GIDvariable referencedocker-setup.shOPENCLAW_SANDBOXenvironment variable to enable sandbox setupOPENCLAW_EXTRA_MOUNTSOPENCLAW_INSTALL_DOCKER_CLI=1for local buildsgroup_addwith detected GID inwrite_extra_compose()openclaw-sandbox:bookworm-slimfrom existingDockerfile.sandboxagents.defaults.sandbox(mode=non-main, scope=agent, workspaceAccess=none)Usage
For hosting providers (Hostinger, DigitalOcean)
Minimum change on their side to enable sandbox in their templates:
Plus building with
--build-arg OPENCLAW_INSTALL_DOCKER_CLI=1.Test plan
./docker-setup.shwithoutOPENCLAW_SANDBOXworks exactly as beforeOPENCLAW_SANDBOX=1 ./docker-setup.shauto-detects socket, builds sandbox image, enables configdocker build --build-arg OPENCLAW_INSTALL_DOCKER_CLI=1installs Docker CLIdocker buildwithout the arg does not install Docker CLIgroup_addin extra compose uses correct GID from hostRelated issues
Closes #29933
Partially addresses / unblocks:
🤖 Generated with Claude Code