Welcome back to Advanced Claude Code Features! This is our second unit, and we are making excellent progress. In the previous lesson, we explored custom slash commands and learned about their structure and limitations. Now, we will turn our attention to a fundamental aspect of working safely with Claude Code: managing tool permissions.
In this lesson, we will learn how to control which tools Claude can use and under what conditions. This is critical because while Claude is powerful, some operations like editing files or running shell commands carry inherent risks. We will discover how to view current permissions, configure automatic approvals for safe operations, set up pattern-based rules, and understand the priority system that governs these decisions.
By the end of this lesson, we will know how to create a permission strategy that balances productivity with safety, ensuring Claude can work efficiently while protecting our codebase from unintended changes.
Before diving into the technical details, let's understand why permission management is essential. Claude Code provides several tools that interact with our system: reading files, editing code, searching content, and executing shell commands. While these capabilities enable powerful workflows, they also introduce potential risks.
Consider what could happen without proper controls: Claude might accidentally overwrite an important file, execute a destructive shell command, or make network requests that expose sensitive data. Even with the best intentions, automated actions carry inherent risk. This is where permissions come in: they act as guardrails that define what Claude can and cannot do.
The goal is not to restrict Claude unnecessarily, but rather to create a thoughtful boundary. Safe operations, such as reading files or searching code, can happen automatically, while risky actions, such as deleting files or pushing to production, require explicit approval. This balance keeps our workflow smooth while maintaining safety.
Not all tools carry the same level of risk. Claude Code categorizes tools based on their potential impact on our system. Understanding these categories helps us make informed decisions about permission levels.
Low-risk tools include operations that only read or search existing data:
Read— allows viewing file contents without modificationWebSearch— performs internet searches to gather informationGrep— searches through text content in filesGlob— lists files matching specific patterns
These tools are generally safe to auto-approve because they cannot modify our codebase or system state.
Medium to high-risk tools involve changes or system commands:
Edit— modifies existing files by applying patchesWrite— creates new files or overwrites existing onesBash— executes shell commands with full system access
These tools require more careful consideration. A single edit can change important logic, and a shell command could delete files or alter the system configuration. We typically want explicit approval for these operations, at least initially.
Claude Code provides an interactive interface to check and manage our current permission configuration. We use the /permissions command to access this interface:
This interactive interface shows us the current permission state through four tabs: Allow, Ask, Deny, and Workspace. We can cycle through these tabs using arrow keys or tab to navigate between different permission categories.
In practice, Claude Code intelligently handles permissions based on operation risk. Read-only operations like Read, Search, and certain Bash commands that don't modify the system run automatically without prompting, providing a smooth workflow. Operations that could modify files or the system state—such as Write, Edit, or destructive Bash commands—require explicit permission.
This balanced approach gives us both convenience and safety: we can explore code, search files, and gather information freely, while retaining control over any changes to our workspace. We can further customize this behavior through the permission interface:
To streamline our workflow, we can configure certain safe tools to execute automatically without prompts. This is done through a settings.json file in the .claude directory. Let's create a configuration that auto-approves low-risk operations:
The allow array inside the permissions object lists tools that can execute without prompting. We have included the four low-risk tools we discussed earlier. Now, when Claude needs to read a file or search the web, these operations happen seamlessly in the background. This configuration lives in .claude/settings.json at the project root, making it specific to this workspace.
For operations that carry more risk, we can use the ask array to specify which actions need approval. This supports pattern matching for fine-grained control:
These patterns provide fine-grained control:
Edit(**/*.ts)andEdit(**/*.tsx)meanClaudewill prompt before editing any TypeScript files.Bash(rm*)requires approval for file deletion commands.
The ** pattern matches any number of directories, while * matches any characters within a path segment. This pattern syntax allows us to be specific about which operations need oversight while keeping the workflow smooth for routine tasks.
While the settings.json file supports a deny array for blocking specific operations:
These restrictions are not reliably enforced. Even when specified in the deny array, Claude may still execute the operations. The configuration system appears to be primarily advisory rather than strictly enforced at the settings.json level. For reliable permission enforcement, we need to use CLI flags instead.
For effective permission control, Claude Code provides CLI flags that enforce restrictions at startup. These flags reliably control what Claude can and cannot do:
When we start Claude with these flags, the session begins with the specified permissions enforced:
Unlike settings.json configurations, these CLI flags are strictly enforced. When we attempt a disallowed operation, it is blocked:
These CLI flags provide reliable permission enforcement for sessions where we need specific restrictions. For example, during a code review, we might allow only read operations, or when working on documentation, we might permit edits but disable shell commands. The flags give us guaranteed control over what Claude can access.
When using CLI flags, Claude Code follows a clear priority order:
The --disallowedTools flag always takes precedence. If we start Claude with both --allowedTools "Bash" and --disallowedTools "Bash(rm*)", any rm commands are blocked because the specific disallow pattern overrides the general allow pattern:
With this configuration, Bash(ls -la) executes automatically, but Bash(rm file.txt) is immediately denied. The system evaluates rules from most restrictive to least restrictive, ensuring that safety constraints are never accidentally bypassed by broader permissions.
With our configuration in place, let's see how auto-approved tools work. When we ask Claude to search for information, the WebSearch tool executes without interruption:
Notice there is no approval prompt. Because WebSearch is in our allow list within the permissions object, Claude executed the search immediately. The workflow is seamless: we made a request, and Claude handled the technical details without requiring our intervention. This is the power of thoughtful permission configuration; safe operations happen smoothly while risky ones are controlled through the ask array or blocked by CLI flags.
In this lesson, we have learned how to manage tool permissions in Claude Code. We explored the /permissions command for viewing current settings, configured auto-approval for safe tools through the allow array inside the permissions object in settings.json, set up pattern-based confirmation rules using the ask array, and discovered that CLI flags provide the most reliable permission enforcement. We also understood the priority system where --disallowedTools flags always take precedence.
Permission management is about finding the right balance: enabling Claude to work efficiently on safe operations while controlling or blocking actions that carry risk. The settings.json file is useful for workflow preferences like auto-approving read operations and specifying which operations need confirmation through the ask array, while CLI flags provide guaranteed enforcement when we need strict boundaries.
Now, it is time to apply this knowledge hands-on! The upcoming practice exercises will guide you through configuring permissions for different scenarios, helping you develop the judgment needed to create effective permission strategies for real-world projects. Let's put these concepts into action and build your confidence in managing Claude Code safely!
