Linux sandbox fails on Ubuntu with AppArmor userns restrictions: bwrap loopback RTM_NEWADDR EPERM

Resolved 💬 12 comments Opened Mar 18, 2026 by giannisCKS Closed May 5, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

On Ubuntu, native npm-installed Codex fails to use its Linux sandbox when AppArmor unprivileged user namespace restrictions are enabled.

Repro

codex sandbox linux /bin/true

Actual result

bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted

Expected result

codex sandbox linux /bin/true should exit successfully.

Environment

  • Codex: codex-cli 0.115.0
  • Install method: native npm install
  • OS: Ubuntu
  • bubblewrap: 0.11.0-2
  • apparmor: 5.0.0~alpha1-0ubuntu8.3

Relevant sysctls:

kernel.apparmor_restrict_unprivileged_userns = 1
kernel.apparmor_restrict_unprivileged_unconfined = 1

Diagnosis

The issue appears to be in the native Linux sandbox path, not the JS/npm wrapper.

Tracing showed the sandbox fails when trying to assign 127.0.0.1/8 to loopback inside the sandboxed network namespace. The RTM_NEWADDR request returns EPERM.

Confirmed workaround

I confirmed a targeted AppArmor profile fixes the issue without disabling the restriction globally.

Profile used:

abi <abi/4.0>,
include <tunables/global>

@{codex_bin} = /home/nitro/.local/share/fnm/node-versions/v24.12.0/installation/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex/codex

profile codex-native @{codex_bin} flags=(unconfined) {
  userns,
  @{codex_bin} mr,

  include if exists <local/codex-native>
}

Then:

sudo install -m 0644 /tmp/codex-native.apparmor /etc/apparmor.d/codex-native
sudo apparmor_parser -r /etc/apparmor.d/codex-native
sudo mv /etc/sysctl.d/60-codex-userns.conf /etc/sysctl.d/60-codex-userns.conf.disabled
sudo sysctl --system
codex sandbox linux /bin/true

After this:

  • kernel.apparmor_restrict_unprivileged_userns = 1
  • kernel.apparmor_restrict_unprivileged_unconfined = 1
  • codex sandbox linux /bin/true succeeds

This keeps Ubuntu's AppArmor restrictions enabled globally and grants a targeted exception only to the native Codex binary.

Request

Please either document the Ubuntu/AppArmor requirement, detect this case with a better error, or provide guidance for a targeted AppArmor profile workaround.

View original on GitHub ↗

12 Comments

github-actions[bot] contributor · 4 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #14919

Powered by Codex Action

teebs4140 · 4 months ago

I can confirm this is still affecting a real Ubuntu Azure VM setup with newer Codex.

Environment:

  • Codex CLI: 0.116.0
  • OS: Ubuntu 24.04 on Azure VM
  • bubblewrap: /usr/bin/bwrap, version 0.9.0
  • Azure Monitor Agent healthy after repair/update
  • bubblewrap installed from apt
  • kernel before test: 6.8.0-1031-azure

Observed behavior:

  • Codex sandboxing/review worked after I installed system bubblewrap
  • After the VM was shut down overnight and started again, sandboxing failed again
  • Failure matched:
  • bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted

Important host state:

  • After reboot, this sysctl had reverted to:
  • kernel.apparmor_restrict_unprivileged_userns = 1
  • While that value was 1, Codex sandboxing failed again
  • After running:
  • sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
  • Codex sandboxing immediately worked again

What this suggests:

  • Even with codex-cli 0.116.0 and system /usr/bin/bwrap installed, Ubuntu/AppArmor userns restriction still breaks Codex sandboxing on this host after reboot unless the sysctl is temporarily relaxed
  • So this is not only a missing /usr/bin/bwrap problem
  • There is still a host-policy compatibility problem on Ubuntu/Azure VMs with AppArmor restriction enabled

It would help if Codex could either:

  1. work under Ubuntu’s default AppArmor restriction,
  2. detect this case and emit a very explicit diagnostic,
  3. or document the supported targeted AppArmor-profile workaround for the Codex binary.
congwang-mk · 3 months ago

The root cause is that bwrap depends on unprivileged user namespaces for network namespace setup (loopback configuration), and Ubuntu's AppArmor policy blocks this by default (apparmor_restrict_unprivileged_userns = 1). The workarounds -- custom AppArmor profiles, disabling the sysctl -- weaken the host security posture to accommodate the sandbox, which is counterproductive.

An alternative approach is to not use namespaces at all. sandlock provides process sandboxing using Landlock + seccomp-bpf + seccomp user notification -- no user namespaces, no mount namespaces, no network namespaces. Nothing that AppArmor restricts.

pip install sandlock
sandlock run -w . -r /usr -r /lib -r /etc -- /bin/true  # works with apparmor_restrict_unprivileged_userns=1

Network isolation is handled via Landlock TCP port rules (kernel 6.7+) and seccomp notification for domain-based allowlisting, rather than creating a network namespace and configuring loopback.

Disclaimer: I'm the sandlock author.

gcp · 3 months ago
The workarounds -- custom AppArmor profiles, disabling the sysctl -- weaken the host security posture to accommodate the sandbox

Saying that using the AppArmor profiles to allow _specific_ applications that use user namespaces for increased sandboxing to work, is a _less_ secure solution than using an untested vibecoded isolation tool is...quite the claim.

helgiborg · 3 months ago

I can confirm this is still reproducible for me on Ubuntu 24 with Codex 0.117.0.

Environment:

  • OS: Ubuntu 24
  • Codex: codex-cli 0.117.0
  • bubblewrap: 0.9.0
$ codex --version 
codex-cli 0.117.0 

$ bwrap --version 
bubblewrap 0.9.0 

$ codex sandbox linux -- /bin/true 
bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted 

$ sysctl kernel.apparmor_restrict_unprivileged_userns 
kernel.apparmor_restrict_unprivileged_unconfined 
kernel.apparmor_restrict_unprivileged_userns = 1 
kernel.apparmor_restrict_unprivileged_unconfined = 0

$ echo "OS: $(grep PRETTY_NAME /etc/os-release | cut -d= -f2- | tr -d '"')"; echo "Kernel: $(uname -r)"
OS: Ubuntu 24.04.4 LTS
Kernel: 6.17.0-19-generic

So in my case this still fails on 0.117.0, even though the 0.117 release notes mention improved Linux sandbox reliability.

I also see a related user-facing symptom in normal Codex runs: for each attempted file edit I get the approval prompt:

Would you like to make the following edits? Reason: command failed; retry without sandbox

without showing me the file list.

congwang-mk · 3 months ago

To clarify -- sandlock uses Landlock LSM and seccomp-bpf, both of which operate within the existing namespace. No user namespaces, no network namespaces, no RTM_NEWADDR. That's why it isn't affected by apparmor_restrict_unprivileged_userns at all.

This isn't a workaround for the AppArmor restriction -- it's a different architecture that doesn't need namespaces in the first place. Landlock and seccomp are upstream kernel security primitives, not something sandlock invented.

Regarding testing: the project has 131 Rust integration tests and 63 Python tests covering syscall filtering, network isolation, resource limits, filesystem COW, and policy enforcement. Happy to have more eyes on it.

80avin · 3 months ago
g-i-o-r-g-i-o · 3 months ago

Still reproducible on my machine as of 2026-04-20.

Environment:

  • codex-cli 0.122.0
  • Ubuntu 24.04 (kernel 6.8.0-110-generic)
  • bubblewrap 0.9.0
  • kernel.unprivileged_userns_clone = 1
  • user.max_user_namespaces = 63100
  • kernel.apparmor_restrict_unprivileged_userns = 1

Repro:

codex sandbox linux /bin/pwd

Actual:

bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted

Additional check outside Codex sandbox:

bwrap --ro-bind / / --proc /proc --dev /dev true

returns:

bwrap: setting up uid map: Permission denied

This is not workspace-specific; I see the same failure in /tmp and in a trusted project directory.

Confirmed workaround here too:

codex --enable use_legacy_landlock sandbox linux /bin/pwd

succeeds and prints the working directory.

So this still affects the current CLI and the Landlock fallback still works.

viyatb-oai contributor · 3 months ago

@g-i-o-r-g-i-o how was bubblewrap installed - via apt and is this a docker container?

Paste the output of

command -v bwrap
readlink -f "$(command -v bwrap)"
dpkg -S "$(readlink -f "$(command -v bwrap)")"
dpkg -L bubblewrap | grep -Ei 'apparmor|bwrap'
aa-status 2>/dev/null | grep -Ei 'bwrap|unpriv'
/usr/bin/bwrap --unshare-user --unshare-net --ro-bind / / --proc /proc --dev /dev /bin/true
sudo journalctl -k --since '10 min ago' | grep -Ei 'apparmor|bwrap|userns|RTM_NEWADDR'
g-i-o-r-g-i-o · 2 months ago
(python) user@user:/path$ command -v bwrap
/usr/bin/bwrap
(python) user@user:/path$ readlink -f "$(command -v bwrap)"
/usr/bin/bwrap
(python) user@user:/path$ dpkg -S "$(readlink -f "$(command -v bwrap)")"
bubblewrap: /usr/bin/bwrap
(python) user@user:/path$ dpkg -L bubblewrap | grep -Ei 'apparmor|bwrap'
/usr/bin/bwrap
/usr/share/bash-completion/completions/bwrap
/usr/share/man/man1/bwrap.1.gz
/usr/share/zsh/vendor-completions/_bwrap
(python) user@user:/path$ aa-status 2>/dev/null | grep -Ei 'bwrap|unpriv'
(python) user@user:/path$ /usr/bin/bwrap --unshare-user --unshare-net --ro-bind / / --proc /proc --dev /dev /bin/true
bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted
(python) user@user:/path$ sudo !!
sudo /usr/bin/bwrap --unshare-user --unshare-net --ro-bind / / --proc /proc --dev /dev /bin/true
[sudo] password for user: 
(python) user@user:/path$ sudo /usr/bin/bwrap --unshare-user --unshare-net --ro-bind / / --proc /proc --dev /dev /bin/true
(python) user@user:/path$ sudo journalctl -k --since '10 min ago' | grep -Ei 'apparmor|bwrap|userns|RTM_NEWADDR'
apr 25 19:45:13 user kernel: audit: type=1400 audit(1777139113.285:259): apparmor="AUDIT" operation="userns_create" class="namespace" info="Userns create - transitioning profile" profile="unconfined" pid=137534 comm="bwrap" requested="userns_create" target="unprivileged_userns"
(python) user@user:/path$ 
viyatb-oai contributor · 2 months ago

please follow the instructions on https://developers.openai.com/codex/concepts/sandboxing#prerequisites for ubuntu 24.04 and let me know if you can still reproduce this on latest codex release.

<img width="1870" height="1028" alt="Image" src="https://github.com/user-attachments/assets/698a275a-731c-4f64-9397-e64cd1808b90" />

abulgher · 2 months ago
please follow the instructions on https://developers.openai.com/codex/concepts/sandboxing#prerequisites for ubuntu 24.04 and let me know if you can still reproduce this on latest codex release. <img alt="Image" width="1870" height="1028" src="https://private-user-images.githubusercontent.com/234056686/587442490-698a275a-731c-4f64-9397-e64cd1808b90.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Nzc5NTU0OTIsIm5iZiI6MTc3Nzk1NTE5MiwicGF0aCI6Ii8yMzQwNTY2ODYvNTg3NDQyNDkwLTY5OGEyNzVhLTczMWMtNGY2NC05Mzk3LWU2NGNkMTgwOGI5MC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYwNTA1JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MDUwNVQwNDI2MzJaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1jNWQ5NTA1YzUxYjNjNDlmZWQ3MTI1M2Y5YmRjYzFmYmZkNTFhMjlhMTA5NTZiYWEwYzBjZTdiZmM2MjA5ZTEyJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ.pt8_YX7pqcE-J32ORfLhDTNO19skuD5nP70cuUfqx8o">

I have no root rights on the development machine. I cannot run the provided instructions.

In my case executing codex sandbox linux /bin/pwd works, but during a coding session I keep on getting plenty of requests to allow codex to perform all commands due to failure to execute in the sandbox.