What is the difference between --allowedTools and --dangerously-skip-permissions in Claude Code
I wanted to run Claude Code in non-interactive mode for a CI/CD pipeline. I saw --dangerously-skip-permissions mentioned in several tutorials and thought: “Great, that’s the flag to stop the prompts.” I added it to my script, ran it on a server, and watched Claude delete files I didn’t intend to delete.
That’s when I realized I had completely misunderstood the permission model.
The Problem: Confusing Convenience with Safety
Most tutorials present --dangerously-skip-permissions as simply “the flag to stop the prompts.” Here’s a typical example:
claude --dangerously-skip-permissions --prompt "Analyze the codebase and fix any issues"This works, but it’s dangerous. The flag bypasses ALL confirmations. Claude can read, write, execute commands - anything - without asking. The “dangerously” prefix in the name isn’t just a warning label; it’s describing the actual behavior.
On my first attempt, Claude decided to “clean up” some files it thought were unnecessary. Those files contained important configuration data. If I had used --allowedTools instead, this wouldn’t have happened.
The Correct Approach: Scoped Permissions with —allowedTools
After the incident, I discovered --allowedTools. Instead of removing all guardrails, this flag defines a specific allowlist of tools Claude can use without prompting.
For my original use case (code analysis), I should have written:
claude --allowedTools "Read" "Glob" "Grep" --prompt "Analyze the codebase for issues"Now Claude can explore and analyze code, but it cannot modify anything. The blast radius is contained.
Understanding the Permission Model
The key insight from the Reddit discussion:
“The permission model is a blast-radius limiter for accidents, not a security boundary for adversarial inputs.”
This distinction matters:
- Blast radius limiter: If Claude makes a mistake, the damage is contained within allowed tools
- Not a security boundary: Malicious prompts can still exploit allowed tools
Think of it like giving someone keys to specific rooms in a building versus giving them the master key.
Practical Scoping Strategies
Read-Only Analysis Tasks
When I need Claude to analyze code without touching anything:
claude --allowedTools "Read" "Glob" "Grep" --prompt "Review the authentication module"Analysis with Outbound Notifications
When I want Claude to also send notifications via webhooks:
claude --allowedTools "Read" "Bash(curl *)" --prompt "Check for vulnerabilities and notify the team"Note: Bash(curl *) allows arbitrary curl commands. A safer pattern might be Bash(curl -X GET *) to limit request types.
CI/CD Pipeline with Git Operations
For automated workflows that need to commit and push:
claude --allowedTools "Edit" "Read" "Bash(npm test)" "Bash(git *)" \ --prompt "Fix the failing tests and commit the changes"This gives Claude just enough power to do its job without the risk of running arbitrary commands.
When to Use —dangerously-skip-permissions
There’s one legitimate use case: truly isolated, ephemeral environments.
docker run --rm -it claude-code \ --dangerously-skip-permissions \ --prompt "Refactor the codebase"The --rm flag ensures the container is deleted after use. If something goes wrong, you just spin up a new container. But on a server with production access? Never.
Comparing the Two Approaches
┌─────────────────────────────────────────────────────────────────┐│ --allowedTools ││ ────────────────────────────────────────────────────────────── ││ - Defines specific tools Claude can use ││ - Creates a permission boundary ││ - Limits blast radius for accidents ││ - Default choice for automation │└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐│ --dangerously-skip-permissions ││ ────────────────────────────────────────────────────────────── ││ - Bypasses ALL confirmations ││ - Removes all guardrails ││ - Unlimited access to read, write, execute ││ - Only for throwaway environments │└─────────────────────────────────────────────────────────────────┘Common Mistakes I Made
-
Copying flags from tutorials without understanding: Many examples use
--dangerously-skip-permissionsfor simplicity, which I copied without thinking. -
Treating allowedTools as a security feature: I initially thought
--allowedToolswas about security. It’s not - it limits accidents, not adversarial behavior. Proper prompt engineering and input validation are still required. -
Overly broad Bash permissions:
Bash(curl *)is still risky. Better to use specific command patterns or MCP tools instead.
Decision Framework
When setting up Claude Code automation, I now follow this process:
- Define the task clearly - What exactly does Claude need to do?
- Identify required tools - Read, Write, Edit, Bash commands?
- Scope to minimum - Grant only what’s necessary
- Test in isolation - Run in a throwaway environment first
- Review outputs - Check what Claude actually did
# Step 1: Read-only analysis firstclaude --allowedTools "Read" "Glob" "Grep" --prompt "Identify issues"
# Step 2: Scoped fixes with human reviewclaude --allowedTools "Edit" "Read" --prompt "Fix the identified issues"
# Step 3: Controlled deploymentclaude --allowedTools "Bash(git add *)" "Bash(git commit *)" "Bash(git push origin *)" \ --prompt "Commit and push changes"This multi-step approach with different scopes at each stage is safer than one big unrestricted run.
Summary
The difference between --allowedTools and --dangerously-skip-permissions is fundamental:
--allowedTools= Scoped, controlled autonomy. Define exactly what Claude can do. Use this as your default approach.--dangerously-skip-permissions= Unrestricted autonomy. No guardrails at all. Reserve for throwaway containers only.
The permission model in Claude Code is a blast-radius limiter for accidents, not a security boundary for adversarial inputs. Use it accordingly: scope permissions to the minimum required for your task, and never use --dangerously-skip-permissions on systems you care about.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments