RFC: codex container provisioner — add --cap-add NET_ADMIN so bwrap --unshare-net works (revert sandbox to workspace-write) #1693

Open
opened 2026-05-22 23:38:43 +00:00 by hongming · 0 comments
Owner

Why

Codex CLI 0.130+ runs tool calls under bwrap with --unshare-net by default — codex tries to create a private network namespace, then sets up loopback inside it. Inside our docker container this fails with:

bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted

because the container doesn't carry CAP_NET_ADMIN. Even setting sandboxPolicy.network_access: True in the codex thread/start params doesn't help — bwrap still tries to bring up a netns and still fails.

Current workaround (in PR #30)

executor.py's sandboxPolicy is set to {"mode": "danger-full-access"} which bypasses bwrap entirely. Works, but loses the bwrap sandboxing (writable-root protection, filesystem allowlist, etc.).

Proper fix

molecule-controlplane provisioner adds --cap-add NET_ADMIN to the docker run args for codex template containers. Once that ships, revert executor.py to:

params["sandboxPolicy"] = {
    "mode": "workspace-write",
    "network_access": True,
}

and codex regains its proper sandboxing while still having network access.

Where to patch

molecule-controlplane — the function that emits docker run args for codex template workspaces. Look for the codex template branch in the provisioner; add NET_ADMIN to the cap-add list (others like T4's docker.sock + --privileged setup may already be there for the escalation leg; NET_ADMIN should be ADDITIVE).

Acceptance

  • docker inspect <codex-container> shows "CapAdd": ["NET_ADMIN", ...]
  • Inside container: bwrap --unshare-net --bind / / true exits 0 instead of Operation not permitted
  • Revert executor.py sandboxPolicy back to workspace-write + network_access:True via a template PR; codex agents still complete real Gitea-write turns
  • Smoke test: PM dispatches CR for a non-author PR review, CR successfully posts the review via Gitea API

Why a separate cap (not --privileged or --cap-add ALL)

  • NET_ADMIN narrowly allows netns + iface mgmt for bwrap; no extra footgun (no /dev/mem access, no SYS_ADMIN, no module load)
  • Auditable in docker inspect output

Related

  • PR #30 (template-codex) — the workaround currently shipping
  • The codex 0.130 schema/sandbox saga generally — see PR #30 description for the broader investigation

Owner

TBD. Estimated ~half day (provisioner change + smoke).

## Why Codex CLI 0.130+ runs tool calls under bwrap with `--unshare-net` by default — codex tries to create a private network namespace, then sets up loopback inside it. Inside our docker container this fails with: ``` bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted ``` because the container doesn't carry `CAP_NET_ADMIN`. Even setting `sandboxPolicy.network_access: True` in the codex thread/start params doesn't help — bwrap still tries to bring up a netns and still fails. ## Current workaround (in PR #30) executor.py's sandboxPolicy is set to `{"mode": "danger-full-access"}` which bypasses bwrap entirely. Works, but loses the bwrap sandboxing (writable-root protection, filesystem allowlist, etc.). ## Proper fix molecule-controlplane provisioner adds `--cap-add NET_ADMIN` to the docker run args for codex template containers. Once that ships, revert executor.py to: ```python params["sandboxPolicy"] = { "mode": "workspace-write", "network_access": True, } ``` and codex regains its proper sandboxing while still having network access. ## Where to patch `molecule-controlplane` — the function that emits docker run args for codex template workspaces. Look for the codex template branch in the provisioner; add NET_ADMIN to the cap-add list (others like `T4`'s docker.sock + --privileged setup may already be there for the escalation leg; NET_ADMIN should be ADDITIVE). ## Acceptance - `docker inspect <codex-container>` shows `"CapAdd": ["NET_ADMIN", ...]` - Inside container: `bwrap --unshare-net --bind / / true` exits 0 instead of `Operation not permitted` - Revert executor.py sandboxPolicy back to workspace-write + network_access:True via a template PR; codex agents still complete real Gitea-write turns - Smoke test: PM dispatches CR for a non-author PR review, CR successfully posts the review via Gitea API ## Why a separate cap (not --privileged or --cap-add ALL) - NET_ADMIN narrowly allows netns + iface mgmt for bwrap; no extra footgun (no /dev/mem access, no SYS_ADMIN, no module load) - Auditable in `docker inspect` output ## Related - PR #30 (template-codex) — the workaround currently shipping - The codex 0.130 schema/sandbox saga generally — see PR #30 description for the broader investigation ## Owner TBD. Estimated ~half day (provisioner change + smoke).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#1693