CC
Claude Code
v2.1.88
Claude CodePermissions Module

Permissions Module

30 files · ~20K lines

5 Layers Between You and Disaster — permission modes, rule matching, filesystem allowlists, and the yoloClassifier: an AI that asks AI whether a bash command is safe.

The 5-Layer Security Funnel

Every tool call passes through 5 narrowing layers. Each layer is more specific and can veto the call. Most calls are stopped before reaching layer 5.

1
Mode Check
bypassPermissions → skip user prompt. default → show dialog.
2
Session Rules
Rule match → auto-approve. No match → continue to layer 3.
3
AST Analysis (yoloClassifier)
HIGH RISK → blocked with explanation. LOW RISK → continue to layer 4.
4
Path Allowlist
Path outside roots → BLOCKED. Path inside roots → continue to layer 5.
5
User Prompt
User decides: allow (once or always) or deny.
BLOCKED or ALLOWED

Layer 1: Is the session in default, acceptEdits, or bypassPermissions mode? Mode determines whether a dialog is shown at all.

Layer 2: Has the user already approved this tool/command pattern in this session? Stored as PermissionRule objects in LoopState.

Layer 3: bashParser.ts builds a Tree-sitter AST of the command. Pattern classifier detects recursive deletes, root path access, network calls, injection chains.

Layer 4: File paths are validated against the project root allowlist. Paths outside allowed roots are blocked — even in bypassPermissions mode.

Layer 5: A terminal dialog renders in the REPL: Allow once / Always allow / Never. The user decides. 'Always allow' stores a new PermissionRule in session state.

Hall of Fame: Best Variable Names in Production Code

There is a function in production Claude Code literally called yoloClassifier. Here's what it actually does.

yoloClassifierutils/permissions/yoloClassifier.ts · ~8KB

When Claude Code runs headlessly (CI mode, --dangerously-skip-permissions), it can't ask a human for permission. Instead, yoloClassifier sends the bash command to the Claude API with a safety assessment prompt. Claude-asking-Claude decides if it's safe. The name is literally in the source code.

Why 'yolo'?
You Only Live Once
It runs when you've already said 'skip all checks'
Input
bash command string
Process
Claude API safety assessment
Output
allow / block + reason

Permission Modes — Risk Spectrum

6 modes from safest to most dangerous. Each removes one or more security layers.

SafeDangerous
default

Normal mode — all 5 layers active. User dialogs shown for every novel tool action.

acceptEdits

Auto-approves file edits. Still prompts for bash commands, network, and destructive ops.

autoAccept

Accepts most tool calls automatically. Skips session-rule layer. Destructive ops still prompt.

plan

Planning mode — Claude describes actions but doesn't execute them without explicit approval.

bypassPermissions

Skips user dialogs. yoloClassifier still runs. Path allowlist still enforced. Intended for CI pipelines.

dangerouslySkipPermissions

All permission checks disabled. No classifier. No path check. Only use in fully sandboxed environments.

rm -rf / Walkthrough — All 5 Layers

The LLM generates BashTool('rm -rf /'). Here is what happens before a single byte is deleted.

1
Mode Check

Is the session in default, acceptEdits, or bypassPermissions mode? Mode determines whether a dialog is shown at all.

bypassPermissions → skip user prompt. default → show dialog.
2
Session Rules

Has the user already approved this tool/command pattern in this session? Stored as PermissionRule objects in LoopState.

Rule match → auto-approve. No match → continue to layer 3.
3
AST Analysis (yoloClassifier)

bashParser.ts builds a Tree-sitter AST of the command. Pattern classifier detects recursive deletes, root path access, network calls, injection chains.

HIGH RISK → blocked with explanation. LOW RISK → continue to layer 4.
4
Path Allowlist

File paths are validated against the project root allowlist. Paths outside allowed roots are blocked — even in bypassPermissions mode.

Path outside roots → BLOCKED. Path inside roots → continue to layer 5.
5
User Prompt

A terminal dialog renders in the REPL: Allow once / Always allow / Never. The user decides. 'Always allow' stores a new PermissionRule in session state.

User decides: allow (once or always) or deny.
Result: Layer 3 (AST analysis) detects recursive delete + root path. Layer 4 (path allowlist) confirms '/' is outside all allowed roots. The command is blocked before layer 5 is ever reached.

Permission Rule Matching — 4 Types

When a user clicks 'Always allow', a rule is stored. Future calls match against these rules in priority order.

Exactgit commit -m 'fix'

Full string equality. Fastest check.

Prefixgit commit

Matches if the command starts with this string. Covers variants like git commit -am, git commit --amend.

Glob / Wildcardgit *

Shell glob patterns. * matches any sequence. Covers git pull, git push, git rebase, etc.

Tool PatternFileEdit:src/**

Tool name + path glob. Approves FileEdit for any path under src/, but not outside it.

3 Security Vulnerabilities Patched (HackerOne)

Real vulnerabilities found and patched in production. The permission system was hardened after responsible disclosure.

H1-1
Path Traversal via Symlink

A symlink inside the allowed root could point outside it. The fix: resolve real paths via fs.realpath() before allowlist comparison.

H1-2
Injection via Tool Description

Malicious MCP server tool descriptions could inject instructions to the LLM. The fix: sanitize tool descriptions before they enter the system prompt.

H1-3
Permission Rule Bypass via Unicode

Unicode lookalike characters in file paths could fool exact/prefix matching. The fix: normalize paths to NFC before rule comparison.

Key Files

utils/permissions/yoloClassifier.ts~8KB

ML classifier that uses AI to auto-approve bash commands — literally named 'yolo'

hooks/toolPermission/~12KB

React hooks for tool approval UI — renders permission dialogs in terminal

utils/permissions/~25KB

Permission rule parsing, filesystem path allowlists, mode definitions

utils/permissions/pathPermissions.ts~6KB

Filesystem path checks — resolves globs, validates against allowed roots

utils/permissions/permissionRules.ts~5KB

Permission rule DSL: tool name patterns, command patterns, path patterns