There is a Codex flag whose name already tries to warn us that we are not enabling a simple convenience:
codex exec --dangerously-bypass-approvals-and-sandbox "..."
It also has a shorter alias:
codex exec --yolo "..."
OpenAI’s current documentation describes it very directly: it runs commands without approvals and without sandboxing, and recommends using it only inside an externally hardened environment such as an isolated runner or dedicated VM.
The important part is those two words:
approvals
sandbox
They are not the same thing.
Understanding the difference makes it possible to build much more autonomous agents without giving them unrestricted access to the machine.
The right mental model: two independent axes
Codex separates two questions:
1. What is technically allowed?
2. When should the human be asked for permission?
The sandbox answers the first.
The approval policy answers the second.
We can visualize it like this:
Codex
│
▼
wants to execute something
│
▼
┌────────────────────┐
│ Approval policy │
│ should I ask? │
└─────────┬──────────┘
│
▼
┌────────────────────┐
│ Sandbox / profile │
│ can I do it? │
└─────────┬──────────┘
│
▼
operating system
This is the distinction worth remembering most:
Approval controls interaction. Sandbox controls capability.
An agent can never ask and still remain heavily restricted.
It can also have an almost-open filesystem and still stop before certain escalations.
What exactly does --dangerously-bypass-approvals-and-sandbox do?
The official CLI reference says this flag makes Codex run all commands without approvals or sandboxing and should only be used inside an externally hardened environment.
Conceptually, it is equivalent to combining:
sandbox_mode = danger-full-access
approval_policy = never
OpenAI calls that combination Full access.
That means the boundary stops being inside Codex and moves to whatever surrounds the process.
For example:
normal host
└── user frank
└── codex --yolo
├── shell
├── git
├── gh
├── python
├── docker
└── any tool accessible to the user
Codex does not magically gain root if the user does not have it.
But it can reach approximately as far as the account that launched the process can reach.
If that account can do:
cat ~/.ssh/id_ed25519
rm -rf ~/projects
curl https://example.com
gh repo delete ...
docker run ...
kubectl ...
then a Codex process without a sandbox can attempt to use those capabilities too.
The risk is not only a wrong command.
The risk is the complete blast radius of the identity running the process.
The three classic sandbox modes
The current CLI exposes three main modes:
--sandbox read-only
--sandbox workspace-write
--sandbox danger-full-access
read-only
It is designed for inspection.
read repo ✅
analyze code ✅
review ✅
modify repo ❌
An interesting CI pattern is:
codex exec \
--sandbox read-only \
--ask-for-approval never \
"Review this change and return findings"
Here the agent does not interrupt the pipeline with questions, but it also does not receive authority to modify the workspace.
Autonomy does not imply unlimited access.
workspace-write
This is probably the most useful mode for local work and development agents.
Codex can:
read the project
edit inside the workspace
run routine local commands
while preserving the workspace boundary.
The current documentation presents it as the low-friction local mode.
For example:
codex exec \
--sandbox workspace-write \
--ask-for-approval on-request \
"Implement the issue and run the tests"
The agent works normally inside the project and asks for approval when it needs to cross the intended boundary.
danger-full-access
codex --sandbox danger-full-access
removes the sandbox’s local restrictions.
The documentation explicitly notes that the sandbox’s filesystem and network boundaries disappear.
But that still does not require approvals to be disabled.
That is an important distinction.
never does not automatically mean “give it access to everything”
The never approval policy essentially means:
do not interrupt me with approval prompts
It does not mean:
ignore all technical restrictions
For example:
codex exec \
--sandbox read-only \
--ask-for-approval never \
"Analyze this repository"
is a silent and highly restricted agent.
And:
codex exec \
--sandbox workspace-write \
--ask-for-approval never \
"Fix the tests"
can be an excellent configuration for local automation or a dedicated runner when we want zero interaction but still want confinement.
The dangerous combination is:
danger-full-access
+
never
That is exactly YOLO territory.
The matrix worth keeping in your head
| Sandbox | Approval | Behavior |
|---|---|---|
read-only | on-request | very conservative |
read-only | never | autonomous for auditing |
workspace-write | on-request | good local default |
workspace-write | never | autonomous but confined agent |
danger-full-access | on-request | open host with human checkpoints |
danger-full-access | never | full access / YOLO |
The most common mistake is thinking the main axis is:
asks a lot ←→ does not ask
The more important security axis is actually:
what can it do even if it is wrong?
The sandbox also wraps child processes
The sandbox does not protect only Codex’s internal file-editing function.
If Codex runs:
bash
python
pytest
uv
npm
git
gh
curl
those processes are part of the restricted environment.
Conceptually:
Codex
└── bash
└── python
└── subprocess
└── tool
The usefulness of this architecture is that policy is applied to the runtime, not only to a promise made by the model.
That is crucial for both mistakes and prompt injection.
A prompt can try to persuade the model to do something.
The operating system can still answer:
ACCESS DENIED
Enforcement happens at the operating-system level
OpenAI documents that the local sandbox uses different mechanisms depending on the platform.
Currently:
macOS
└── Seatbelt / sandbox-exec
Linux
└── bwrap + seccomp
WSL
└── Linux sandbox
Windows
└── Codex native sandbox
This introduces a very important separation:
"model, do not do X"
≠
"kernel, prevent X"
The first is a probabilistic instruction.
The second is an execution boundary.
For agent security, we need both, but we should not confuse them.
Network is another capability that should be modeled explicitly
In workspace-write, network access for commands is disabled by default according to current Codex documentation.
It can be enabled with:
[sandbox_workspace_write]
network_access = true
But allowing network access and allowing every destination are different decisions.
Codex supports network_proxy, which can apply policies by domain.
For example:
[features.network_proxy]
enabled = true
domains = {
"api.openai.com" = "allow",
"example.com" = "deny"
}
This makes it possible to build a boundary like:
agent
│
├── filesystem → workspace only
│
└── network
└── proxy
├── api.openai.com ✅
├── github.com ✅
└── everything else ❌
That is much better than assuming that “it needs Internet” means opening the entire Internet.
--add-dir: expand access without abandoning the sandbox
OpenAI explicitly recommends preferring --add-dir when the agent needs to work with additional directories instead of jumping straight to danger-full-access.
Example:
codex \
--sandbox workspace-write \
--add-dir ../shared-library
That creates much narrower authority:
main repo write ✅
shared-library write ✅
rest of machine ❌
This is exactly the kind of least-privilege design that makes sense for long-running agents.
Permission Profiles: a finer layer than the three classic modes
Codex also supports permission profiles.
The current documentation includes three built-in profiles:
:read-only
:workspace
:danger-full-access
And it allows custom profiles.
For example:
default_permissions = "project-edit"
[features]
network_proxy = true
[permissions.project-edit]
extends = ":workspace"
[permissions.project-edit.filesystem.":workspace_roots"]
"**/*.env" = "deny"
[permissions.project-edit.network]
enabled = true
[permissions.project-edit.network.domains]
"api.openai.com" = "allow"
That profile expresses a policy much more useful than simply “sandbox on/off”:
workspace write
.env deny
api.openai.com allow
all other destinations not allowed
There is an important subtlety: OpenAI documents that these permission profiles do not compose with the classic sandbox_mode mechanism.
We need to consciously configure one family or the other.
Denying .env is a good example of useful security
Consider this workspace:
repo/
├── src/
├── tests/
├── pyproject.toml
└── .env
The goal should not be to prevent Codex from doing real work.
The goal should be to give it enough authority to:
edit code
create tests
run linters
fix bugs
while preventing it from reading secrets it does not need.
A permission profile can turn that intent into technical policy:
src/** write
tests/** write
.env deny
That greatly reduces the impact of a prompt injection that tries to find credentials.
Rules: a firewall for commands
Another Codex layer is execution rules, or .rules.
Rules can decide among:
allow
prompt
forbidden
And when several match, the documentation defines this precedence:
forbidden > prompt > allow
We could imagine a policy such as:
gh pr view allow
gh pr list allow
gh pr create prompt
gh repo delete forbidden
This layer is especially useful because many sensitive actions are not distinguished only by the executable.
This:
gh pr view
is not the same as:
gh repo delete
even though both begin with gh.
Rules let authority be expressed at the level of specific operations.
Auto-review: automate approvals without deleting the boundary
Codex can also delegate certain approvals to an automated reviewer.
The documented configuration includes:
approval_policy = "on-request"
approvals_reviewer = "auto_review"
That changes the flow from:
Codex
↓
requests escalation
↓
human decides
to:
Codex
↓
requests escalation
↓
reviewer agent
├── approves
└── rejects
The important point is that this does not remove the sandbox.
It automates part of the gate.
This is a much more interesting pattern than jumping directly to YOLO when we want agents that work for hours without continuous supervision.
--full-auto is no longer the recommended direction
The CLI still recognizes:
--full-auto
but the current reference marks it as deprecated and recommends using --sandbox workspace-write.
That reflects a healthy conceptual evolution:
autonomy
≠
unlimited access
An agent can be fully automatic inside a narrow boundary.
Other escape hatches worth knowing
The CLI also documents flags such as:
--dangerously-bypass-hook-trust
which allows enabled hooks to run without requiring the usual persisted trust for that invocation.
And:
--ignore-rules
which avoids loading the user’s or project’s execpolicy rules during that run.
They are not equivalent to --yolo, but they do modify important layers of the trust model.
In CI they should be treated as deliberate security changes, not simple shortcuts to “make it pass.”
The best pattern for CI is usually not YOLO
Suppose we want an agent to perform automatic review.
A reasonable configuration could be:
filesystem: read-only
approvals: never
network: only what is necessary
secrets: minimal
For an agent that fixes code:
filesystem: workspace-write
approvals: never
network: allowlist
secrets: repo-scoped token
For an agent that publishes a PR:
workspace-write
+
explicit rule for gh pr create
+
minimum-permission token
+
branch protection
+
required checks
The architecture should try to preserve several barriers:
model
↓
permission profile / sandbox
↓
rules
↓
network policy
↓
least-privilege credentials
↓
isolated branch
↓
CI
↓
branch protection
That is defense in depth for agents.
When --yolo does make sense
The flag does not exist because it is never useful.
It makes sense when Codex is not the security boundary.
For example:
real host
↓
ephemeral VM / isolated runner
↓
container or unprivileged user
↓
minimal secrets
↓
Codex --yolo
In that design, removing the second sandbox can simplify tools that would otherwise fight duplicated restrictions.
But the right question before enabling the flag is:
If Codex executed the worst plausible command, what could it destroy, read, or exfiltrate from this environment?
If the answer includes:
my SSH keys
all my private repos
cloud credentials
host Docker socket
production kubectl
long-lived tokens
then the environment is probably not ready for YOLO.
The central principle: limit capability, not only confirmations
A system that relies only on human approvals still has a problem.
The human can get tired.
They can approve out of habit.
They may not fully understand what they are authorizing.
They may want the agent to keep working while they sleep.
That is why the mature goal should not be:
make Codex ask about everything
but rather:
make whatever it can execute automatically
already constrained by technical policies
That produces a better architecture:
highly autonomous agent
+
small blast radius
Instead of:
highly autonomous agent
+
identity with full access
The relationship with prompt injection
This permissions model connects directly with another problem we already analyzed at Capital de Tokens: repository poisoning and prompt injection against coding agents.
A repository can contain malicious text.
An issue can contain manipulative instructions.
Tool output can be compromised.
We should not build the defense around the assumption:
"the model will always recognize the attack"
The more robust stance is:
model can be wrong
↓
what can it do if it is wrong?
That is where sandboxing, rules, network policy, and least privilege stop being configuration details.
They become the core security architecture of the agent.
A practical recipe for local agents
If we want Codex to work fairly autonomously in a local repository, I would start with something like:
codex exec \
--sandbox workspace-write \
--ask-for-approval never \
"Implement the task, run tests, and leave the workspace ready"
Then I would expand only what is necessary:
needs another repo → --add-dir
needs Internet → explicit network access
needs only GitHub → domain allowlist
must not read .env → permission profile deny
dangerous commands → .rules forbidden
The right escalation path is:
least privilege
↓
observe what is missing
↓
add a concrete capability
Not:
something was blocked
↓
enable YOLO
The idea worth remembering
Codex’s security system is not a simple switch.
It is a composition of layers:
Model
↓
Approval policy
↓
Rules
↓
Permission profile / sandbox
↓
Network policy
↓
OS enforcement
↓
Credentials / external environment
↓
Git / CI / branch protection
And --dangerously-bypass-approvals-and-sandbox removes two of the most important barriers in that stack at once.
That is why the name is deliberately uncomfortable.
It does not necessarily mean:
“Codex becomes unsafe in every context.”
It means:
“From this point on, security depends much more heavily on the external environment you built.”
That is the difference between using YOLO inside an ephemeral VM with a token scoped to one repository and using it from your main laptop with all your credentials loaded.
The same flag.
A completely different blast radius.
And that is probably the most important lesson for anyone building autonomous agents: autonomy should grow faster than privileges.