Codex Sandbox and Approvals skill for Codex
The narrowest boundary that still finishes the job. Codex matches the task to a sandbox mode and approval policy from a decision table, grants only the extra directories, network access or domains the work needs, and proves the boundary with codex sandbox before relying on it. It knows the protected paths, the network proxy's real scope, the retired untrusted policy and how beta permission profiles interact with sandbox_mode.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- codex-sandbox-approvals Installs to ~/.agents/skills/codex-sandbox-approvals/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install codex-sandbox-approvals The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project codex-sandbox-approvals Installs to .agents/skills/codex-sandbox-approvals/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/codex-sandbox-approvals.zipunzip -o codex-sandbox-approvals.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) codex-sandbox-approvals PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $codex-sandbox-approvals, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Chooses and configures the Codex sandbox mode (read-only, workspace-write, danger-full-access), approval policy (on-request, never, granular), automatic approval review, network access and domain allowlists, extra writable roots and beta permission profiles for a given task, then tests the boundary with codex sandbox. Use when deciding how much autonomy to give Codex, when commands fail with sandbox or network denials, when Codex asks for approval too often or not enough, or before running Codex unattended.
Use it when
- Deciding how much autonomy to give Codex for a task
- Commands fail with sandbox or network denials
- Approval prompts are too frequent or too rare
- Preparing an unattended or containerized run
Use something else when
- Hardening Codex for untrusted repositories or a whole team: use codex-security-hardening
- Configuring sandbox inputs of the GitHub Action: use codex-github-action
How to check the result
Run codex sandbox macos or linux with a write outside the workspace and a blocked network request, confirm both are denied, then check /status for the expected mode and writable roots.
The mistake it prevents
Turning on the network proxy domain list without network_access, or network_access without the proxy, and believing traffic is restricted.
The right setting is the narrowest boundary that lets the task finish without a human babysitting it. Two independent controls decide this: the sandbox (what commands can technically touch) and the approval policy (when Codex must stop and ask before crossing the sandbox). Pick both deliberately, then prove the boundary with a test command.
Decision table
| Task | Sandbox | Approvals | Flags |
|---|---|---|---|
| Explore, explain, plan; no edits | read-only | on-request | codex -s read-only -a on-request |
| Normal local coding in a git repo (Auto preset) | workspace-write | on-request | default, or -s workspace-write -a on-request |
| Same, but fewer interruptions with a safety net | workspace-write | on-request + approvals_reviewer = "auto_review" | -c approvals_reviewer=auto_review |
| Needs package installs or API calls | workspace-write + network on, ideally domain-limited | on-request | -c sandbox_workspace_write.network_access=true |
| CI analysis, reports, reviews | read-only | never asks (exec default) | codex exec (read-only by default) |
| CI that edits the checkout | workspace-write | never asks | codex exec -s workspace-write |
| Inside a disposable container or VM that is the real boundary | danger-full-access | never | --dangerously-bypass-approvals-and-sandbox (alias --yolo) only there |
Default to the Auto preset for interactive work. Escalate one notch at a time, and prefer granting a specific directory or domain over switching to full access.
How each control behaves
Sandbox modes (enforced by the OS: Seatbelt on macOS, bwrap plus seccomp on Linux and WSL2, MXC or legacy elevated/unelevated sandbox on native Windows):
read-only: commands can read; no writes, no network.workspace-write: writes inside the workspace (cwd plus temp dirs, see/status) and any--add-dir/writable_roots; network off unless enabled..git,.agents,.codexand.awsunder writable roots stay read-only, recursively, sogit commitnormally needs approval.danger-full-access: no sandbox. Web search also defaults to live results here.
Approval policies:
on-request: commands inside the sandbox run freely; Codex asks before leaving it (writing outside, network when off, other escalations).never: never asks; anything the sandbox blocks fails and the error goes back to the model. Pair with the narrowest sandbox that still works.{ granular = { sandbox_approval = true, rules = true, mcp_elicitations = true, request_permissions = false, skill_approval = false } }: keep some prompt categories interactive, auto-reject the others.untrustedis retired and can stop Codex from starting. For “ask before everything not explicitly allowed”, omitapproval_policyand mark the project[projects."/path"] trust_level = "untrusted"; execpolicy rules then decide (rules match command argument prefixes only, so allowgit status, not a pattern inside args).
Automatic approval review (approvals_reviewer = "auto_review") routes requests that
already need approval through a reviewer agent instead of you. It does not widen the
sandbox, fails closed on errors and timeouts, and costs extra model calls. In the TUI,
/approve retries one recent denial. In codex exec, --approve-for-me uses
workspace-write plus automatic review.
Workflow
- [ ] 1. Identify what the task must write and which hosts it must reach
- [ ] 2. Pick sandbox + approval from the table
- [ ] 3. Grant the minimum extras (dirs, network, domains)
- [ ] 4. Test the boundary with codex sandbox before relying on it
- [ ] 5. Record the choice (profile file or AGENTS.md note)
3. Grant the minimum extras
Extra writable directory for one run (beats switching to full access):
codex --add-dir ../shared-lib
Network for commands, limited to specific domains (the proxy enforces the list only when network is on AND the proxy feature is on):
[sandbox_workspace_write]
network_access = true
[features.network_proxy]
enabled = true
domains = { "registry.npmjs.org" = "allow", "pypi.org" = "allow", "files.pythonhosted.org" = "allow" }
Domain patterns: exact host; *.example.com subdomains only; **.example.com apex plus
subdomains; * allow-all. deny beats allow. Local and private addresses stay blocked
unless you allow an exact localhost or IP literal (or set allow_local_binding = true).
Per-repo strictness without global changes:
[projects."/Users/me/src/vendor-fork"]
trust_level = "untrusted"
Permission profiles (beta)
Named profiles combine filesystem and network rules: built-ins :read-only,
:workspace, :danger-full-access, or custom [permissions.<name>] selected by
default_permissions. They do not compose with sandbox_mode: if sandbox_mode appears
in any loaded layer or --sandbox is passed, the older settings win and the profile is
ignored. Use one model per machine.
default_permissions = "project-edit"
[features]
network_proxy = true
[permissions.project-edit]
extends = ":workspace" # keeps .git/.agents/.codex/.aws read-only
[permissions.project-edit.filesystem.":workspace_roots"]
"**/*.env" = "deny"
[permissions.project-edit.network]
enabled = true
[permissions.project-edit.network.domains]
"api.github.com" = "allow"
4. Test the boundary
codex sandbox runs any command under the same policy Codex uses:
codex sandbox macos --log-denials -- touch ../outside.txt # expect a denial
codex sandbox linux -- curl -sI https://example.com # expect failure with network off
codex sandbox macos --permissions-profile project-edit -- cat .env # expect denied
Then in the TUI run /status to confirm sandbox, approval policy and writable roots, and
/permissions to switch modes mid-session.
Gotchas
- The command network proxy filters only commands Codex spawns. Web search, MCP servers,
apps/connectors and model traffic are separate; restrict them with
web_search,mcp_servers.<id>.enabled_tools/ approval modes, and feature flags. features.network_proxywithoutnetwork_access = truedoes nothing; network stays off.network_access = truewithout the proxy means unrestricted outbound traffic.- Destructive MCP or app tools that advertise a destructive annotation always prompt, unless the tool also claims to be read-only. Do not trust third-party annotations blindly.
- Inside Docker, bwrap may lack the namespaces it needs. Either grant the capabilities or
make the container the boundary and run
danger-full-accessinside it, only for trusted repositories: anything in the container, including Codex credentials, is reachable. shell_environment_policy.ignore_default_excludesdefaults totrue, so secret-looking variables are passed to commands. Set it tofalsefor untrusted work.-a neverwithread-onlyis safe for analysis but makes edit tasks fail repeatedly; check the transcript for denials before blaming the model.- WSL1 is no longer supported by the Linux sandbox; use WSL2.
- A workspace-write session can still edit files that run later with your privileges
(git hooks are protected, but
Makefile,package.jsonscripts and CI files are not). Review the diff before running project scripts outside Codex.
Output contract
**Mode:** workspace-write + on-request (auto_review on)
**Extras:** --add-dir ../shared-lib; network on, proxy allowlist: registry.npmjs.org, pypi.org
**Boundary test:** write outside workspace denied; curl example.com blocked; npm install ok
**Saved as:** ~/.codex/deps.config.toml (use: codex --profile deps) What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Codex Sandbox and Approvals"
short_description: "The narrowest boundary that still finishes the job"
default_prompt: "$codex-sandbox-approvals What sandbox and approval settings should I use to let Codex install npm packages?" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.