[FEATURE] Add allowed_paths scope restriction to settings.json
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Claude Code currently has no native way to restrict which folders it can access. When started from a home directory (~) or a broad root, Claude can read and traverse the entire file system, creating two serious problems:
- Security Risk
Users cannot enforce a hard boundary on which folders Claude is allowed to access. Sensitive files outside the project scope — SSH keys, environment files, personal documents — are potentially exposed. The existing permissions.deny in settings.json is insufficient as it requires explicitly listing every sensitive file, and as reported in issues #2162, #7246, and #29159, deny rules are not reliably enforced anyway. There is currently no way to say "Claude can ONLY access this folder" at the config level.
- Token Waste
Without scope restriction, Claude reads files broadly across the project tree, consuming unnecessary tokens from irrelevant files. This is especially painful for users on limited plans (Pro $20/month) where token limits are hit quickly during long coding sessions.
Proposed Solution
Here's the complete Proposed Solution section:
---
Proposed Solution
Add allowed_paths and deny_outside_scope to ~/.claude/settings.json:
{
"allowed_paths": ["~/Projects/myapp/src"],
"deny_outside_scope": true
}
This is intentionally minimal — just two fields, declarative, and immediately understandable to any developer.
---
This completes a natural two-layer control system that Claude Code already has half of:
Layer 1: WHERE can Claude go? → settings.json (MISSING ❌)
Layer 2: WHAT can Claude see there? → .claudeignore (EXISTS ✅)
Each layer has a single, clear responsibility:
| Config | Question it answers | Scope |
|---|---|---|
| settings.json allowed_paths | WHERE is Claude allowed? | Folder-level boundary |
| .claudeignore | WHAT should Claude skip inside? | File/pattern filtering |
Neither overlaps. Together they provide complete, native, cross-platform access control.
---
How they work together in practice:
~/Projects/myapp/ ← allowed_paths boundary (Layer 1)
├── src/
│ ├── components/ ← Claude can see ✅
│ ├── utils/ ← Claude can see ✅
│ └── auth/ ← Claude can see ✅
├── node_modules/ ← blocked by .claudeignore ✅
├── dist/ ← blocked by .claudeignore ✅
└── *.log ← blocked by .claudeignore ✅
~/Documents/ ← blocked by allowed_paths ✅
~/.ssh/ ← blocked by allowed_paths ✅
~/OtherProject/ ← blocked by allowed_paths ✅
---
Design Principles
- Native — Claude enforces its own boundaries, no external tools needed
- Cross-platform — works identically on Linux, Mac, and Windows
- Simple — two config fields, no new concepts to learn
- Consistent — mirrors MCP
allowedDirectoriesalready used internally - Familiar —
.claudeignoresyntax already follows.gitignoreconvention - Complementary — does not replace
.claudeignore, completes it - Accessible — usable by hobby developers and non-technical users, not just experts
---
Precedent Already Exists Within Anthropic
The MCP Filesystem server already implements this exact concept:
{
"allowedDirectories": ["~/Projects"]
}
Bringing the same capability natively into Claude Code's settings.json is a natural, consistent, and already internally validated extension of this design.
Claude should be its own gatekeeper. Scope restriction is Claude's responsibility — not the operating system's. This feature puts that responsibility exactly where it belongs. 🔒
---
This ties everything together cleanly — the solution is simple, the design rationale is solid, and the precedent makes it hard to argue against. Ready to paste! 👏
Alternative Solutions
Current Workarounds (and Why They Are Inadequate)
Developers have attempted to solve this with OS-level sandboxing tools:
Linux:
# Rename real binary
mv /usr/local/bin/claude /usr/local/bin/_claude
# Create jailed wrapper
cat > /usr/local/bin/claude << 'EOF'
#!/bin/bash
firejail --whitelist=~/Projects _claude "$@"
EOF
chmod +x /usr/local/bin/claude
Mac:
sandbox-exec -f claude.sb claude
While these approaches work at the OS level, they are fundamentally the wrong solution because:
| Problem | Why It Matters |
|---|---|
| Platform-specific | firejail is Linux only, sandbox-exec is Mac only, no solution for Windows |
| Requires root/admin | Not available in corporate or restricted environments |
| Hack, not a feature | Brittle, breaks on Claude updates, requires maintenance |
| VS Code extension bypass | OS sandbox doesn't cleanly contain the VS Code extension's file access |
| Not user-friendly | Completely inaccessible to non-technical or hobby users |
| Invisible to Claude | Claude itself is unaware of the restriction — can cause unexpected errors |
---
Why This Must Be a Native Claude Feature
Scope restriction is fundamentally a Claude responsibility, not an OS responsibility. Claude is the agent accessing the files — Claude should know and respect its own boundaries natively.
The right place for this is ~/.claude/settings.json:
{
"allowed_paths": ["~/Projects/myapp/src"],
"deny_outside_scope": true
}
This approach is:
- ✅ Cross-platform — works identically on Linux, Mac, Windows
- ✅ Simple — one config change, no system tools needed
- ✅ Native — Claude enforces its own boundaries, no external hacks
- ✅ Consistent — same behavior in terminal AND VS Code extension
- ✅ Familiar — mirrors existing patterns like MCP
allowedDirectoriesand.gitignore - ✅ Accessible — hobby developers, retirees, non-technical users can use it
- ✅ Maintainable — survives Claude updates automatically
---
Precedent Already Exists
Anthropic has already implemented this thinking in other products. The MCP Filesystem server already accepts allowedDirectories:
{
"allowedDirectories": ["~/Projects"]
}
This proves the concept is sound and already accepted internally. Bringing the same capability natively to Claude Code's settings.json is a natural, consistent extension of this existing design.
Claude should be its own gatekeeper — not rely on the OS to do its job for it. 🔒
---
This framing makes a strong case: the jail approach proves the need is real, but clearly positions allowed_paths in settings.json as the correct, permanent, Claude-native solution. 👏
Priority
High - Significant impact on productivity
Feature Category
Developer tools/SDK
Use Case Example
Here are real-world use case examples to add to the request:
---
Use Case 1: Hobby Developer (your situation!)
User: Retired hobby developer, long daily coding sessions in VS Code
Project: ~/Projects/myapp/src
Problem: Claude started from home (~) reads entire file system.
Hits token limits quickly from irrelevant files being scanned.
Personal documents, photos, SSH keys all potentially exposed.
With allowed_paths: ["~/Projects/myapp/src"]
→ Claude only sees the project folder
→ Token usage drops significantly
→ Sensitive home directory files are never exposed
→ Pro plan ($20/month) limits last much longer
---
Use Case 2: Security-Conscious Developer
User: Developer working with credentials and API keys
Files: ~/.ssh/id_rsa, ~/.env, ~/.aws/credentials
Problem: No hard guarantee Claude won't accidentally read
sensitive credential files outside the project.
Deny rules in settings.json are known to be unreliable
(see issues #2162, #7246)
With allowed_paths: ["~/Projects/myapp"]
→ Credential files physically unreachable
→ No need to list every sensitive file in deny rules
→ Security enforced at scope level, not file level
---
Use Case 3: Multi-Project Developer
User: Developer with multiple active projects
Structure:
~/Projects/
├── client-a/ ← working on this today
├── client-b/ ← confidential, must not be mixed
└── personal/ ← private
Problem: When working on client-a, Claude can accidentally
read client-b or personal files.
No way to enforce project isolation.
With allowed_paths: ["~/Projects/client-a"]
→ Complete project isolation
→ Confidential client code never cross-contaminated
→ Switch projects by simply changing allowed_paths
---
Use Case 4: Team/Enterprise Environment
User: Admin managing Claude for a development team
Risk: Junior developers accidentally run Claude from ~
or wrong directory, exposing company codebase structure
Problem: No way to enforce safe defaults company-wide
via a shared settings.json policy.
Relies entirely on human discipline.
With allowed_paths in global settings.json:
→ Policy enforced for entire team automatically
→ New developers can't make dangerous mistakes
→ No training or discipline required — system enforces it
---
Summary Table to include in the request:
| Use Case | Current State | With allowed_paths |
|---|---|---|
| Hobby dev on Pro plan | Hits token limits fast | Limits last much longer |
| Credentials protection | Rely on deny rules (broken) | Hard scope boundary |
| Multi-project isolation | No enforcement | Complete isolation |
| Team policy | Human discipline only | Config-enforced automatically |
---
These examples make the feature request concrete and compelling — Anthropic can immediately see who benefits and why. 👏
___
Here's the updated use case section with that emphasis:
---
Current Workarounds (and Why They Are Inadequate)
Developers have attempted to solve this with OS-level sandboxing tools:
Linux:
# Rename real binary
mv /usr/local/bin/claude /usr/local/bin/_claude
# Create jailed wrapper
cat > /usr/local/bin/claude << 'EOF'
#!/bin/bash
firejail --whitelist=~/Projects _claude "$@"
EOF
chmod +x /usr/local/bin/claude
Mac:
sandbox-exec -f claude.sb claude
While these approaches work at the OS level, they are fundamentally the wrong solution because:
| Problem | Why It Matters |
|---|---|
| Platform-specific | firejail is Linux only, sandbox-exec is Mac only, no solution for Windows |
| Requires root/admin | Not available in corporate or restricted environments |
| Hack, not a feature | Brittle, breaks on Claude updates, requires maintenance |
| VS Code extension bypass | OS sandbox doesn't cleanly contain the VS Code extension's file access |
| Not user-friendly | Completely inaccessible to non-technical or hobby users |
| Invisible to Claude | Claude itself is unaware of the restriction — can cause unexpected errors |
---
Why This Must Be a Native Claude Feature
Scope restriction is fundamentally a Claude responsibility, not an OS responsibility. Claude is the agent accessing the files — Claude should know and respect its own boundaries natively.
The right place for this is ~/.claude/settings.json:
{
"allowed_paths": ["~/Projects/myapp/src"],
"deny_outside_scope": true
}
This approach is:
- ✅ Cross-platform — works identically on Linux, Mac, Windows
- ✅ Simple — one config change, no system tools needed
- ✅ Native — Claude enforces its own boundaries, no external hacks
- ✅ Consistent — same behavior in terminal AND VS Code extension
- ✅ Familiar — mirrors existing patterns like MCP
allowedDirectoriesand.gitignore - ✅ Accessible — hobby developers, retirees, non-technical users can use it
- ✅ Maintainable — survives Claude updates automatically
---
Precedent Already Exists
Anthropic has already implemented this thinking in other products. The MCP Filesystem server already accepts allowedDirectories:
{
"allowedDirectories": ["~/Projects"]
}
This proves the concept is sound and already accepted internally. Bringing the same capability natively to Claude Code's settings.json is a natural, consistent extension of this existing design.
Claude should be its own gatekeeper — not rely on the OS to do its job for it. 🔒
---
This framing makes a strong case: the jail approach proves the need is real, but clearly positions allowed_paths in settings.json as the correct, permanent, Claude-native solution. 👏
____
Additional Context
Great point! Here's the complementary section to add:
---
A Complete Two-Layer Control System
This feature does not exist in isolation — it completes a natural two-layer control system that Claude Code already has half of:
Layer 1: WHERE can Claude go? → settings.json (MISSING ❌)
Layer 2: WHAT can Claude see there? → .claudeignore (EXISTS ✅)
Currently only Layer 2 exists. Without Layer 1, .claudeignore is like having locks on the doors inside your house but no fence around the property.
---
How They Work Together
~/Projects/myapp/ ← allowed_paths boundary (Layer 1)
├── src/
│ ├── components/ ← Claude can see this
│ ├── utils/ ← Claude can see this
│ └── auth/ ← Claude can see this
├── node_modules/ ← blocked by .claudeignore (Layer 2)
├── dist/ ← blocked by .claudeignore (Layer 2)
├── *.log ← blocked by .claudeignore (Layer 2)
└── .env ← blocked by .claudeignore (Layer 2)
~/Documents/ ← blocked by allowed_paths (Layer 1)
~/ssh/ ← blocked by allowed_paths (Layer 1)
~/OtherProject/ ← blocked by allowed_paths (Layer 1)
---
Responsibilities Are Clean and Separate
| Config | Question it answers | Scope |
|---|---|---|
| settings.json allowed_paths | WHERE is Claude allowed? | Folder-level boundary |
| .claudeignore | WHAT should Claude skip inside? | File/pattern level filtering |
Each does one job. Neither overlaps. Together they give complete, layered control with minimal configuration.
---
Real World Example
// ~/.claude/settings.json
{
"allowed_paths": ["~/Projects/myapp"],
"deny_outside_scope": true
}
# ~/Projects/myapp/.claudeignore
# Block token-heavy noise
node_modules/
dist/
*.log
*.lock
package-lock.json
*.map
*.min.js
coverage/
.cache/
Result:
- Claude cannot leave
~/Projects/myapp← Layer 1 enforces this - Inside the project, Claude skips all irrelevant files ← Layer 2 enforces this
- Token usage drops dramatically
- Security is enforced at both levels
- Zero OS hacks required
---
Design Consistency
.claudeignore syntax is already familiar to any git user. allowed_paths in settings.json follows the same pattern as MCP allowedDirectories. Both are simple, declarative, and consistent with existing Claude and developer tooling conventions.
Together,allowed_pathsinsettings.jsonand.claudeignoreform a complete, native, cross-platform access control system — one that Claude owns and enforces itself, requiring no external tools, no OS configuration, and no technical expertise beyond editing a config file.
---
This framing positions your feature request as completing something already half-built — which makes it much harder for Anthropic to ignore! 👏
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗