How the Chachamaru claude-code-harness Permission System Prevents Unauthorized File Modifications
The claude-code-harness permission system employs a multi-layer defense architecture that intercepts, evaluates, and either blocks or prompts for approval before any file-modifying operation reaches the filesystem.
The Chachamaru127/claude-code-harness repository implements a robust security framework designed to prevent accidental or malicious file modifications during autonomous code generation. By combining declarative permission tables, sandboxed filesystem filters, and hook-based enforcement, this claude-code-harness permission system creates a defense-in-depth barrier that vets every tool invocation.
Multi-Layer Permission Architecture
The harness operates through four distinct enforcement layers that must all be satisfied before any write operation succeeds.
Permission Rules Layer
The foundation of the system resides in .claude-plugin/settings.json, where the permissions block defines three rule categories:
- Allow list: Automatically approves safe read-only commands like
Bash(git diff:*)【`.claude-plugin/settings.json#L7-L30】 - Deny list: Blocks destructive operations such as
Bash(sudo:*)andBash(rm -rf:*)【`.claude-plugin/settings.json#L31-L40】 - Ask list: Requires explicit user confirmation for risky but occasionally necessary actions like
Bash(git reset --hard:*)【`.claude-plugin/settings.json#L51-L58】
Sandbox File-system Filters
Before any file operation executes, the harness validates paths against the sandbox.filesystem configuration in the same settings file. The denyRead patterns prevent access to sensitive secrets including .env, **/*.pem, **/*.key, and **/.ssh/**【.claude-plugin/settings.json#L84-L96】, while allowRead explicitly permits benign documentation and configuration files【.claude-plugin/settings.json#L97-L102】.
Permission-Request Hooks
The active enforcement mechanism lives in .claude-plugin/hooks.json, where the PermissionRequest event intercepts any Write, Edit, or MultiEdit invocation. The hook matcher triggers the harness binary (_ hook permission) to evaluate rule tables against the requested operation【.claude-plugin/hooks.json#L63-L66】. For Bash commands, a comprehensive whitelist allows safe operations while routing unknown commands to the askordeny logic【.claude-plugin/hooks.json#L64-L66】.
Post-Tool Validation
After any successful write or edit, the PostToolUse hook executes an automated security scan【`.claude-plugin/hooks.json#L48-L55】. This review detects hard-coded credentials, TODO/FIXME stubs, and insecure patterns, potentially denying the operation even after initial permission approval.
Configuration Implementation
The claude-code-harness permission system relies on two primary configuration files that work in tandem:
.claude-plugin/settings.json contains:
- The
permissionsblock withallow,deny, andaskarrays - The
sandbox.filesystemsection withdenyReadandallowReadpatterns - The
sandbox.network.deniedDomainsarray blocking metadata services like169.254.169.254and data exfiltration sites likepastebin.com【`.claude-plugin/settings.json#L71-L82】
.claude-plugin/hooks.json defines:
PermissionRequestmatchers forWrite|Edit|MultiEditandBashoperationsPostToolUsehooks for security scanning- Execution targets that invoke the harness binary for policy evaluation
Permission Enforcement Examples
Example 1: Automatically Allowed Operation
Safe, read-only commands execute without interruption:
Bash(git diff:*)
Result: Matches the allow list; executes immediately.
[info] Running: git diff HEAD
Example 2: Explicitly Denied Operation
Destructive commands terminate with an error:
Bash(rm -rf:*)
Result: Matches the deny list; operation aborted.
[error] Permission denied: Bash(rm -rf:*) is prohibited by the policy.
Example 3: Confirmation Required
Potentially destructive but legitimate operations trigger user prompts:
Bash(git reset --hard:*)
Result: Falls under the ask category; requires explicit approval.
[request] Permission required: Bash(git reset --hard:*) – approve? (yes/no)
Example 4: Sandbox Blocked Write
Attempts to modify protected files fail at the filesystem layer:
{
"action": "Write",
"file": ".env"
}
Result: Blocked by denyRead policies (implicitly protecting secrets).
[error] Permission denied: Write to .env is prohibited (secret file).
Example 5: Validated Edit with Post-Review
Standard source modifications proceed through full validation:
{
"action": "Edit",
"file": "src/utils.ts"
}
Result: Passes permission check, executes edit, and undergoes security scan.
[info] Edit applied.
[review] No security issues detected.
Summary
The claude-code-harness permission system prevents unauthorized file modifications through:
- Declarative rules in
.claude-plugin/settings.jsonthat categorize operations as allow, deny, or ask - Sandbox filters that block access to secrets and sensitive paths before any read or write occurs
- Hook-based interception via
.claude-plugin/hooks.jsonthat evaluates every tool invocation against policy tables - Automated post-operation scanning that detects credentials and insecure patterns after edits complete
- Network restrictions that prevent data exfiltration to unauthorized domains
This layered approach ensures only vetted, non-destructive actions modify repository files while maintaining the flexibility required for autonomous development workflows.
Frequently Asked Questions
How does the claude-code-harness permission system differentiate between safe and dangerous Bash commands?
The system uses pattern matching in the permissions block of .claude-plugin/settings.json. Safe commands like Bash(git diff:*) appear in the allow array and execute automatically, while dangerous patterns like Bash(sudo:*) and Bash(rm -rf:*) reside in the deny array. Commands with potential risk but legitimate use cases, such as Bash(git reset --hard:*), live in the ask array and require explicit user confirmation before execution.
Can the permission system protect against writing secrets to files?
Yes. The sandbox.filesystem configuration includes denyRead patterns that treat files like .env, **/*.pem, and **/.ssh/** as protected resources. Additionally, the PostToolUse hook in .claude-plugin/hooks.json executes automated scans after any write operation to detect hard-coded credentials, TODO markers, or insecure patterns, potentially rejecting the change even if initial permission was granted.
What happens if a tool invocation does not match any specific permission rule?
Unmatched commands fall through the permission layers according to the hook logic in .claude-plugin/hooks.json. For Bash operations, the whitelist explicitly covers safe commands; anything outside that range routes to the ask or deny logic depending on the risk profile. For file operations (Write, Edit, MultiEdit), the harness binary (_ hook permission) evaluates against the rule tables and defaults to blocking or prompting if no explicit allowance exists.
Where are the network restrictions configured in claude-code-harness?
Network controls reside in .claude-plugin/settings.json under the sandbox.network.deniedDomains array. This configuration blocks access to internal metadata services like 169.254.169.254 and public paste sites like pastebin.com to prevent data exfiltration【`.claude-plugin/settings.json#L71-L82】. These restrictions apply to all network operations initiated by the agent, creating an additional security boundary beyond file-system protections.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →