Understanding Permissions
Deep dive into Claude Code's permission system, including when and how to use --dangerously-skip-permissions safely.
What you'll accomplish
Understand the risks and proper use of Claude Code permissions and the skip-permissions flag.
Prerequisites
- Completed Configuration Deep Dive lesson
- Familiarity with Docker (for safe usage)
The Permission System
By default, Claude Code asks permission before:
- Writing files: Creating or modifying any file
- Executing commands: Running anything in the terminal
- Accessing sensitive locations: Reading certain files
This is a safety feature, not an annoyance. It keeps you in control.
Warning
Important: Claude Code is an AI assistant. Like any tool, it can make mistakes. The permission system is your chance to catch those mistakes before they happen.
Permission Levels
Read Operations
Claude Code typically auto-approves reading files it needs for context. You can control this:
json{ "autoApprove": { "read": true } }
Setting this to false would require approval for every file read - usually too restrictive.
Write Operations
Writing files (create, modify, delete) requires explicit approval:
Claude wants to create file: src/components/Button.tsx
[y] Yes [n] No [v] View content [e] Edit first
Options:
y- Approve the writen- Reject the writev- See the full file content before decidinge- Edit the content before saving
Execute Operations
Running commands requires explicit approval:
Claude wants to run: npm install react
[y] Yes [n] No [m] Modify command
Options:
y- Run the commandn- Don't run itm- Edit the command before running
The Danger: --dangerously-skip-permissions
The --dangerously-skip-permissions flag tells Claude Code to automatically approve all operations without asking.
bashclaude --dangerously-skip-permissions
When enabled, Claude Code will:
- ✓ Create, modify, and delete any file
- ✓ Run any command without confirmation
- ✓ Execute destructive operations automatically
- ✓ Make changes you can't easily review
Why It Exists
The flag is useful for:
- Automated pipelines (CI/CD) where human approval isn't possible
- Containerized environments where damage is contained
- Rapid prototyping where you trust the context completely
- Batch operations on disposable environments
Why It's Dangerous
Real risks include:
| Scenario | What Could Happen |
|---|---|
| Misunderstood request | Claude deletes files you wanted to keep |
| Overeager cleanup | "Remove unused code" deletes your tests |
| Command chaining | Innocent command + mistake = disaster |
| Sensitive file access | Secrets logged or exposed |
| Runaway modifications | Small change spirals into large refactor |
Imagine giving someone your house keys and saying:
- "Reorganize my stuff however you think best"
- "I trust your judgment completely"
- "Don't ask me before throwing anything away"
Even with the best intentions, they might:
- Throw away something you wanted to keep
- Move things where you can't find them
- Misunderstand what "organize" means to you
The permission system is like saying "show me what you're about to change first."
Safe Usage: Isolated Environments
Strongly prefer disposable or isolated environments when using --dangerously-skip-permissions. This includes:
- Docker containers (most common)
- Virtual machines
- Throwaway Git branches (where you can easily discard all changes)
- Cloned project directories (not your main working copy)
The key principle is limiting the blast radius—if Claude makes unwanted changes, you should be able to easily discard them without affecting your real work.
Why Docker Is Popular for This
Docker is the most common choice because it provides:
- Isolation: The container is separate from your real system
- Disposability: If something goes wrong, delete the container
- Reversibility: Your actual files are untouched
- Reproducibility: Containers can be rebuilt from scratch
Basic Docker Setup
Dockerfile:
dockerfileFROM node:20-slim # Install Claude Code RUN npm install -g @anthropic-ai/claude-code # Create workspace WORKDIR /workspace # Run as non-root user RUN useradd -m coder USER coder # Default command CMD ["claude", "--dangerously-skip-permissions"]
Build and run:
bash# Build the image docker build -t claude-dev . # Run with your project mounted docker run -it \ -v $(pwd):/workspace \ -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \ claude-dev
Warning
Even with Docker, be careful about volume mounts. If you mount your home directory (-v ~:/workspace), Claude has access to everything in it.
Docker Compose Setup
For a more complete setup:
yaml# docker-compose.yml version: '3.8' services: claude: build: . volumes: - ./project:/workspace environment: - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} stdin_open: true tty: true
Run with:
bashdocker-compose run claude
Recommended Volume Strategy
Mount only what Claude needs:
bash# Good: Only the project directory docker run -it -v ./my-project:/workspace claude-dev # Bad: Your whole home directory docker run -it -v ~:/workspace claude-dev # DON'T DO THIS
Alternative: Selective Auto-Approve
Instead of skipping all permissions, selectively auto-approve safe operations:
json{ "autoApprove": { "read": true, "write": { "patterns": ["src/**/*.ts", "src/**/*.tsx"], "exclude": ["*.env*", "*.secret*", "package-lock.json"] }, "execute": { "commands": ["npm run", "npx prettier", "npx eslint"], "exclude": ["rm", "sudo", "git push"] } } }
This approach:
- Auto-approves writes to specific directories
- Excludes sensitive files
- Allows specific safe commands
- Still requires approval for everything else
Permission Best Practices
1. Start Restrictive
Begin with default permissions. Only relax them after you understand the workflow.
2. Review Before Approving
Take time to read what Claude is proposing. A few seconds of review can prevent hours of cleanup.
3. Use Git as a Safety Net
Always work in a Git repository. If something goes wrong:
bash# See what changed git diff # Undo all changes git checkout . # Or undo specific files git checkout src/important-file.ts
4. Test in Isolation First
Before running --dangerously-skip-permissions on a real project:
- Clone the repo to a temporary location
- Run Claude there first
- Review the changes
- Apply to the real project if satisfied
5. Set Up Hooks for Safety
Use pre-execute hooks to block dangerous commands:
json{ "hooks": { "pre-execute": { "command": "./scripts/command-safety.sh {{command}}", "failBehavior": "block" } } }
When to Use Each Approach
| Scenario | Recommendation |
|---|---|
| Learning / exploring | Default permissions (ask for everything) |
| Normal development | Auto-approve reads, manual approve writes |
| Trusted, simple task | Auto-approve matching patterns |
| Docker container | --dangerously-skip-permissions OK |
| CI/CD pipeline | --dangerously-skip-permissions OK |
| Production system | Never use skip-permissions |
| Shared machine | Default permissions only |
Recovering from Mistakes
If Claude makes unwanted changes:
With Git (Recommended)
bash# See what changed git status git diff # Undo all uncommitted changes git checkout . git clean -fd # Undo specific file git checkout path/to/file.ts # Undo last commit (keep changes staged) git reset --soft HEAD~1 # Undo last commit (discard changes) git reset --hard HEAD~1
Without Git
If you're not using Git (please start!):
- Check your IDE's local history (VS Code: File > Local History)
- Check system backups (Time Machine, etc.)
- Manually review and fix changes
In Docker
bash# Delete the container (changes in container are lost) docker rm container_name # Changes in mounted volumes persist - use git # Start fresh docker run -it claude-dev
Common Issues
Frequently Asked Questions
If you're using Git, yes - use git checkout . to revert. Without Git or Docker isolation, recovery may be difficult or impossible for destructive changes.
Yes, when prompted you can often type:
y- approve this onea- approve all (for this session)n- reject this one
Check the prompt for available options.
Yes, use hooks with failBehavior: "block":
json{ "hooks": { "pre-write": { "command": "./scripts/check-write.sh {{file}}", "failBehavior": "block" } } }
You're always in control. If Claude suggests something risky:
- Reject the operation (
n) - Explain why it's problematic
- Ask for an alternative approach
- Exit the session if needed (
/exit)
Be cautious of:
rm -rf(especially with/,~,*)sudoanythinggit push --force- Commands with
>(overwrites files) - Package install commands from unknown sources
- Commands that modify system files
Verify Your Understanding
You've completed this lesson if you can:
Next: Running Claude Code in Docker containers for isolation.