Skip to main content
Codex is OpenAI’s CLI coding agent. It reads repositories, writes files, runs commands, and stores local session state. Running it under nono keeps that access confined to the project and state paths you intentionally grant.
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
nono makes those boundaries kernel-enforced instead of advisory.

Quick Start

If the registry pack 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-drafts for persistent capability drafts
  • Read+write access to user cache directories (~/.cache on both platforms, plus ~/Library/Caches and ~/Library/Logs on 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, including codex 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 ~/.codex grant required for Codex state. --no-daemon is therefore the required isolation control.
The flag depends on the command’s execution model: 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 signed nolabs-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:
After the one-second input guard enables the prompt, press 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:
The actual managed 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 during nono 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:
The general cached pack checker may additionally show a one-line 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 enabled nono@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

Reverses the recorded marketplace, cache, profile-drafts marker, managed 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:
Then start interactive sessions with 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 opens https://auth.openai.com during the OAuth flow. The profile includes the required browser-open allowlist:
  • https://auth.openai.com
  • localhost callbacks for the OAuth redirect
On Linux, no additional flags are needed:
On macOS, enable LaunchServices temporarily for the login session:
After login completes, exit and rerun without --allow-launch-services.
--allow-launch-services lets the sandboxed Codex process ask macOS LaunchServices to open URLs, files, or apps for that session. Use it only for temporary login or setup flows, and prefer running it from a trusted directory.

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:
Then run the noninteractive review command. Unlike the interactive TUI, 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

The allow_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 --self cannot see NONO_CAP_FILE, so a command cannot introspect the active nono capability set.
Option 1: Allow login shell in nono sandbox
Codex defaults allow_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’s shell_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.
Filter matching is case-insensitive, so the uppercase proxy entries also preserve nono’s lowercase 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:
See Network Filtering and Security Profiles for details on host allowlists, profile format, and precedence rules.