How to Run Claude Code in YOLO Mode Safely (2026)
Running Claude Code? See, control, and price every tool call it makes — allow/ask/deny policy, a per-session bill at API rates, and a full audit log, in one command:
curl -sf https://agenticcontrolplane.com/install.sh | bash
Full Claude Code guide → · see your first governed call → · free up to 5 agents
“Yolo mode” is the mode people actually run. The prompts get annoying, the work
is real, and --dangerously-skip-permissions makes the agent stop asking. The
question worth answering isn’t whether people will use it — they already do —
it’s what you should have written down before they did.
Here’s the honest answer, and it’s better news than the flag’s name suggests.
What the flag actually turns off
--dangerously-skip-permissions (equivalently, --permission-mode
bypassPermissions) auto-allows every call through Claude Code’s permission
system. That’s the subsystem that produces “Allow this tool call? (y/n)”. It is
not the only subsystem between the model and your filesystem.
Still enforced with the flag on, per Claude Code’s own control model:
| Still holds | Gone |
|---|---|
deny rules at every settings scope — deny beats allow everywhere, and a managed (org-deployed) deny can’t be overridden even by a CLI flag |
Every interactive permission prompt |
Explicit ask rules, and MCP tools flagged as requiring interaction |
Any control whose mechanism was “a human reads the command and decides” |
PreToolUse hook blocks — hooks fire in every permission mode, and exit 2 / permissionDecision: "deny" is unconditional |
The acceptEdits / auto classifier screen, which bypass replaces rather than stacks with |
The rm -rf circuit breaker, which catches rm -rf / and rm -rf ~ even inside $(…) |
— |
The refusal to run bypass mode as root |
— |
So bypass mode is not “no controls.” It is exactly your denies and your hooks, and nothing else. That’s a precise statement, and it’s also the whole design brief: the flag doesn’t make a session dangerous, it makes a session exactly as safe as the rules you wrote in advance. The December home-directory wipe ran under this flag; the circuit breaker that would catch it today was widened afterwards.
The corrected long-form version of this — including our own published error
about it — is Is --dangerously-skip-permissions
safe?
The hardening checklist, in order
Order matters here: each step covers a class the one above it doesn’t, and the cheap ones come first.
1. Write the deny rules before you need them
Deny is the only rule tier that survives the flag, so it’s where anything
non-negotiable belongs. In ~/.claude/settings.json (user scope) or
.claude/settings.json (project):
{
"permissions": {
"deny": [
"Bash(curl:*)",
"Bash(rm:*)",
"Read(./.env)",
"Read(~/.aws/credentials)",
"Read(~/.ssh/id_*)",
"WebFetch"
]
}
}
Two things the docs are unusually candid about, and both change how you write these:
- Deny the command family, not the arguments. Anthropic’s own docs call
argument-constrained Bash patterns fragile —
Bash(curl http://github.com/ *)misses the-X GETspelling, thehttps://spelling, and env-var indirection.Bash(curl:*)is a rule;Bash(curl http://… *)is a wish. Write()rules are silently never consulted.Edit()rules govern Write and NotebookEdit. A warning was added in v2.1.210 because enough people had rules that did nothing.
And know the ceiling on this step: a deny list is a string match evaluated inside the client, so a compound command, an interpreter, or a three-line script the agent writes and runs all route around it. That’s not a bug you can patch out — it’s the documented bypass class, and it’s why step 2 exists.
2. Put anything that must hold in a PreToolUse hook
Hooks are the strongest mechanism inside the harness. PreToolUse fires on
every tool call in every permission mode — the hook receives permission_mode:
"bypassPermissions" in its input, which it couldn’t if it never ran — and a
hook that exits 2 or returns permissionDecision: "deny" blocks the call
unconditionally. A hook allow, correctly, cannot loosen a deny or ask rule.
The caveat: Claude Code hooks are fail-open on timeout. The docs say it plainly. A hook that stalls doesn’t block, so if your enforcement lives in a hook, that hook’s availability is now part of your security posture, and a crashed control layer silently stops controlling. Design for that before you depend on it.
3. Turn the sandbox on
/sandbox — Seatbelt on macOS, bubblewrap on Linux. It’s off by default,
which is the single most common gap in a yolo setup. Once on: writes confined to
the workspace and $TMPDIR, network through a proxy with no domains
pre-allowed, and a set of paths write-protected with no exemption possible
(settings files, hook and skill directories, .mcp.json, credentials, shell rc
files, .git/hooks).
The two limits to hold in your head: reads are unconfined by default — the
docs explicitly warn that ~/.ssh and ~/.aws/credentials are readable unless
you add deny-read rules, which is why they’re in the step-1 snippet above — and
the model can request dangerouslyDisableSandbox through the normal permission
flow, which in bypass mode is a flow that no longer asks anyone. A sandbox
bounds the blast radius; it decides nothing. Sandboxes and control
planes is the longer version of that trade.
4. Don’t run it as root, and don’t inherit a hostile repo’s settings
Bypass mode refuses to run as root — take the hint rather than working around
it. The other sharp edge is headless: -p counts as having accepted workspace
trust, so a scripted invocation in a repo you didn’t write inherits that repo’s
project settings. --setting-sources user strips them. Worth wiring into any
cron or CI invocation, because that’s exactly where nobody is watching.
5. Flip the org-level switch if the answer is “never”
If a class of machine should never have this mode available at all, managed
(org-deployed) settings carry two kill switches:
permissions.disableBypassPermissionsMode removes the mode, and
allowManagedHooksOnly pins your hooks so a user or project setting can’t
override them. Managed denies can’t be overridden by a CLI flag either.
This is the strongest purely-native answer, and its limit is honest: managed settings are files on the endpoint. They assume the endpoint is managed.
6. Add a layer the flag can’t reach
Everything above lives on the machine running the agent, which means everything
above can be edited by whoever owns that machine. disableAllHooks is a
documented one-line switch that stops all hooks; deleting the hook entry does the
same. For a developer on their own laptop that’s fine — you’re not defending
against yourself. For anything where the endpoint isn’t the trust boundary,
the control that holds has to sit somewhere the endpoint can’t edit.
That’s the layer we build. Two paths, and they’re genuinely different:
# Connected: policy and the record live off the machine
curl -sf https://agenticcontrolplane.com/install.sh | bash
# Fully on-device: no account, nothing leaves your box
curl -sf https://agenticcontrolplane.com/install.sh | bash -s -- --local
What each gets you in a bypass session:
- A safety floor. Recursive force-delete of a root or home path,
mkfs,ddto a block device, fork bombs, force-push tomain/master— denied regardless of policy, token-matched so flag order and spelling don’t help (rm -r -f ~,rm -rf ~/), and recursed one level intobash -c "…"andeval. In the connected path this floor is evaluated server-side, where no tenant setting, no standing approval, and no client flag can reach it. - allow / ask / deny policy applied to every call, in one dialect, across every harness you run — not re-derived per settings file.
- An audit line either way. One row per call — tool, decision, reason,
timestamp — written whether the call was allowed, denied, or waved through by
a human.
tail -f ~/.acp/audit.jsonlin local mode; a queryable ledger in the connected one. A record of what a bypass session did is the thing every native model is missing, across every harness we’ve measured.
What the installer writes to your machine, file by file, if you’d rather read before you pipe.
7. Re-run the installer if you installed before August 27, 2026
One honest correction, because it affects the local path specifically. The
on-device decision engine (~/.acp/decide.mjs) had a wrapper-and-compound
bypass: timeout 5 rm -rf ~ classified as a timeout command rather than an
rm, because the wrapper parser skipped flags but not the positional operands a
wrapper like timeout consumes before the real command. It’s fixed — the engine
now carries an explicit wrapper table with per-wrapper flag and operand arity,
and scans each segment of a compound command separately.
The fix is live in the canonical installer. Verify it yourself in one line:
curl -s https://agenticcontrolplane.com/install.sh | grep 'const WRAPPERS'
You should see const WRAPPERS = new Map([. If you installed before August 27,
2026, your ~/.acp/decide.mjs predates the fix and re-running the installer
replaces it:
curl -sf https://agenticcontrolplane.com/install.sh | bash -s -- --local
Your ~/.acp/policy.json is left alone — the installer only writes it when it
doesn’t already exist. The connected path was never affected; its classifier
runs server-side.
What still isn’t covered
The list this site always carries, because a hardening checklist that ends on a win is a sales page.
A deny list can’t constrain a Turing-complete tool. Step 1’s rules are a
first line, not a boundary. python3 -c "import shutil; shutil.rmtree(...)" is
not a trick — it’s what a coding agent does all day. Every layer above the
sandbox reasons about command text; only the kernel reasons about effects.
The hook is fail-open, by design and by ours. Claude Code proceeds if a hook
times out, and ACP’s dispatcher also fails open by
default — your tool runs, loudly flagged as
unchecked, rather than your session bricking when a network hop is slow. That’s
the right default for a developer laptop and the wrong one for a machine
touching production, which is why the ~/.acp/failmode opt-in exists. Either
way, it’s a choice you should make deliberately rather than discover.
Local mode is removable by whoever owns the machine. --local puts the
engine, the policy, and the log on your disk. That’s the point — no account,
nothing leaves the box — and it also means it enforces against accidents, not
against the person holding the keyboard. Only the off-machine path changes that
property.
Nothing here covers what the agent reads. Bypass mode plus unconfined sandbox reads is a credential-exposure shape, not a destructive-command shape, and no permission prompt was ever going to catch it. Deny-read rules and the sandbox are the controls; the flag doesn’t touch either, which is the good news and the reason step 1 includes them.
Yolo is a per-harness word. These seven steps are Claude Code’s. Codex’s
--yolo drops the sandbox and the approvals; Antigravity’s
--dangerously-skip-permissions is total — verified, hooks are not invoked at
all under it; Cursor’s Run Everything mode has no sandbox, no classifier, no
prompts. If you run more than one agent, the equivalent table for all of them is
Bypass Permissions Safely, and the mechanism
view — which of the eight control patterns survive an escape hatch at all — is
harness control patterns.
The short version
Yolo mode isn’t the risk. An unprepared yolo mode is. The flag removes the one control that was never going to scale anyway — a human reading every command — and leaves standing exactly the two that do: rules written in advance, and a check that runs outside the prompt. Write those, turn the sandbox on, put one layer somewhere the flag can’t reach, and the mode is what it should have been called: the mode where your policy does the work instead of your attention.
Every Claude Code behavior above is from Anthropic’s docs and our own control-model page, current to v2.1.233; the ACP behavior is from the installer, which is plain text you can read top to bottom. Harnesses move — we correct these pages when they do, in public.
Can you run Claude Code in yolo mode safely?
Safely enough for ordinary work, if you do three things first: write deny rules for the command families you never want run (deny beats allow at every scope and survives bypassPermissions), put anything that must hold in a PreToolUse hook (hooks fire in every permission mode and a hook deny is unconditional), and turn on the sandbox with /sandbox. Without those, bypass mode is genuinely what its name says — the prompts were the only thing standing between the agent and the command, and you removed them.
What does --dangerously-skip-permissions actually turn off?
Only the interactive permission prompts. It sets the session to bypassPermissions, which auto-allows every call through Claude Code’s permission system. Deny rules at every scope, explicit ask rules, PreToolUse hook blocks, MCP tools flagged as requiring interaction, and an rm -rf circuit breaker that fires even inside command substitution all still apply, and the mode refuses to run as root.
How do I disable yolo mode for my whole team?
permissions.disableBypassPermissionsMode in managed (org-deployed) settings removes the mode entirely, and allowManagedHooksOnly pins your hooks so a user or project setting cannot override them. Both are files on the endpoint, so both assume the endpoint is managed — if it is not, the control that holds has to live somewhere the endpoint cannot edit.
Do hooks still run with --dangerously-skip-permissions?
Yes. PreToolUse fires on every tool call in every permission mode, and exit code 2 or permissionDecision deny blocks the call unconditionally. The caveat worth knowing is the other direction: Claude Code hooks are fail-open on timeout, so a hook that stalls does not block. If your enforcement lives in a hook, that hook’s availability is part of your security posture.