OpenAI's Codex CLI and Google's Gemini CLI both run an agent in your terminal that can read files, edit code and execute commands. Both ship with real safety controls — sandboxes, approval modes, tool restrictions — but they name and layer them differently, which makes it easy to think you've locked one down the way you locked down the other. This guide puts Codex CLI and Gemini CLI safety settings side by side, with configurations for interactive use and CI.
Settings change between releases. Everything here is taken from each project's current documentation (Codex: agent approvals & security, Gemini CLI configuration); verify against your installed version.
The two layers both tools share
Both tools separate two questions:
- What can the agent technically do? — the sandbox: which paths are writable, whether the network is reachable.
- When must it ask first? — the approval policy: which actions pause for a human.
Getting safety right means setting both deliberately. A strict approval policy on top of an unrestricted sandbox depends entirely on you reading every prompt; a tight sandbox with no approvals depends entirely on the sandbox being correct.
Codex CLI
Sandbox modes
sandbox_mode / --sandbox
|
Effect |
|---|---|
read-only |
Can read files and run commands inside a read-only sandbox |
workspace-write |
Can edit files and run commands in the working directory; network off by default |
danger-full-access |
No sandbox |
Locally, the sandbox is OS-enforced: Seatbelt on macOS, bwrap plus seccomp on Linux. In workspace-write, some paths inside writable roots stay read-only, including .git, .codex and .agents — useful, because it stops the agent from rewriting its own config or your git internals.
Approval policies
approval_policy / --ask-for-approval
|
Effect |
|---|---|
on-request |
Asks before leaving the sandbox (e.g. writing outside the workspace, using the network) |
never |
Never asks; works within whatever sandbox you chose |
| granular | Keep some prompt categories interactive, auto-reject others |
Note: the old approval_policy = "untrusted" value has been retired and can stop Codex from starting. The documented replacement for stricter command approval is a per-project trust level in ~/.codex/config.toml:
[projects."/path/to/project"]
trust_level = "untrusted"
Network
Network is off by default in workspace-write. If you turn it on, turn on the network proxy too, or outbound traffic is unrestricted:
[sandbox_workspace_write]
network_access = true
[features.network_proxy]
enabled = true
domains = { "registry.npmjs.org" = "allow", "api.github.com" = "allow" }
Domain rules are allowlist-first and deny always wins. The proxy filters commands inside the sandbox; it does not filter web search, MCP server connections or app/connector tool calls, which have their own controls. Web search defaults to a cached index rather than live pages, which reduces exposure to prompt injection from arbitrary sites.
The flag to avoid
--dangerously-bypass-approvals-and-sandbox (alias --yolo) removes both layers. If you need it, run it only inside a container or devcontainer that is itself the security boundary.
Recommended Codex configs
Interactive development:
sandbox_mode = "workspace-write"
approval_policy = "on-request"
Read-only review in CI:
codex exec --sandbox read-only --ask-for-approval never "Review this diff for bugs"
Gemini CLI
Approval modes
--approval-mode |
Effect |
|---|---|
default |
Prompts for approval on tool calls |
auto_edit |
Auto-approves edit tools, prompts for others |
plan |
Read-only mode |
yolo |
Auto-approves all tool calls |
general.defaultApprovalMode in settings.json accepts default, auto_edit and plan. YOLO can only be enabled from the command line, and the standalone --yolo flag is deprecated in favour of --approval-mode=yolo. To make YOLO impossible on a machine regardless of flags:
{
"security": { "disableYoloMode": true }
}
Sandboxing
Enable the sandbox with -s / --sandbox, the GEMINI_SANDBOX environment variable, or tools.sandbox in settings.json (for example "docker" or "podman"). The documentation states that the sandbox is enabled by default when running in YOLO mode. There is also a newer security.toolSandboxing option that isolates individual tools instead of the whole process.
{
"tools": { "sandbox": "docker" }
}
Tool allow and exclude lists
-
tools.excluderemoves tools from discovery entirely — the model never sees them. -
tools.allowedlists tools that bypass the confirmation dialog, for example"run_shell_command(git)"or"run_shell_command(npm test)".
Be careful with tools.allowed. An entry like run_shell_command(git) pre-approves far more than git status; it includes git push --force. Allowlist the narrowest commands you can, and prefer excluding the shell tool entirely for read-only workflows. Earlier Gemini CLI docs warned that command-specific restrictions for the shell tool are based on simple string matching and can be bypassed — a good rule of thumb for any agent's command patterns.
Folder trust
security.folderTrust.enabled defaults to true, which gates whether a project's own configuration and tools are loaded. Leave it on; a cloned repository should not be able to configure your agent.
Recommended Gemini configs
Interactive development:
{
"general": { "defaultApprovalMode": "default" },
"tools": { "sandbox": "docker" },
"security": { "disableYoloMode": true, "folderTrust": { "enabled": true } }
}
Read-only analysis:
gemini --approval-mode plan
Side by side
| Concern | Codex CLI | Gemini CLI |
|---|---|---|
| Read-only mode | --sandbox read-only |
--approval-mode plan |
| Default write scope | Workspace (workspace-write) |
Depends on sandbox config |
| Network default | Off in workspace-write
|
Depends on sandbox config |
| Auto-approve everything |
--yolo (also removes sandbox) |
--approval-mode=yolo (sandbox on by default) |
| Restrict approval modes centrally | Managed allowed_approval_policies
|
security.disableYoloMode |
| Pre-approve commands | Execution-policy rules | tools.allowed |
| Turn off web search | web_search = "disabled" |
tools.exclude for the search tool |
| Project config trust | Project trust_level
|
security.folderTrust.enabled |
What neither setting gives you
Both tools' controls are per-tool and per-session. Neither, on its own, gives you one testable policy shared across every agent your team runs, a session-aware rule like "no external egress after a secret was read", or a named-approver hold for production actions with a decision log you can query later.
Where Cirvix fits
Cirvix AgentControl is an open-source policy layer that can sit alongside either CLI. Two pieces apply today:
-
Inventory:
cirvix scanrecognises Codex CLI and Gemini CLI configurations (alongside Claude Code, Cursor and others) and flags MCP servers with broad filesystem scope, inline secrets, or duplicate definitions. It is a local heuristic scan of config files, not proof of what a running agent does. -
MCP gateway: both CLIs can use MCP servers. Point them at
cirvix gatewayas the only MCP entry, and every routed MCP tool call is evaluated against one policy file — permit, hold for a named approver, or deny by default — before it reaches the real server.
npx @cirvix_ai/agent-control scan
npx --yes @cirvix_ai/agent-control check --action fs.read --resource .env.production
The boundary: the gateway governs MCP calls routed through it. Each CLI's built-in shell and file tools are governed by the settings in this article, so configure those first.
GitHub: https://github.com/CIRVIX/agent-control
Website: https://cirvix.com
Top comments (0)