Explicitly allowlisted loopback target still requires allow_local_binding

Open 💬 0 comments Opened Jul 15, 2026 by liby

What version of the Codex App are you using (From “About Codex” dialog)?

26.707.72221 (5307), with bundled codex-cli 0.144.2

What subscription do you have?

Not relevant to this locally reproducible sandbox issue.

What platform is your computer?

Darwin 25.5.0 arm64 arm

What issue are you seeing?

An explicitly allowlisted loopback IP remains unreachable when allow_local_binding = false.

This was first observed in Codex Desktop with a custom permission profile, then reproduced independently with the App's bundled codex sandbox command. The same loopback HTTP request succeeds only after setting allow_local_binding = true.

That makes it impossible to grant a narrow exception for one loopback literal while keeping the broader local/private-network protection enabled.

This differs from #23973: that issue reports the Desktop App ignoring allow_local_binding = true for listener binding. This report concerns an outbound connection to an explicitly allowlisted loopback target.

What steps can reproduce the bug?

Use a permission profile with managed networking enabled and only the loopback literal allowlisted:

default_permissions = "development"

[features]
network_proxy = true

[permissions.development.network]
enabled = true
allow_local_binding = false

[permissions.development.network.domains]
"127.0.0.1" = "allow"

Start an HTTP server outside the Codex sandbox:

$ python3 -m http.server 38765 --bind 127.0.0.1

Verify the host-side control request:

$ curl --max-time 5 -sS -o /dev/null -w 'HTTP=%{http_code}\n' http://127.0.0.1:38765/
HTTP=200

Run the same request in the named permission profile. These are the exact overrides used to make the policy under test explicit:

$ codex sandbox -P development --enable network_proxy \
    -c 'permissions.development.network.allow_local_binding=false' \
    -c 'permissions.development.network.domains={"127.0.0.1"="allow"}' \
    curl --max-time 5 -sS -o /dev/null -w 'HTTP=%{http_code}\n' \
    http://127.0.0.1:38765/
curl: (7) Failed to connect to 127.0.0.1 port 38765 after 0 ms: Could not connect to server
HTTP=000

Forcing curl through the managed proxy instead of the injected loopback NO_PROXY entry also fails:

$ codex sandbox -P development --enable network_proxy \
    -c 'permissions.development.network.allow_local_binding=false' \
    -c 'permissions.development.network.domains={"127.0.0.1"="allow"}' \
    curl --noproxy '' --max-time 5 -sS -D - -o /dev/null \
    http://127.0.0.1:38765/
HTTP/1.1 502 Bad Gateway

Changing only allow_local_binding to true makes the request succeed:

$ codex sandbox -P development --enable network_proxy \
    -c 'permissions.development.network.allow_local_binding=true' \
    -c 'permissions.development.network.domains={"127.0.0.1"="allow"}' \
    curl --max-time 5 -sS -o /dev/null -w 'HTTP=%{http_code}\n' \
    http://127.0.0.1:38765/
HTTP=200

What is the expected behavior?

With "127.0.0.1" = "allow", that literal loopback target should be reachable while allow_local_binding = false; other non-allowlisted local and private targets should remain blocked.

This matches the documented contract: explicit allowlisting of a local IP literal or localhost is described as the narrow exception when local/private networking is otherwise disabled.

Additional information

The current network-proxy README states that explicit local IP literals or localhost can be allowlisted while allow_local_binding = false: README.md.

Potentially relevant code paths, provided as supporting evidence rather than a confirmed root-cause claim:

  • NetworkProxyState::host_blocked contains the explicit-local-literal exception: runtime.rs.
  • The downstream connector rejects every non-public target whenever allow_local_binding is false, without receiving the host-policy decision: connect_policy.rs.
  • Managed proxy environment setup includes loopback literals in NO_PROXY, so ordinary curl requests bypass the proxy: proxy.rs.

View original on GitHub ↗