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, prefer a single sandbox layer: let nono enforce filesystem and network boundaries, and start Codex with its own sandbox disabled.Recommended invocation:
This keeps Codex’s approval flow while avoiding nested sandboxes that can make denials harder to diagnose. See OpenAI’s 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 always-further/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
  • Read+write access to ~/.codex (config, auth state, sessions, caches, and local metadata) and ~/.agents
  • Read access to common user-local runtime paths for Rust, Node.js, Python, and Nix toolchains, plus ~/Library/Preferences (Codex queries CFPreferences on startup)
  • 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

Automatic Pack Install and Plugin Wiring

The codex profile is distributed as a signed registry pack at always-further/codex along with a Codex plugin that provides sandbox-aware diagnostic hooks and a skill for guiding the user through denial-recovery. The first time you run nono run --profile always-further/codex -- codex, nono prompts to install the pack:
Press Y. nono pulls the pack, verifies its Sigstore provenance, and writes Codex’s plugin wiring directly to the files Codex actually reads (verified against openai/codex source — not the ~/.agents/plugins/marketplace.json that some external docs hint at).

What the pull writes

The config.toml block is fenced with markers so re-pulls and removals never touch your other settings:

Activating the hooks

Codex requires an opt-in feature flag for hooks. Add the following to ~/.codex/config.toml (the section header and the key must be on separate lines — this is TOML, not a single-line declaration):
nono never writes this flag — opting into a Codex feature is your call. After nono pull you’ll see a one-line reminder if the flag isn’t set:

Subsequent runs

Once installed, nono run --profile always-further/codex -- codex runs silently — no prompt. nono’s profile resolver finds codex in the pack store and re-asserts the marketplace + cache wiring on every run, so deleting any of the entries above is recovered transparently on the next nono run. If a newer version of the pack is available, nono prints a one-line hint after the capabilities block:
Run nono update to apply it, or nono outdated to check all installed packs at once. See Managing Packs for pinning and other options.

Skipping or automating the prompt

Hook-driven sandbox diagnostics

The pack’s hooks wire into three Codex events:
  • PostToolUse for Bash, apply_patch, and MCP file tools — when the tool’s output matches a sandbox-denial signature (Operation not permitted, EACCES, EPERM, landlock), the hook returns decision: block with a reason string. Codex pauses the agent loop and shows the reason to the user verbatim — no LLM paraphrasing, no “Want me to run nono why?” dangler. The reason includes the diagnostic, the allowed paths, and an inline JSON template for the Option B persistent-fix profile (extends codex and adds the blocked path).
  • PermissionRequest — when Codex’s approval flow asks the user to escalate, the hook denies upstream with a message explaining that approval can’t grant access the OS sandbox already blocks. The user is told to restart with --allow <path>.
  • SessionStart — pre-loads the sandbox boundary into the conversation as additionalContext, so the model understands the limits from turn 1 and won’t reach for “macOS TCC” or “chmod” diagnoses on the first denial.
In permission_mode = "bypassPermissions" (Codex’s yolo mode), all three hooks stay silent — the user has explicitly opted into running without approval.

Removing the pack

Removes the pack store directory, the cache subtree, the fenced block from config.toml, the hook entries from hooks.json, and the lockfile entry. [features] codex_hooks = true is left alone — it’s a user-set Codex preference, not something nono installed.

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 sessions with nono run --profile my-codex -- codex.
The extends chain pulls in everything the pack profile declares (allow paths, runtime groups, OAuth origin, hook plugin) and merges your additions on top. If you instead create a profile literally named codex in ~/.config/nono/profiles/, it shadows the pack profile entirely — you take responsibility for the full configuration.

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 its local state but not modify the repository:

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 use login-shell semantics. When disabled, login-shell requests are rejected and the subprocess falls back to a non-login shell. This matters because, even with the Codex sandbox disabled, Codex subprocesses will have a narrow set of environment variables. As a result:
  • when domain filtering is enabled, all network requests from commands executed by Codex are denied, regardless of the allowlist;
  • tool commands no longer appear to run inside nono.
Option 1: Allow login shell in nono sandbox
Because nono is already sandboxing the execution and filtering environment variables, you can start Codex with its own sandbox and optional hardening disabled. 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 list required exports:

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.