Lesson 2.5 — Permission Modes and –allowedTools: Your Safety Dial
Lesson 2.5 — Permission Modes and --allowedTools: Your Safety Dial
Module 2 · Core Commands & File Context
THE NAIVE APPROACH TRAP
A developer who has only used Claude.ai interactively carries a specific mental model into their first Claude Code session: Claude is a text generator that produces suggestions, and they decide what to apply. That model is wrong the moment they run claude in a real repository.
Without any tool restrictions, Claude Code can read files, write files, execute arbitrary shell commands, fetch external URLs, and invoke every connected MCP server tool — all in one session, all without confirmation if you're in --print mode. The developer who types:
has just given Claude permission to edit any file in the working tree, run npm install, execute git commit, and git push origin main — because "make sure tests pass" implies running tests, and Claude's tool use is greedy toward task completion, not blast-radius minimization. The commit happens before the developer reads the output.
The specific failure: Claude's judgment about what's appropriate is the only safeguard. Claude is optimized to complete tasks. It is not optimized to minimize the surface area of changes.
THE FAILURE MODE
Silent over-permission in headless mode. In --print mode, there is no terminal to prompt. Claude Code must either use a tool or skip it — there is no "ask first." Without --allowedTools, the full tool set is available: Bash, Write, Edit, MultiEdit, WebFetch, and any connected MCP server tools. A CI job intended to generate a code review comment can git push or curl an external endpoint if Claude determines that satisfies the task.
--dangerouslySkipPermissions used alone. This flag disables every permission prompt. Its purpose is headless automation in a sandboxed environment where tool access is already bounded externally. Used without --allowedTools in a developer's working directory, it is equivalent to granting Claude root-level access to the working tree with no human in the loop at any point. The flag name contains the word "dangerously" because the team who shipped it wanted that word in every shell history line where it appears.
Tool name typos produce silent no-ops. --allowedTools Reads (extra s) is silently discarded — Claude Code ignores unrecognized tool names and falls back to interactive prompts. In --print mode with no terminal, the fallback is to allow all tools. Your "restricted" pipeline is actually unrestricted, and you will not receive an error message telling you so.
ANTHROPIC_API_KEY overrides Pro subscription billing silently. If you set ANTHROPIC_API_KEY in your shell (for Module 8 Artifact work) and forget to unset it before running claude, every subsequent Claude Code session bills to API credits at the per-token API rate, not your $20/month Pro subscription. There is no in-terminal warning. The cost difference surfaces only in your console.anthropic.com usage dashboard, after the tokens are spent.
Non-zero exit codes from permission denials. When Claude cannot complete a task because a required tool is blocked, Claude Code exits 2. Bare shell scripts that only gate on exit_code != 0 (exit 1 = hard CLI error) will treat a silently incomplete task as a success. Gate CI steps on both: exit_code == 1 (auth/API failure) and exit_code == 2 (task-level incomplete).
THE CLAUDEFORGE ARCHITECTURE
Lesson 2.5 is the bridge between deliberate context loading and safe automation. Lessons 2.1–2.4 taught you how to load exactly the right context into Claude's window. This lesson teaches you to constrain what Claude can do with that context before you remove yourself from the loop.
Keep going with the full lesson
The rest of this lesson — plus its implementation guide, runnable scripts and source code — is included with the course or an All Access plan. Create a free account to start the free lessons in every course.
Already a member? Sign in