# Permission System

The permission system is critical for safety. It controls what the agent can do, when it needs approval, and how to sandbox dangerous operations.

## Design Goals

- **Safety by default** - Require approval for potentially harmful actions
- **User control** - Let users decide what to allow
- **Granular** - Control per-tool, per-command, per-path
- **Transparent** - Show what will happen before execution
- **Flexible** - Support different modes (interactive, auto-approve safe, etc.)
- **Auditable** - Log all permission decisions

## Permission Models

| Model | Description | Use Case |
|---|---|---|
| **Interactive** | Ask for approval on each sensitive action | Default, safest |
| **Allowlist** | Auto-approve specific tools/commands/paths | Trusted workflows |
| **Denylist** | Block specific dangerous patterns | Blacklist known bad |
| **YOLO/Trust All** | Auto-approve everything | Sandboxed environments only |
| **Plan Mode** | Read-only, plan only | Exploration, code review |
| **Subagent Mode** | Inherit or restricted permissions | Isolated tasks |

## Risk Classification

| Risk Level | Tools/Actions | Default Behavior |
|---|---|---|
| **Low** | read_file, glob, grep, list_dir, websearch | Auto-approve |
| **Medium** | write_file, edit, git add/commit, webfetch | Usually ask or need approval |
| **High** | bash/shell, rm, git push, browser automation | Always ask by default |
| **Critical** | System commands, sudo, network config, secrets access | Block or require explicit confirmation |

## Permission Flow

```mermaid
graph TD
    A[Tool Call Requested] --> B{Check Allowlist}
    B -->|Allowed| C[Execute]
    B -->|Not Allowed| D{Check Risk Level}
    D -->|Low| E{Check Mode}
    D -->|Medium/High| F[Ask User]
    E -->|Auto-approve Low| C
    E -->|Interactive| F
    F -->|Approve Once| C
    F -->|Approve Always| G[Add to Allowlist]
    F -->|Deny| H[Reject with Message]
    G --> C
    
    style C fill:#e8f5e9
    style H fill:#ffcdd2
    style F fill:#fff3e0
```

## Permission Rules

Rules can be defined at multiple levels:

```typescript
interface PermissionRule {
  type: 'allow' | 'deny' | 'ask';
  tool?: string;      // Specific tool or wildcard
  command?: string;   // For shell, regex pattern
  path?: string;      // For filesystem, glob pattern
  description?: string;
}
```

### Example Rules

```yaml
permissions:
  rules:
    - type: allow
      tool: read_file
    - type: allow
      tool: grep
    - type: allow
      tool: glob
    - type: ask
      tool: write_file
    - type: ask
      tool: edit
    - type: ask
      tool: bash
    - type: deny
      tool: bash
      command: "rm -rf /"
    - type: ask
      tool: bash
      command: "git push*"
```

## Shell Command Analysis

For bash/shell commands, parse and analyze for safety:

```python
DANGEROUS_PATTERNS = [
    r"rm\s+-rf\s+/",      # Delete everything
    r"curl.*\|\s*sh",     # Pipe curl to shell
    r"wget.*\|\s*sh",     # Pipe wget to shell
    r"sudo",              # Privilege escalation
    r"chmod\s+777",       # Overly permissive
    r"mkfs",              # Format disk
    r"dd\s+if=",          # Disk operations
]

def analyze_command(cmd: str) -> RiskLevel:
    for pattern in DANGEROUS_PATTERNS:
        if re.search(pattern, cmd):
            return RiskLevel.CRITICAL
    # Check for other risky operations
    ...
    return RiskLevel.HIGH
```

## Filesystem Path Restrictions

Prevent escaping the project directory:

```python
def validate_path(path: str, working_dir: str) -> bool:
    resolved = os.path.realpath(os.path.join(working_dir, path))
    wd_resolved = os.path.realpath(working_dir)
    # Must be within working directory
    if not resolved.startswith(wd_resolved + os.sep) and resolved != wd_resolved:
        raise PermissionError("Path outside working directory")
    # Check for sensitive paths
    if is_sensitive_path(resolved):
        raise PermissionError("Access to sensitive path denied")
    return True
```

## User Approval UI

When asking for permission, show clear information:

```
Permission required

Tool: bash
Command: npm install express
Risk: Medium
Working directory: /home/user/project

This command will:
- Download and install packages from npm registry
- Modify node_modules/ and package-lock.json

[Allow once] [Allow for this session] [Allow always] [Deny]
```

## Session-Based Permissions

Track approvals within a session:

```typescript
interface SessionPermissions {
  allowedTools: Set<string>;
  allowedCommands: Array<{pattern: RegExp, count: number}>;
  allowedPaths: Set<string>;
  autoApproveLowRisk: boolean;
  planMode: boolean;
}
```

## Sub-Agent Permissions

Sub-agents can have different permission profiles:

| Profile | Description |
|---|---|
| **Inherit** | Same permissions as parent |
| **Restricted** | Read-only, no shell |
| **Task-Specific** | Only tools needed for the task |
| **Sandboxed** | Completely isolated with minimal permissions |

## Sandboxing Strategies

| Strategy | Level | Use Case |
|---|---|---|
| **Directory Restriction** | Filesystem | Limit to project directory |
| **Command Filtering** | Shell | Block dangerous commands |
| **Container/VM** | Full isolation | Untrusted code execution |
| **Bubblewrap/firejail** | OS-level | Linux sandboxing |
| **Docker/Podman** | Container | Isolated environments |
| **WASM** | Language-level | Sandboxed code execution |

## Audit Logging

Log all permission decisions:

```json
{
  "timestamp": "2024-01-15T10:30:00Z",
  "sessionId": "ses_123",
  "tool": "bash",
  "args": {"command": "git commit -m 'fix'"},
  "riskLevel": "medium",
  "decision": "approved",
  "approvedBy": "user",
  "duration": 150
}
```

## Best Practices

1. **Default deny for high-risk** - Better to ask than regret
2. **Be specific in prompts** - Show exactly what will happen
3. **Allow session-level approval** - Reduce friction for repeated safe actions
4. **Support plan mode** - Let users review before executing
5. **Clear deny messages** - Explain why something was blocked
6. **Respect .gitignore patterns** - Don't modify ignored files carelessly
7. **Handle secrets carefully** - Never log sensitive values
8. **Provide escape hatch** - Allow advanced users to configure

## Configuration

Users can configure permissions in settings:

```json
{
  "permissions": {
    "mode": "interactive",
    "autoApprove": ["read_file", "glob", "grep"],
    "deny": ["rm -rf /*"],
    "requireApproval": ["bash", "write_file"],
    "workingDirectoryOnly": true
  }
}
```

## Related Notes

- [[Tool-Registry.md]] — Tool system integration
- [[../Integration/Shell-Integration.md]] — Shell safety
- [[../Integration/Filesystem-Integration.md]] — Filesystem restrictions
- [[../Production/Security.md]] — Broader security
- [[../Building-A-Harness/Minimal-Harness.md]] — Implementation

## Sources

* Claude Code permissions documentation  
* OpenCode security model  
* Principle of Least Privilege (NIST)  
* OWASP Secure Coding Practices  
* Container security best practices  
