Repository navigation
Codex ACP exits Operation not permitted in unprivileged Docker before ACP initialize #470
Description
Summary
@agentclientprotocol/codex-acp cannot initialize Codex App Server inside an unprivileged Docker container when using a mounted ChatGPT login. The ACP subprocess exits before responding to initialize with Operation not permitted.
This prevents Agent Canvas from using the Codex ACP provider in a containerized self-hosted backend.
Environment
- Host: Debian 13, x86_64, Docker Engine
- Container: official
ghcr.io/openhands/agent-canvas:1.16.0@sha256:ab194760cb46098641747b27c1e07458ab1bed439821af7a31c97133ca466bb8 - Container user:
openhandsUID 10001 - ACP adapter:
@agentclientprotocol/codex-acp@1.8.0 - Bundled Codex dependency:
@openai/codex@0.152.1 CODEX_HOME=/home/openhands/.codex- Host
/root/.codexis mounted read-write at/home/openhands/.codex - The mounted
auth.jsonis readable and writable, and Codex login status exits 0 - Host user namespaces are enabled (
user.max_user_namespacesis nonzero andkernel.unprivileged_userns_clone=1) - The container runs without
privileged,SYS_ADMIN, orseccomp=unconfined
Reproduction
Start the adapter in the container:
CODEX_HOME=/home/openhands/.codex \
INITIAL_AGENT_MODE=agent-full-access \
NO_BROWSER=1 \
CODEX_CONFIG='{"sandbox_mode":"danger-full-access","approval_policy":"never"}' \
npx -y @agentclientprotocol/codex-acpSend newline-delimited JSON-RPC over stdin:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{},"clientInfo":{"name":"verification","version":"1"}}}Expected: an ACP initialize result.
Actual: ACP error response, code 1001, with the Codex process error:
WARNING: proceeding, even though we could not create PATH aliases: Operation not permitted (os error 1)
Error: Operation not permitted (os error 1)
session/new cannot be reached because initialize fails first. The test used the standard ACP newline-delimited JSON stream implemented by this repository's createJsonStream/StdUtils.
Additional observations
-
The older documented command
npx -y @zed-industries/codex-acp(0.16.0) also failed in the same container, reporting that bubblewrap was unavailable and thenOperation not permitted. -
unshare -Ur truefails in the default OpenHands container withOperation not permitted. -
A disposable test with only Docker
seccomp=unconfinedallowed the rawunshareoperation, but the production container was not given that setting. A full ACP handshake under that disposable test was inconclusive. -
INITIAL_AGENT_MODE=agent-full-accesswas set as documented by the current adapter, but Codex App Server still fails during startup before ACP initialization. -
An OpenHands-only
config.tomlmounted over the host Codex config with:sandbox_mode = "danger-full-access" approval_policy = "never"
did not resolve the startup error.
-
No host Codex configuration was modified. No credentials or token values are included here.
Requested behavior
Please document or fix the containerized startup path so Codex ACP can complete initialize and session/new when:
CODEX_HOME/auth.jsonis supplied by a mounted ChatGPT login;INITIAL_AGENT_MODE=agent-full-accessis selected; and- the enclosing container provides the isolation boundary.
If Docker requires a specific minimal capability/seccomp/AppArmor configuration, please document the exact requirements. Ideally the adapter should apply the selected full-access mode before Codex App Server startup, without requiring privileged for the entire parent container.
Related: #310 (sandbox and approval policies from config.toml are ignored).
Activity