Claude Code asks permission before every file edit, every shell command, every network request. For a 10-file refactor, that means 30+ approval prompts. Each one breaks flow state. The --dangerously-skip-permissions flag removes all of them.
The name sounds alarming because Anthropic wanted it to. But most developers using Claude Code daily end up reaching for it, or for the granular permission system that gives you 90% of the speed without the risk.
This guide covers what the flag does, the 5 Claude Code permission modes, how to configure settings.json allowlists so you never need the nuclear option, and how to set up Docker and CI/CD for safe autonomous mode.
What --dangerously-skip-permissions Actually Does
When you launch Claude Code with --dangerously-skip-permissions, you activate what Anthropic calls Bypass Permissions Mode. Every action Claude proposes proceeds immediately without confirmation:
- File edits and writes
- Shell command execution
- MCP tool calls
- Web fetch requests
- Subagent spawning
Basic usage
# One-shot task with full bypass
claude --dangerously-skip-permissions -p "Refactor the auth module to use JWT tokens"
# Named session with bypass
claude --dangerously-skip-permissions --resume refactor-sprint "Continue refactoring"
# Combine with output format for scripting
claude --dangerously-skip-permissions -p "Fix all lint errors" --output-format jsonThe -p flag passes a prompt directly and runs in headless mode. Combined with --dangerously-skip-permissions, Claude executes the task from start to finish without stopping. No human in the loop.
The flag name is intentional
Anthropic chose a deliberately scary name to force a conscious decision. You cannot accidentally enable it. You have to type out the full flag every time. There is no short alias, no -y shortcut.
The 5 Claude Code Permission Modes
--dangerously-skip-permissions is one of 5 permission modes. Most developers never need it because the other 4 cover the common cases. Press Shift+Tab to cycle through the first three interactively.
| Mode | File Edits | Shell Commands | MCP Tools | Best For |
|---|---|---|---|---|
| Default | Prompt once per type | Prompt each | Prompt each | New users, unfamiliar codebases |
| Accept Edits | Auto-approve | Prompt each | Prompt each | Daily development, code-heavy tasks |
| Plan Mode | Blocked | Blocked | Blocked | Code review, architecture analysis |
| Don't Ask | Denied unless pre-approved | Denied unless pre-approved | Denied unless pre-approved | Locked-down environments |
| Bypass (YOLO) | Auto-approve | Auto-approve | Auto-approve | CI/CD, Docker, trusted sessions |
Default Mode
Prompts on first use of each tool type. Approve file editing once and subsequent edits proceed automatically for that session. Shell commands still prompt individually. This is what you get out of the box.
Accept Edits Mode
Auto-approves all file modifications but still prompts for shell commands. The sweet spot for most developers. You get fast iteration on code changes with human oversight on commands that could have side effects. Activate with Shift+Tab.
Plan Mode
Claude can read and analyze but cannot modify files or execute commands. Use this when you want Claude to propose changes without executing them, or to review a codebase before committing to an approach.
Don't Ask Mode
Auto-denies all tool usage unless the tool is explicitly pre-approved via /permissions or your permissions.allow rules. Claude will not prompt you for confirmation. If a tool is not in the allowlist, it is silently denied. This mode is useful for locked-down environments where you want zero unexpected actions.
Bypass Permissions Mode
Equivalent to --dangerously-skip-permissions. All tools execute without prompting. Set it interactively with Shift+Tab or in your config with "defaultMode": "bypassPermissions". Only use this in isolated environments.
Setting the default mode
Add "defaultMode": "acceptEdits" to your settings.json to start every session in Accept Edits mode. You can still switch modes with Shift+Tab during the session.
settings.json: Granular Permission Control
Before reaching for --dangerously-skip-permissions, configure the permission system that gives you fine-grained control. The .claude/settings.json file in your project root lets you allowlist specific tools while blocking dangerous ones.
.claude/settings.json — Recommended starter configuration
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(bun run *)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(git add *)",
"Read",
"Edit(/src/**)",
"Edit(/tests/**)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(sudo *)",
"Bash(curl *)",
"Bash(wget *)",
"Read(./.env*)",
"Read(./secrets/**)",
"Edit(./.env*)"
],
"ask": [
"Bash(git push *)",
"Bash(git commit *)",
"Bash(npm publish *)",
"Edit(/package.json)"
]
}
}Three categories of rules:
- allow auto-approves the tool. No prompt, no delay.
- deny blocks the tool entirely. Claude cannot use it even if asked.
- ask forces a confirmation prompt, even in Accept Edits mode.
Rules evaluate in order: deny > ask > allow. The first matching rule wins. A deny rule always takes precedence, which means you can use a broad allow rule and carve out exceptions with deny.
Permission Rule Syntax
Rules follow the format Tool or Tool(specifier). The specifier supports glob patterns with *.
Bash Rules
Wildcards can appear at any position in the command:
Bash permission examples
"Bash(npm run build)" // Exact match: only "npm run build"
"Bash(npm run *)" // Prefix match: "npm run test", "npm run lint", etc.
"Bash(* --version)" // Suffix match: any command ending with --version
"Bash(git * main)" // Middle match: "git checkout main", "git merge main"
"Bash(*)" // Matches all Bash commands (same as just "Bash")Word boundary matters
Bash(ls *) (space before *) matches ls -la but NOT lsof. The space enforces a word boundary. Bash(ls*) (no space) matches both. Claude Code is also aware of shell operators: Bash(safe-cmd *) will not match safe-cmd && dangerous-cmd.
Read and Edit Rules
Follow the gitignore specification with four path prefix types:
| Pattern | Meaning | Example |
|---|---|---|
| //path | Absolute path from filesystem root | Read(//Users/alice/secrets/**) |
| ~/path | Relative to home directory | Read(~/Documents/*.pdf) |
| /path | Relative to project root | Edit(/src/**/*.ts) |
| path | Relative to current directory | Read(*.env) |
Note: * matches files in a single directory. ** matches recursively across directories. To allow all file access, use the tool name without parentheses: Read, Edit, or Write.
Other Tool Rules
WebFetch, MCP, and Agent rules
"WebFetch(domain:example.com)" // Restrict web fetches by domain
"mcp__puppeteer" // All tools from the puppeteer MCP server
"mcp__puppeteer__puppeteer_navigate" // Specific MCP tool
"Agent(Explore)" // The Explore subagentPer-Project and Per-User Permission Configuration
Settings follow a hierarchy. More specific settings override less specific ones:
- 1Managed settings (IT-deployed, cannot be overridden by anyone)
- 2CLI arguments (
--allowedTools,--disallowedTools) - 3Local project settings (
.claude/settings.local.json, gitignored) - 4Shared project settings (
.claude/settings.json, checked into git) - 5User settings (
~/.claude/settings.json, applies to all projects)
Array settings (like permission rules) merge across scopes rather than replace. If a permission is allowed in user settings but denied in project settings, the project deny wins. If a tool is denied at any level, no other level can allow it.
Shared project settings — .claude/settings.json (commit this)
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git diff *)",
"Read",
"Edit(/src/**)"
],
"deny": [
"Bash(rm -rf *)",
"Read(./.env*)"
]
}
}Local overrides — .claude/settings.local.json (gitignored, your preferences)
{
"permissions": {
"allow": [
"Bash(docker compose *)",
"Edit(/infrastructure/**)"
],
"defaultMode": "acceptEdits"
}
}Use the /permissions command inside Claude Code to view all active rules and which settings file they come from. Use /config to edit settings interactively.
Common Permission Prompts and How to Auto-Allow Them
These are the prompts developers hit most often. Here is how to auto-approve each one without reaching for --dangerously-skip-permissions:
| Prompt You See | Auto-Allow Rule | Notes |
|---|---|---|
| Allow file edits? | Press Shift+Tab for Accept Edits mode | Session-level, resets on restart |
| Run npm run test? | "Bash(npm run test *)" | Glob matches test:unit, test:e2e, etc. |
| Run git commands? | "Bash(git *)" | Broad. Consider allowing specific git subcommands. |
| Read file outside project? | "Read(//path/to/dir/**)" | Use // prefix for absolute paths |
| Run curl/wget? | Add to deny list instead | Network requests are risky. Use WebFetch rules. |
| Use MCP tool? | "mcp__servername" | Allows all tools from that server |
| Run any bash command? | "Bash" | Nuclear option. Same as bypass for bash. |
You can also add rules interactively. When Claude prompts you for permission, selecting "Always allow" adds the rule to your settings file. Or use the /permissions command to add rules manually during a session.
CLI flags for session-level overrides
# Allow specific tools for this session only
claude --allowedTools "Bash(npm run *)" "Bash(git *)" "Read" "Edit"
# Deny specific tools for this session
claude --disallowedTools "Bash(curl *)" "Bash(wget *)"
# Combine both
claude --allowedTools "Read" "Edit" --disallowedTools "Bash(rm *)" "Bash(sudo *)"When --dangerously-skip-permissions Makes Sense
The flag is not as dangerous as the name implies, if you have the right safety nets in place. Four scenarios where it is the right choice:
CI/CD Pipelines
Automated systems cannot click approve. If Claude Code runs in GitHub Actions, GitLab CI, or any pipeline, you need non-interactive execution. The pipeline itself is your permission layer.
Docker / Devcontainers
If Claude runs in an isolated container with a default-deny firewall and no access to production credentials, the container is your sandbox. The permission system becomes redundant.
Batch Operations
Processing hundreds of files with a known-safe transformation (add headers, fix formatting, update imports) does not require human confirmation at each step. Git is your undo button.
Trusted Local Sessions
Clear implementation plan, version control as a safety net, full understanding of what Claude will change. Some developers run bypass mode daily and rely on git for rollback.
The common thread: you have already made the security decision elsewhere. The flag is not granting trust. It is acknowledging trust you have already established through isolation, version control, or both.
When NOT to Use --dangerously-skip-permissions
Real risk scenarios
- Untrusted repositories. A malicious
.claude/settings.jsonor CLAUDE.md in a cloned repo could instruct Claude to exfiltrate credentials. With bypass mode, those instructions execute without prompts. - Machines with production access. If your laptop has SSH keys to production servers, cloud credentials in
~/.aws, or database connection strings, one wrong command could reach them. - Shared development machines. Other users' work could be affected by Claude's file operations.
- Long, multi-hour sessions. In extended sessions, models can lose track of context and make assumptions. Without permission prompts as checkpoints, those assumptions execute immediately.
A study from eesel AI found that 32% of developers using --dangerously-skip-permissions encountered at least one unintended file modification. 9% reported data loss. The solution is not to avoid the flag entirely, but to pair it with proper isolation.
Docker Setup for Safe Autonomous Mode
The recommended way to use --dangerously-skip-permissions safely is inside a container. Anthropic provides a reference devcontainer setup with built-in firewall rules.
Dockerfile — Minimal Claude Code container
FROM node:20-slim
# Install Claude Code globally
RUN npm install -g @anthropic-ai/claude-code
# Install essential dev tools
RUN apt-get update && apt-get install -y \
git \
iptables \
&& rm -rf /var/lib/apt/lists/*
# Copy firewall initialization script
COPY init-firewall.sh /usr/local/bin/init-firewall.sh
RUN chmod +x /usr/local/bin/init-firewall.sh
# Create non-root user
RUN useradd -m -s /bin/bash developer
USER developer
WORKDIR /home/developer/project
ENTRYPOINT ["/usr/local/bin/init-firewall.sh"]init-firewall.sh — Restrict outbound network access
#!/bin/bash
# Allow DNS
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
# Allow connections to Anthropic API
iptables -A OUTPUT -d api.anthropic.com -j ACCEPT
# Allow npm registry for package installs
iptables -A OUTPUT -d registry.npmjs.org -j ACCEPT
# Allow GitHub
iptables -A OUTPUT -d github.com -j ACCEPT
# Block everything else
iptables -A OUTPUT -j DROP
# Run Claude Code
exec claude --dangerously-skip-permissions "$@"Running the container
# Build
docker build -t claude-sandbox .
# Run with your code mounted read-write
docker run -it \
-e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
-v $(pwd):/home/developer/project \
claude-sandbox -p "Fix all TypeScript errors"
# Maximum isolation: read-only source, no network
docker run -it \
-e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
-v $(pwd):/home/developer/project:ro \
-v /tmp/claude-output:/home/developer/output \
--network=none \
claude-sandbox -p "Analyze this codebase for security issues"The official devcontainer from github.com/anthropics/claude-code/.devcontainer includes a more complete firewall with precise domain whitelisting, VS Code integration, and session persistence. Use it as a starting point.
Devcontainer limitation
Even with container isolation, --dangerously-skip-permissions does not prevent a malicious project from exfiltrating anything accessible inside the devcontainer, including Claude Code credentials. Only use devcontainers with trusted repositories.
GitHub Actions / CI/CD Setup
Anthropic provides an official GitHub Action for integrating Claude Code into your CI/CD workflow. Two approaches: the action (for PR-based workflows) and raw headless mode (for arbitrary automation).
Official GitHub Action
.github/workflows/claude.yml — Respond to @claude mentions
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
permissions:
contents: write
pull-requests: write
issues: write
jobs:
claude:
if: contains(github.event.comment.body, '@claude')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_args: "--max-turns 10"Headless Mode in CI
.github/workflows/claude-lint-fix.yml — Auto-fix on push
name: Claude Lint Fix
on:
push:
branches: [main]
jobs:
fix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm install -g @anthropic-ai/claude-code
- name: Fix lint errors
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude --dangerously-skip-permissions \
-p "Fix all ESLint errors in src/" \
--max-turns 5 \
--allowedTools "Read" "Edit" "Bash(npm run lint)"
- name: Commit fixes
run: |
git config user.name "Claude Code"
git config user.email "claude@example.com"
git add -A
git diff --staged --quiet || git commit -m "fix: auto-fix lint errors"
git pushKey flags for CI:
--max-turnscaps execution to prevent runaway costs--allowedToolsrestricts which tools Claude can use in the pipeline--output-format jsonorstream-jsonfor programmatic output parsing-pruns in headless mode (no interactive interface)
Claude Code Headless Mode
Headless mode runs Claude Code without an interactive interface. It is the foundation for all CI/CD and scripting use cases.
Headless mode examples
# Simple prompt, text output to stdout
claude -p "Generate a .gitignore for Node.js"
# Pipe stdin as context
cat src/utils.ts | claude -p "Find potential bugs in this file"
# JSON output with metadata
claude -p "List all TODO comments" --output-format json
# Streaming JSON Lines (NDJSON) for real-time processing
claude -p "Refactor this module" --output-format stream-json
# Multi-turn: maintain context across calls
claude -p "Analyze the codebase" --session-id my-session --output-format json
claude -p "Now fix the issues you found" --resume my-sessionThree output formats: text (default, raw response on stdout), json (structured object with metadata), and stream-json (tokens as JSON Lines for real-time processing).
Managed Settings for Teams and Organizations
Organizations that need centralized control can deploy managed settings that no user or project can override. This includes the ability to disable --dangerously-skip-permissions entirely.
Managed settings — deployed by IT via MDM
// macOS: /Library/Application Support/ClaudeCode/managed-settings.json
// Linux: /etc/claude-code/managed-settings.json
{
"permissions": {
"deny": [
"Bash(rm -rf *)",
"Bash(sudo *)",
"Read(//etc/**)"
]
},
"disableBypassPermissionsMode": "disable",
"allowManagedPermissionRulesOnly": true
}Key managed-only settings:
disableBypassPermissionsMode: set to"disable"to block--dangerously-skip-permissionsand bypass mode entirelyallowManagedPermissionRulesOnly: prevents user and project settings from defining their own permission rulesallowManagedHooksOnly: blocks user/project hooks, only managed hooks runallowManagedMcpServersOnly: restricts MCP servers to the managed allowlist
Managed settings cannot be overridden by CLI arguments, project settings, or user settings. They are the final word.
Frequently Asked Questions
How do I enable auto approve in Claude Code without --dangerously-skip-permissions?
Use settings.json with granular allow rules. Auto-approve specific tools you trust (like your test runner, linter, and git commands) while keeping everything else gated. Combine with Accept Edits mode (Shift+Tab) to auto-approve file changes.
What is Claude Code safe YOLO mode?
"Safe YOLO" refers to running --dangerously-skip-permissions inside a sandboxed environment: a Docker container with firewall rules, restricted network access, and git as a rollback mechanism. The container provides the safety. The flag provides the speed.
Can I use --dangerously-skip-permissions in VS Code?
The flag is a CLI argument, so it applies when launching Claude Code from the terminal. In VS Code, use the devcontainer setup to get equivalent behavior, or configure "defaultMode": "bypassPermissions" in your settings. Note that the Claude Code VS Code extension may use its own permission flow.
How do hooks interact with --dangerously-skip-permissions?
Hooks still fire even in bypass mode. A PreToolUse hook can block a tool call regardless of the permission mode. This means you can run bypass mode with hooks as your guardrails: allow everything by default, but block specific dangerous patterns through hooks. This is the most flexible approach for power users.
Does --dangerously-skip-permissions affect MCP tools?
Yes. MCP tool calls are also auto-approved in bypass mode. If you run MCP servers that interact with external services (databases, APIs, deployment tools), be aware that Claude can invoke them without confirmation.
How do I undo what Claude did in bypass mode?
git checkout . reverts all file changes. git stash saves them for review first. For shell commands with side effects (database writes, API calls, file deletions outside the repo), there is no automatic undo. This is why isolation matters.
What is the difference between --allowedTools and settings.json allow rules?
--allowedTools is a CLI flag that sets permissions for a single session. settings.json rules are persistent and version-controlled. Both use the same Tool(specifier) syntax. Use --allowedTools for one-off overrides, settings.json for your standard workflow.
Can Claude Code bypass permissions read my .env files?
Yes, unless you explicitly deny it. Add "Read(./.env*)" and "Read(./secrets/**)" to your deny list. Deny rules take precedence even in bypass mode when configured through managed settings. However, note that Claude could still access env vars through shell commands like cat .env unless Bash(cat .env*) is also denied.
Is there a short flag like -y for --dangerously-skip-permissions?
No. The long name is intentional. Anthropic does not provide a short alias because they want the flag to require a conscious decision every time you use it.
How do I restrict which models can use bypass mode?
Managed settings can restrict available models with availableModels and disable bypass mode with disableBypassPermissionsMode. These settings are deployed via MDM and cannot be overridden by individual users.
What is the recommended permission setup for a team?
Commit a .claude/settings.json to your repo with sane defaults: allowlist your standard toolchain (linters, formatters, test runners), denylist anything that touches production infrastructure. Let individual developers add personal overrides in .claude/settings.local.json (gitignored). Disable bypass mode in managed settings unless your team uses containers.
How do sandboxing and permissions work together?
They are complementary layers. Permissions control which tools Claude can use. Sandboxing provides OS-level enforcement that restricts what Bash commands can access, even if a prompt injection bypasses Claude's decision-making. Use both for defense in depth: permissions as the first gate, sandbox as the backstop.
Build faster with Morph Fast Apply
Morph merges AI-generated code into your files at 10,500+ tokens per second. Works with Claude Code, Cursor, and any tool that outputs code diffs.