From product-design
Reference for configuring tool permissions when launching Claude Code agents. Use when setting up --allowedTools flags, restricting file access, or configuring agent permissions.
npx claudepluginhub jpoutrin/product-forge --plugin product-designThis skill uses the workspace's default tool permissions.
Configure tool permissions when launching parallel Claude Code agents.
Configures Claude Code permissions: tool rules (allow/deny/ask), modes (plan/dontAsk/bypass), sandboxing. Use for Bash/Edit/WebFetch policies, debugging prompts, org managed settings.
Guides creation of custom agents for Claude Code, including file structure, behaviors, tool permissions, workflows, and YAML configuration for specialized tasks.
Lists Claude Code default tools by category and agent tool access configurations including whitelists, blacklists, MCP customs, patterns, and token warnings.
Share bugs, ideas, or general feedback.
Configure tool permissions when launching parallel Claude Code agents.
| Tool | Description | Use Case |
|---|---|---|
Read | Read files | Always needed for context |
Write | Create new files | Creating new code files |
Edit | Modify existing files | Updating existing code |
Bash | Execute shell commands | Running tests, builds, git |
Glob | Find files by pattern | File discovery |
Grep | Search file contents | Code search |
WebFetch | Fetch web content | Documentation lookup |
WebSearch | Search the web | Research |
TodoWrite | Manage task lists | Progress tracking |
Task | Launch sub-agents | Delegation |
NotebookEdit | Edit Jupyter notebooks | Data science |
mcp__<server> | MCP server tools | External integrations |
Each tool is a separate quoted argument:
claude --allowedTools "Tool1" "Tool2" "Tool3(...)" --print "prompt"
Example with multiple tools:
claude --allowedTools "Read" "Edit" "Bash(pytest:*)" --print "implement feature"
Restrict file operations to specific directories using gitignore-style patterns.
| Pattern | Meaning | Example |
|---|---|---|
//path | Absolute filesystem path | Edit(//Users/alice/src/**) |
~/path | Home directory relative | Read(~/.zshrc) |
/path | Relative to settings file | Edit(/src/**/*.ts) |
path | Relative to current directory | Read(src/**) |
# Allow editing only in src/ directory
claude --allowedTools "Edit(/src/**)" --print "..."
# Allow editing TypeScript files only
claude --allowedTools "Edit(/src/**/*.ts)" --print "..."
# Multiple path restrictions
claude --allowedTools "Read" "Edit(/apps/users/**)" "Edit(/tests/**)" --print "..."
# Absolute path restriction
claude --allowedTools "Edit(//tmp/scratch.txt)" --print "..."
Restrict which shell commands can be executed using prefix matching.
Bash(command:*)
The :* wildcard only works at the END of patterns (prefix matching).
| Pattern | Matches | Does NOT Match |
|---|---|---|
Bash(pytest:*) | pytest, pytest apps/ | python -m pytest |
Bash(npm run test:*) | npm run test, npm run test:unit | npm run build |
Bash(git log:*) | git log --oneline | git commit |
Bash(git status:*) | git status | git push |
Bash(mypy:*) | mypy apps/ | python -m mypy |
Bash(ruff:*) | ruff check . | python -m ruff |
claude --allowedTools "Bash(pytest:*)" "Bash(mypy:*)" "Bash(ruff:*)" "Read" --print "run tests"
Claude Code prevents bypass via shell operators (&&, ;, ||). Be aware:
python -m pytest vs pytest)WebFetch(domain:...) over Bash(curl:*)Restrict web fetches to specific domains:
claude --allowedTools "WebFetch(domain:github.com)" "WebFetch(domain:docs.python.org)" --print "..."
claude --allowedTools "mcp__puppeteer" --print "..."
claude --allowedTools "mcp__puppeteer__puppeteer_navigate" --print "..."
Note: MCP permissions do NOT support wildcards (*).
| Task Type | Recommended --allowedTools |
|---|---|
| Implementation | "Read" "Write" "Edit(/apps/myapp/**)" "Bash(pytest:*)" "Bash(mypy:*)" "Glob" "Grep" |
| Code Review | "Read" "Glob" "Grep" (read-only) |
| Testing Only | "Read" "Bash(pytest:*)" "Bash(npm test:*)" |
| Documentation | "Read" "Write(/docs/**)" "Edit(/docs/**)" "WebFetch" |
| Full Access | --dangerously-skip-permissions |
When using git worktrees for isolation, --dangerously-skip-permissions is safe:
# Safe in isolated worktree
claude --dangerously-skip-permissions --print "$(cat prompts/task-001.txt)"
When agents share a workspace, use path-scoped permissions:
claude \
--allowedTools \
"Read" \
"Write(/apps/users/**)" \
"Edit(/apps/users/**)" \
"Bash(pytest apps/users/:*)" \
"Bash(mypy apps/users/:*)" \
"Glob" \
"Grep" \
--print "$(cat prompts/task-001.txt)"
claude \
--allowedTools \
"Read" \
"Write(/apps/orders/**)" \
"Edit(/apps/orders/**)" \
"Bash(pytest apps/orders/:*)" \
"Bash(mypy apps/orders/:*)" \
"Bash(ruff check apps/orders/:*)" \
"Glob" \
"Grep" \
--print "Implement order management per task-004 spec"
claude \
--allowedTools \
"Read" \
"Write(/src/components/Dashboard/**)" \
"Edit(/src/components/Dashboard/**)" \
"Bash(npm run test:*)" \
"Bash(npm run lint:*)" \
"Glob" \
"Grep" \
--print "Implement Dashboard components per task-003 spec"
claude \
--allowedTools \
"Read" \
"Glob" \
"Grep" \
"WebFetch(domain:docs.python.org)" \
--print "Analyze codebase and suggest improvements"
| Restriction Type | Syntax |
|---|---|
| Allow tool everywhere | "Edit" |
| Restrict to directory | "Edit(/src/**)" |
| Restrict to file type | "Edit(/src/**/*.ts)" |
| Restrict bash command | "Bash(pytest:*)" |
| Restrict web domain | "WebFetch(domain:github.com)" |
| Allow MCP server | "mcp__puppeteer" |
| Allow specific MCP tool | "mcp__puppeteer__puppeteer_navigate" |
| Skip all permissions | --dangerously-skip-permissions |
Match permissions to task boundaries:
# Task owns apps/users/
--allowedTools "Edit(/apps/users/**)" "Write(/apps/users/**)"
# Task owns apps/orders/
--allowedTools "Edit(/apps/orders/**)" "Write(/apps/orders/**)"
--allowedTools "Read" "Bash(pytest:*)" "Bash(npm test:*)" "Bash(go test:*)"
--allowedTools "Read" "Write(/docs/**)" "Edit(/docs/**)" "WebFetch" "WebSearch"
--allowedTools "Read" "Edit(/terraform/**)" "Edit(/docker-compose.yml)" "Bash(terraform:*)" "Bash(docker:*)"