When you run Codex under
nono, keep the interactive client and its app server inside the same sandbox, and prefer a single filesystem and network boundary: use --no-daemon, let nono enforce access, and start Codex with its own sandbox disabled.Recommended invocation:--no-daemon makes the TUI use an embedded app server instead of attaching to the shared background server. --sandbox danger-full-access avoids a nested Codex sandbox, while --ask-for-approval on-request retains Codex’s operator approval flow. See OpenAI’s CLI reference and agent approvals and security docs.Why Sandbox Codex?
Codex is designed to inspect code, execute tools, and persist local state. Without isolation:- It could read files outside the repository you meant to expose
- A prompt injection or tool mistake could modify unrelated files on the same machine
- Long-lived local state could become a path for broader access than the current task needs
Quick Start
nolabs-ai/codex isn’t installed yet, nono prompts to pull it (see Automatic Pack Install and Plugin Wiring below).
The pack profile provides:
- Read+write access to the current working directory after nono’s standard CWD consent prompt (or when started with
--allow-cwd) - Read+write access to
~/.codex(config, auth state, sessions, caches, and local metadata) and~/.agents - Read+write access to
~/.config/nono/profile-draftsfor persistent capability drafts - Read+write access to user cache directories (
~/.cacheon both platforms, plus~/Library/Cachesand~/Library/Logson macOS) - Read access to common user-local runtime paths for Rust, Node.js, Python, and Nix toolchains; macOS also grants
~/Library/Preferences, and Linux grants/sys - macOS credential access to
~/Library/Keychains, which the profile explicitly exempts from the default keychain deny rules for Codex authentication - OAuth login support via supervised URL opening on Linux and a temporary LaunchServices flag on macOS
- Network access enabled
- Interactive mode enabled for the terminal UI
App-server isolation
Recent Codex versions normally connect the TUI to a shared background app server. That server owns the agent harness and tool execution and can outlive the TUI that started it. Sandboxing only the TUI is therefore insufficient: it could attach to a server outside nono and execute tools with that server’s access. For interactive sessions, includingcodex resume and codex fork, always use --no-daemon. It bypasses daemon discovery without stopping or disrupting any shared daemon used by other Codex clients.
- macOS: the pack denies Codex’s shared-daemon control paths as fail-closed protection. If Codex cannot connect, restart with
--no-daemon; it does not automatically fall back to an embedded server. - Linux: Landlock cannot subtract the daemon socket from the broader read-write
~/.codexgrant required for Codex state.--no-daemonis therefore the required isolation control.
The outer nono sandbox applies to the command and all processes it starts. It cannot constrain an already-running daemon outside that process tree. Conversely,
--sandbox danger-full-access only disables Codex’s nested sandbox; it does not disable nono.
Automatic Pack Install and Plugin Wiring
The Codex profile is distributed as the signednolabs-ai/codex package along with a Codex plugin that provides a sandbox-diagnostic skill and startup instructions.
The first time you run the canonical interactive command, nono prompts to install the pack:
Y. Pressing Enter
uses the safe default and skips installation. nono pulls the pack, verifies its
Sigstore provenance, and writes Codex’s plugin wiring to the marketplace,
cache, and configuration paths Codex reads.
What the pull writes
The
config.toml block is fenced with markers so re-pulls and removals never touch your other settings:
developer_instructions block contains the complete denial-confirmation and recovery rules; the abbreviated text above only illustrates its position. The fenced merge leaves every setting outside the managed block untouched.
Fresh installs deliberately do not register lifecycle hooks. Codex currently renders hook output in the TUI even for silent hook entries, so the pack uses its plugin skill and developer_instructions instead. The packaged hook scripts are compatibility no-ops for older installations whose hooks.json may still reference them.
Subsequent runs
Once installed, the canonical interactive command runs without an installation prompt. nono’s profile resolver loads the installed profile from the package store. Plugin wiring is applied duringnono pull and nono update, recorded in the package lockfile, and reversed by nono remove; an ordinary nono run does not repair deleted wiring.
Because Codex is a security-sensitive official pack, nono checks its registry status before launching. An outdated installed version produces:
run: nono update hint. Use either printed update command, or run nono outdated to inspect all installed packs. See Managing Packs for pinning and other options.
Skipping or automating the prompt
Skill-driven sandbox diagnostics
The enablednono@nolabs-ai plugin exposes the nono-sandbox skill. Together with the managed startup instructions, it teaches Codex to distinguish generic permission failures from confirmed nono denials, run nono why --self when a concrete path is available, and offer either a narrowly scoped one-off restart or a structured profile draft.
Codex approval cannot expand the capabilities of an already-running nono sandbox. A confirmed denial requires restarting nono with the missing capability or promoting a derived profile.
Removing the pack
config.toml, and draft-helper wiring, then removes the pack store and lockfile entry. User-authored Codex settings and unrelated hooks are left untouched. If a reversal fails, nono preserves the lockfile entry and reports the conflict unless you explicitly use --force.
Custom Profile
Create~/.config/nono/profiles/my-codex.json if you want different permissions. Extend the pack profile so you keep all its grants (groups, OAuth origin, etc.) and just add what you need:
nono run --profile my-codex -- codex --no-daemon --sandbox danger-full-access --ask-for-approval on-request.
The
extends chain inherits the package profile’s policy (allow paths, runtime groups, OAuth origin, and other profile fields) and merges your additions on top. The package’s plugin wiring is installed separately by nono pull; it is not a profile field. Package profiles require their fully-qualified name; a user profile named codex is separate and does not shadow nolabs-ai/codex.Security Tips
OAuth Login
Codex login openshttps://auth.openai.com during the OAuth flow.
The profile includes the required browser-open allowlist:
https://auth.openai.comlocalhostcallbacks for the OAuth redirect
--allow-launch-services.
Restrict to a Specific Project
The profile grants access to the directory you run Codex from. To pin access to a specific repository:Read-Only Workspace
If you want Codex to keep all pack-provided state and runtime access but not modify the repository, create~/.config/nono/profiles/codex-read-only.json:
codex review starts its app server in the same codex process instead of connecting to the shared background daemon. That process remains inside nono, so --no-daemon is not needed here. --sandbox danger-full-access disables Codex’s nested sandbox, not the outer nono sandbox:
Block Network for Local-Only Work
If you want to inspect local code without allowing outbound access:Use Network Filtering
If you want Codex limited to the built-in host allowlist for coding workflows:Codex Shell-based Tools
Theallow_login_shell configuration key in Codex controls whether shell-based tools may request login-shell semantics. When it is false, requests with login = true are rejected, while requests that omit login use a non-login shell. On affected tool paths, that non-login-shell environment can omit values that nono injected into the Codex process, even when Codex’s own sandbox is disabled.
If those values are missing:
- proxy-filtered network requests from Codex commands fail even for allowed destinations because the proxy variables or token are unavailable;
nono why --selfcannot seeNONO_CAP_FILE, so a command cannot introspect the active nono capability set.
Option 1: Allow login shell in nono sandbox
Codex defaultsallow_login_shell to true; if neither your configuration nor a managed requirement disables it, the network-filtering command above is already sufficient. To override a user configuration that set it to false, pass the setting explicitly. Because nono is already enforcing the outer sandbox, this disables only the optional Codex login-shell hardening for that invocation.
Recommended invocation:
Option 2: Explicit configuration
An alternative, more secure, and explicit approach is to keep optional hardening enabled and configure Codex’sshell_environment_policy so that required environment variables are passed to the subprocess.
Set allow_login_shell=false in the Codex configuration, then add the shell_environment_policy block and explicitly include the required exports. The filters map is the current form of this policy; the older include_only array remains supported by Codex for compatibility but is legacy configuration.
Keep ignore_default_excludes = true here. Codex’s automatic secret-name filter runs before explicit filters and would otherwise remove NONO_PROXY_TOKEN; an include rule cannot restore it. The explicit include filters still form an allowlist, so unlisted environment variables remain excluded.
http_proxy, https_proxy, and no_proxy exports. See OpenAI’s configuration reference for the complete shell_environment_policy semantics.
Additional Home-Directory Tools
The profile covers common Rust, Node.js, Python, and Nix runtime locations under~/, but some developer tools still install into other home-directory paths such as ~/go/bin or ~/.bun/bin.
If a tool exists on your PATH but Codex cannot launch it inside the sandbox, grant read access to the specific path entry: