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

SandboxApprovalBehavior
read-onlyon-requestvery conservative
read-onlyneverautonomous for auditing
workspace-writeon-requestgood local default
workspace-writeneverautonomous but confined agent
danger-full-accesson-requestopen host with human checkpoints
danger-full-accessneverfull 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.

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.

Sources