Permission modes
The active mode is set via--permission-mode on the CLI or the permission_mode field in settings.
| Mode | Rust variant | Behaviour |
|---|---|---|
| Default (interactive) | PermissionMode::Default | Read-only operations run automatically. All write and execute operations prompt the user. |
| AcceptEdits | PermissionMode::AcceptEdits | All operations — including writes and edits — run automatically. |
| BypassPermissions | PermissionMode::BypassPermissions | Every permission check returns Allow immediately; no prompts are shown. Use only in trusted automation contexts. |
| Plan | PermissionMode::Plan | Read-only planning mode. Only tools with is_read_only == true are permitted; all others are denied. |
auto permission mode referenced in the TypeScript source uses an ML-based transcript classifier to approve tool calls automatically. In Claurst this maps to AcceptEdits for tool execution purposes — the classifier infrastructure is not part of the clean-room implementation.
Permission categories
Every permission check is associated with one of these categories, which map directly to the tool types that trigger them:| Category | Tools that use it |
|---|---|
Bash | BashTool, PowerShellTool |
FileRead | FileReadTool, GlobTool, GrepTool |
FileEdit | FileEditTool, NotebookEditTool |
FileWrite | FileWriteTool |
WebFetch | WebFetchTool, WebSearchTool |
MCP | ListMcpResourcesTool, ReadMcpResourceTool, and dynamically registered MCP tools |
Sandbox | Sandboxed execution contexts |
How the AutoPermissionHandler works
AutoPermissionHandler is the non-interactive handler used in headless and scripted runs. It implements the PermissionHandler trait:
PermissionHandler surfaces a dialog to the user and waits for a y/n response before returning a decision.
Layered settings
Permission rules are stored in JSON settings files. The files are read in priority order — the highest-priority source wins:Managed / enterprise settings (read-only)
Deployed by an organisation’s device management system. Users cannot override these rules. Equivalent to a policy layer.
Local project: .claude/settings.local.json
Machine-local settings for the current project. This file should be added to
.gitignore. Suitable for developer-specific overrides that should not be shared with the team.Project: .claude/settings.json
Shared project settings checked into source control. Suitable for project-wide permission rules that every contributor should use.
Settings struct in cc-core handles loading and saving:
Example settings.json permission rule configuration
ToolName(pattern). Patterns support glob matching against the tool’s input.
Risk classification
Every tool action is internally classified as LOW, MEDIUM, or HIGH risk. This classification drives the auto-permission decision and determines what information the permission explainer surfaces to the user.| Risk level | Examples |
|---|---|
| LOW | Read, Glob, Grep, WebFetch, ToolSearch |
| MEDIUM | Edit, Write, NotebookEdit, WebSearch |
| HIGH | Bash, PowerShell, Task (sub-agents) |
Protected files
The following files resist automatic editing. Any tool call that would write to these paths requires explicit user approval, even inAcceptEdits mode:
.gitconfig.bashrc.zshrc.mcp.json.claude.json
execute() method is called.
Path traversal prevention
Claurst’s memory path validation (validateMemoryPath()) and team memory write validation (validateTeamMemWritePath()) guard against path traversal attacks using several techniques:
URL-encoded traversal detection — Patterns like %2e%2e%2f (URL-encoded ../) are detected and rejected before path resolution.
Unicode normalization attacks — Fullwidth characters such as ../ normalise to ../ under NFC. Paths are normalised before comparison.
Backslash injection — Backslashes in path keys are rejected regardless of platform.
Absolute path rejection — Relative paths to the memory directory must not start with /.
Two-pass symlink validation — validateTeamMemWritePath() first uses path::resolve() to eliminate .. segments, then follows symlinks using realpathDeepestExisting() to verify that the real filesystem path is still inside the permitted directory. Symlink loops (ELOOP) and dangling symlinks are handled explicitly.
Null byte rejection — Null bytes in path keys are rejected before any filesystem operation.