Unwait

--dangerously-skip-permissions: what it turns off, and what to use instead

· 6 min read claude code permissions security sandbox cli workflow

The flag people reach for when Claude Code will not stop asking. What bypassPermissions actually disables, the four rules that still apply, why it refuses to start under sudo, the plan mode trap that comes with merely enabling it, and the three newer options that solve the real problem without it.

--dangerously-skip-permissions is the flag people find when Claude Code will not stop asking. The name is doing its job, and most advice about it is either "never use this" or a shrug, neither of which helps you at the moment you are typing it.

The useful version of the answer has two halves. First, the flag turns off less than you think in some places and more than you think in others. Second, the problem that sends most people looking for it now has three better solutions that did not exist when this flag became folklore. Here is both, and then how to pick.

What the flag actually does

--dangerously-skip-permissions is an alias for --permission-mode bypassPermissions. It disables permission prompts and safety checks so tool calls execute immediately, including writes to the protected paths that no other mode will auto-approve, such as your git internals and Claude's own config.

Four things still apply, and knowing them matters more than the headline:

The three failures people hit first

It refuses to start as root. On Linux and macOS you get:

--dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons

This is the single most common wall, because the obvious place to use the flag is a container, and the default user in a container is root. The check is skipped automatically inside a recognized sandbox, and the supported fix is the dev container configuration, which runs Claude Code as a non-root user. Adding a non-root user to your own image works the same way. Reaching for sudo to get past a message about sudo is the wrong direction.

You cannot enter the mode mid-session. Shift+Tab will not cycle you into it from a session that started without it. It has to be enabled at launch, by the flag, by --permission-mode bypassPermissions, or by permissions.defaultMode. There is also --allow-dangerously-skip-permissions, which adds the mode to the cycle without activating it, and that one has a catch worth its own section below.

The first interactive run shows a dialog. You accept responsibility once and the acceptance is saved to user settings. Decline and Claude Code exits. Relevant for automation: a background session started with --bg is refused until you have accepted that dialog in an interactive session at least once, which is a confusing failure if you provisioned a machine and went straight to headless.

Three more that show up later. --restricted refuses the mode outright. Claude Code on the web silently ignores defaultMode: "bypassPermissions" from settings files, so a repository's checked-in settings cannot start a cloud session in it. And an administrator can remove the option entirely with permissions.disableBypassPermissionsMode set to "disable" in managed settings.

The trap: enabling it weakens plan mode

This one is genuinely surprising and it costs nothing to trigger.

In any session where bypass permissions are available, not active, Claude Code stops enforcing plan mode's blocks. Claude is still instructed to plan without editing, but a file edit or shell command it attempts while planning runs without prompting. The instruction remains; the enforcement does not.

So --allow-dangerously-skip-permissions, which reads like the cautious option because it only adds the mode to the cycle, quietly turns plan mode from a guarantee into a request for the entire session. If you use plan mode as a real boundary for exploring unfamiliar code, do not launch with the flag "just in case."

What to use instead

Almost everyone typing this flag wants "stop asking me," not "disable every check." Three things solve that better, and the split is the whole point.

Auto mode, for prompt fatigue. A classifier model reviews actions in the background instead of you. It is the built-in starting mode on Pro, Max, and Team, it requires no isolation, and unlike bypass it is still a check. If your complaint is the volume of prompts on ordinary work, this is the answer, and the documentation says so directly: bypass offers no protection against prompt injection or unintended actions, and auto mode is the recommended way to get far fewer prompts.

The Bash sandbox in auto-allow mode, for command approvals specifically. Run /sandbox and pick auto-allow. The OS enforces which paths and domains commands can touch, and sandboxable commands then run without asking, even in Manual mode. It is built in on macOS through Seatbelt, needs two packages on Linux and WSL2, and is not supported on native Windows, where you run inside WSL2 instead. Deny rules still apply, and ask rules naming a specific command such as Bash(git push *) still prompt. This is the closest thing to "stop asking about commands" that does not also remove the boundary.

Two sandbox details worth knowing before you lean on it. "allowUnsandboxedCommands": false gives you Strict sandbox mode, where the dangerouslyDisableSandbox escape hatch is ignored entirely. And if you turn filesystem isolation off while keeping auto-allow, a sandboxed command can write to shell startup files, executables on $PATH, or ~/.claude/settings.json, and widen its own access on the next run. Network limits do not close that door.

dontAsk mode, for CI. It auto-denies anything that would otherwise prompt, so Claude runs only what your allow rules, read-only commands, and PreToolUse hooks permit, and the session never waits for input:

claude -p "run the test suite" --permission-mode dontAsk \
  --allowedTools "Bash(npm test)" "Read"

This is what most people actually want from an unattended run. It fails closed. Bypass fails open, which in CI means a bad turn does damage instead of exiting non-zero.

When the flag is still right

One case, stated narrowly: a fully unattended -p run inside a container, VM, or the sandbox runtime, as a non-root user, where the work is expected to touch things an allowlist cannot enumerate in advance. That is a real scenario. Large migrations and batch refactors across an unpredictable set of files genuinely resist a pre-written allowlist, and there the isolation boundary does the work the permission prompts were doing.

The rule is that the boundary has to exist somewhere. Permissions and isolation are two different layers: modes decide whether Claude asks before an action, isolation decides what the action can reach once it runs. Turning off the first without the second is the actual mistake, not the flag itself. We laid out the threat model this sits inside separately, and the short version is that prompt injection is the reason the boundary matters even when you trust yourself, because you are not the only author of what lands in the context window.

If you take one thing: write your permissions.deny rules first, because they are what survive every mode. Everything else in this post is about choosing which layer does the gating, and deny rules are the layer that does not change when you change your mind. That, plus keeping plan mode a real boundary, covers most of what the flag was being asked to solve.

Unwait does this for you

A macOS menu bar app that watches your Claude Code and Codex sessions, shows a short card while they work, and puts a strip on screen the moment one finishes. Free for two weeks, no card and no sign up.

Try for free
← All posts