Security sandbox for autonomous coding. Use when validating commands, configuring permissions, managing allowlists, or ensuring safe execution.
Resources
1Install
npx skillscat add adaptationio/skrillz/ac-security-sandbox Install via the SkillsCat registry.
About this skill
This skill provides a security sandbox for autonomous code execution, enforcing isolation, restricted permissions, and command allowlisting. It prevents unauthorized access, system modifications, and unsafe operations by validating commands and limiting filesystem interactions. Use it when executing untrusted code, configuring security policies, or managing restricted environments.
SKILL.md
AC Security Sandbox
Defense-in-depth security for autonomous code execution.
Overview
Provides three layers of security:
- OS-Level Sandbox: Isolated execution environment
- Filesystem Permissions: Restricted path access
- Command Allowlist: Pre-approved commands only
Quick Start
Validate Command
from scripts.security_sandbox import SecuritySandbox
sandbox = SecuritySandbox(project_dir)
# Check if command is allowed
is_safe, reason = sandbox.validate_command("npm install")
if is_safe:
# Execute command
pass
else:
print(f"Blocked: {reason}")Configure Allowlist
sandbox.configure_allowlist([
"ls", "cat", "head", "tail",
"npm", "node", "python",
"git", "grep"
])Security Layers
Layer 1: OS-Level Sandbox
# Enable sandbox mode
sandbox_config = {
"enabled": True,
"isolation": "strict",
"network": "restricted"
}Layer 2: Filesystem Permissions
permissions = {
"allow": [
"Read(./**)", # Read project files
"Write(./**)", # Write project files
"Edit(./**)", # Edit project files
],
"deny": [
"Read(/etc/**)", # No system files
"Write(/usr/**)", # No system writes
"Bash(rm -rf /)", # No destructive commands
]
}Layer 3: Command Allowlist
ALLOWED_COMMANDS = {
# File inspection
"ls", "cat", "head", "tail", "wc", "grep", "find",
# File operations
"cp", "mv", "mkdir", "chmod", "touch",
# Node.js
"npm", "node", "npx", "yarn", "pnpm",
# Python
"python", "python3", "pip", "pip3",
# Version control
"git",
# Process management
"ps", "lsof", "sleep", "pkill",
# Build tools
"make", "cmake", "cargo", "go",
# Testing
"jest", "pytest", "vitest", "playwright"
}Command Validation
Pre-Tool-Use Hook
async def bash_security_hook(input_data, tool_use_id, context):
command = input_data.get("tool_input", {}).get("command", "")
# Extract all commands (handles pipes, &&, etc.)
commands = extract_commands(command)
for cmd in commands:
if cmd not in ALLOWED_COMMANDS:
return {
"decision": "block",
"reason": f"Command '{cmd}' not in allowlist"
}
return {} # Allow executionCommand Extraction
def extract_commands(command: str) -> list[str]:
"""
Extract base commands from complex command strings.
Examples:
"npm install && npm test" → ["npm", "npm"]
"cat file.txt | grep error" → ["cat", "grep"]
"git add . && git commit -m 'msg'" → ["git", "git"]
"""
# Parse command string
# Handle: pipes (|), chains (&&, ||), semicolons (;)
# Return list of base command namesBlocked Command Patterns
Always Blocked
DANGEROUS_PATTERNS = [
r"rm\s+-rf\s+/", # Recursive delete root
r"dd\s+if=", # Direct disk writes
r"mkfs", # Format filesystems
r":(){ :|:& };:", # Fork bombs
r"chmod\s+777", # Overly permissive
r"curl.*\|\s*bash", # Pipe to shell
r"wget.*\|\s*sh", # Pipe to shell
]Context-Dependent
# Allowed in project directory only
RESTRICTED_COMMANDS = {
"rm": lambda path: path.startswith("./"),
"mv": lambda src, dst: src.startswith("./") and dst.startswith("./"),
"cp": lambda src, dst: dst.startswith("./"),
}Configuration
.claude/security-config.json
{
"sandbox": {
"enabled": true,
"isolation": "strict"
},
"permissions": {
"filesystem": {
"read": ["./**", "~/.config/claude/**"],
"write": ["./**"],
"deny": ["/etc/**", "/usr/**", "~/.ssh/**"]
},
"network": {
"allow": ["localhost", "api.anthropic.com"],
"deny": ["*"]
}
},
"allowlist": {
"commands": ["npm", "node", "git", "python"],
"custom": []
}
}Operations
1. Initialize Sandbox
sandbox = SecuritySandbox(project_dir)
await sandbox.initialize()
# Loads config, sets up hooks2. Validate Command
is_safe, reason = sandbox.validate_command(command)
# Returns (True, None) or (False, "reason")3. Validate Path
is_allowed = sandbox.validate_path(path, operation="write")
# Checks against filesystem permissions4. Register Hook
hook = sandbox.create_pre_tool_hook()
# Returns hook function for Claude SDK5. Add Custom Command
sandbox.add_allowed_command("my-custom-tool")
# Adds to allowlist (persists to config)6. Audit Log
# Get recent security events
events = sandbox.get_audit_log(limit=100)
for event in events:
print(f"{event.timestamp}: {event.action} - {event.command}")Audit Logging
All security decisions are logged:
// .claude/security-audit.jsonl
{"timestamp": "2025-01-15T10:00:00Z", "action": "ALLOW", "command": "npm install", "reason": null}
{"timestamp": "2025-01-15T10:01:00Z", "action": "BLOCK", "command": "rm -rf /", "reason": "Dangerous pattern"}
{"timestamp": "2025-01-15T10:02:00Z", "action": "ALLOW", "command": "git commit", "reason": null}Best Practices
DO
- Start with minimal allowlist
- Add commands as needed
- Review audit logs regularly
- Use project-relative paths
DON'T
- Allow
sudocommands - Allow system path writes
- Disable sandbox in production
- Ignore blocked command logs
Integration Points
- ac-session-manager: Provides security hooks
- ac-build-runner: Validates build commands
- ac-coder-agent: Restricts agent commands
- ac-config-manager: Loads security config
References
references/ALLOWLIST.md- Complete command listreferences/PATTERNS.md- Blocked patternsreferences/AUDIT.md- Audit log format
Scripts
scripts/security_sandbox.py- Core SecuritySandboxscripts/command_validator.py- Command validationscripts/path_validator.py- Path validationscripts/audit_logger.py- Security audit logging