Learning Objectives
- Customise Claude Code settings for your workflow
- Set up project-specific CLAUDE.md configuration
- Optimise your automation environment
π― What You'll Learn: How to configure Claude Code for productivity AND safety
β±οΈ Time Required: 50 minutes
π¦ What You'll Build: A customized settings.json with proper permissions
Riley's Journey Continues
Riley knows the commands. But every time Claude reads a file - click. Every search - click. She's still playing whack-a-mole with permissions.
π¬ "I understood WHY the permissions existed - safety first. But I needed to find the balance between 'too cautious' and 'too risky.' That's what this lesson gave me."
β Riley Harper
This lesson teaches Riley (and you):
What We're Building in This Lesson
Configure once, benefit forever. The right settings make Claude feel like it was built just for you.
In this lesson:
The .claude Folder Structure
π .claude/
βββ π settings.json β Your configuration (this lesson)
βββ π CLAUDE.md β Project context (Week 2)
βββ π skills/ β Your skills (you know this!)
β βββ π your-skill/
β βββ π SKILL.md
βββ π agents/ β Custom agents (Week 2)
βββ π commands/ β Custom commands
Today's focus: settings.json - your control panel.
Settings.json: Your Control Panel
settings.json controls what Claude can do, through one permissions section with two lists:
| Section | What It Does | Example |
|---|---|---|
| permissions.allow | What Claude can do WITHOUT asking | ["Read", "Glob", "Bash(git *)"] |
| permissions.deny | What Claude should NEVER do | ["Bash(rm -rf *)", "Bash(sudo *)"] |
Anything not on either list, Claude asks you about before running.
The transformation:
BEFORE: Every action β Permission prompt β Click β Wait
AFTER: Safe actions β Auto-approved β Smooth flow
Risky actions β Permission prompt β You decide
Dangerous actions β Blocked entirely β Protected
Permission Levels Explained
| Level | Best For | Allow list | Deny list |
|---|---|---|---|
| π Conservative | Exploring new code | Read, Glob, Grep only | All write/bash tools |
| βοΈ Balanced | Daily work | Read + Write + safe Bash patterns | Dangerous patterns like rm -rf * |
| π Aggressive | Sandboxed containers | All tools | Only your specific blocks |
The allow list handles what runs without asking. The deny list is your hard stop, these never run regardless. Anything not in either list prompts for approval.
Riley's choice:
π¬ "I went Balanced. Reads fly through automatically. Writes prompt me once. And anything destructive is blocked before Claude can even try."
Exercise: Configure Your Environment
β±οΈ Total Time: 40 minutes
What You'll Build
βοΈ A properly configured settings.json with permissions, auto-approvals, and safety blocks.
Before You Start
You'll need:
Step 1: Find or Create settings.json
β±οΈ Time: 5 minutes
Check if it exists:
cat ~/.claude/settings.json
If it doesn't exist, create it:
touch ~/.claude/settings.json
Open it in your editor.
β Success Check:
Step 2: Add Base Configuration
β±οΈ Time: 10 minutes
Copy this Balanced template:
{
"permissions": {
"allow": [
"Read",
"Glob",
"Grep",
"Write",
"Bash(git *)",
"Bash(ls *)",
"Bash(pwd)",
"Bash(cat *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(sudo *)",
"Bash(chmod 777 *)"
]
}
}
How it works:
| Section | What it does |
|---|---|
permissions.allow | Tools Claude can use without asking, tool names or patterns like Bash(git *) |
permissions.deny | Tools that are blocked entirely, takes priority over allow |
Claude will ask for approval on anything not explicitly listed. The * wildcard matches any arguments, Bash(git *) allows all git commands, Bash(rm -rf *) blocks that specific pattern.
Riley's configuration:
{
"permissions": {
"allow": [
"Read",
"Glob",
"Grep",
"Write",
"Bash(git *)",
"Bash(npm install)",
"Bash(npm run *)",
"Bash(ls *)",
"Bash(pwd)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(sudo *)",
"Bash(chmod 777 *)",
"Bash(git push --force*)"
]
}
}
π¬ "I added 'git push --force' to deny because that's caused problems before. Think about YOUR danger zones, whatever you'd regret if it ran without asking."
β Success Check:
Step 3: Customise Your Deny List
β±οΈ Time: 10 minutes
Think about YOUR work. What should NEVER happen?
Universal Denies (Everyone Should Have)
"deny": [
"Bash(rm -rf *)",
"Bash(sudo *)",
"Bash(chmod 777 *)",
"Bash(dd *)",
"Bash(mkfs *)"
]
Database Work? Add These:
"Bash(* DROP TABLE*)",
"Bash(* DROP DATABASE*)",
"Bash(* TRUNCATE *)",
"Bash(* DELETE FROM*)"
Cloud/Production? Add These:
"Bash(aws s3 rm *)",
"Bash(kubectl delete *)",
"Bash(* --production *)"
Git Safety? Add These:
"Bash(git push --force*)",
"Bash(git reset --hard *)",
"Bash(git clean -fd*)"
Fill in your deny patterns based on YOUR risk profile:
"permissions": {
"allow": [
"Read", "Glob", "Grep", "Write"
// Add your safe Bash patterns here
],
"deny": [
// Universal
"Bash(rm -rf *)",
"Bash(sudo *)",
"Bash(chmod 777 *)",
// My specific blocks
"_____________________",
"_____________________"
]
}
β Success Check:
Step 4: Test Your Configuration
β±οΈ Time: 15 minutes
Save your settings.json and test:
Test 1: Allowed Reads
Read my Quick Win skill file
Expected: Proceeds WITHOUT prompting (Read is in your allow list) β
Test 2: Writes (allowed but prompts by default)
Add a comment to my skill file
Expected: Either proceeds automatically (Write in allow list) or asks once β
Test 3: Denied Command
Run rm -rf on the temp folder
Expected: Claude refuses, the deny list catches it β
Test 4: Bash (pattern-matched)
Show me the current directory
Expected: Runs automatically if Bash(ls *) is in your allow list; prompts otherwise β
Riley's test results:
π¬ "First test - reads flew through without prompting. That alone made my day better. Tested the deny, Claude refused cleanly. Everything working as designed."
β Success Check:
Optional: IDE Integration
β±οΈ Time: 5 minutes (if you use VS Code)
If you use VS Code:
Key shortcuts:
| Action | Mac | Windows |
|---|---|---|
| Open Claude panel | Cmd+Shift+P β "Claude" | Ctrl+Shift+P β "Claude" |
| Ask about selection | Select code β Right-click | Select code β Right-click |
π‘ Pro Tip: Use terminal for complex tasks, IDE for quick questions about specific code.
Overall Success Criteria
By the end of this lesson, you should have:
Quick Verification:
Troubleshooting
π΄ "JSON syntax error"
**Why this happens:** Invalid JSON formatting.
**Common fixes:**
- Check for missing commas between items
- Check for trailing comma after last item (remove it)
- Ensure all strings are in quotes
- Use a JSON validator: jsonlint.com
**Example fix:**
// β Wrong (trailing comma)
["read", "glob",]
// β
Right
["read", "glob"]
π΄ "Claude is still asking for tools I allowed"
**Why this happens:** Tool names in the allow list need to match exactly, they're case-sensitive.
**Use these exact names:**
- Read (capital R)
- Glob (capital G)
- Grep (capital G)
- Write (capital W)
- Bash(git *) for bash patterns
**Check:** Run /help in a session and look at the tool list to confirm names.
π΄ "Blocked command still ran"
**Why this happens:** Command variant not covered.
**Example:** You blocked Bash(rm -rf *) but rm -r -f ran.
**Fix:** Add common variants to your deny list:
"deny": [
"Bash(rm -rf *)",
"Bash(rm -r -f *)",
"Bash(rm -fr *)"
]
π΄ "Can't find .claude folder"
**Why this happens:** Different location by OS or not created yet.
**Fix:**
1. Run Claude Code once (it creates the folder)
2. Or create manually: mkdir -p ~/.claude
3. On Windows, check: C:\Users\YourName\.claude
You Did It!
You just configured Claude Code to work YOUR way!
Riley's transformation:
| Before | After |
|---|---|
| π€ Click-click-click for every action | π Reads flow automatically |
| π° Worried about dangerous commands | π Safety net in place |
| π€· Default settings for everyone | βοΈ Customized for my work |
π¬ "This is when Claude Code stopped feeling like a tool I was fighting with and started feeling like a tool that understood me. The configuration took 30 minutes and saves me frustration every single day."
How Others Configure
James Chen, Healthcare IT Director
{
"permissions": {
"allow": [
"Read", "Glob", "Grep", "Write",
"Bash(git *)", "Bash(ls *)"
],
"deny": [
"Bash(rm -rf *)", "Bash(sudo *)",
"Bash(curl *)", "Bash(wget *)"
]
}
}
"In healthcare, data doesn't leave the system. I deny all network commands that could transmit data externally."
Dr. Sarah Patel, Management Consultant
{
"permissions": {
"allow": [
"Read", "Glob", "Grep", "Write",
"Bash(git *)", "Bash(ls *)"
],
"deny": [
"Bash(rm -rf *)", "Bash(sudo *)",
"Bash(cd ../*)","Bash(* ../)"
]
}
}
"I use project-specific settings for each client engagement. The deny list blocks any attempt to navigate out of the current directory. No cross-contamination."