Implement hierarchical command security with project and org-level configs:
WHAT'S NEW:
- Project-level YAML config (.autocoder/allowed_commands.yaml)
- Organization-level config (~/.autocoder/config.yaml)
- Pattern matching (exact, wildcards, local scripts)
- Hardcoded blocklist (sudo, dd, shutdown - never allowed)
- Org blocklist (terraform, kubectl - configurable)
- Helpful error messages with config hints
- Comprehensive documentation and examples
ARCHITECTURE:
- Hierarchical resolution: Hardcoded → Org Block → Org Allow → Global → Project
- YAML validation with 50 command limit per project
- Pattern matching: exact ("swift"), wildcards ("swift*"), scripts ("./build.sh")
- Secure by default: all examples commented out
TESTING:
- 136 unit tests (pattern matching, YAML, hierarchy, validation)
- 9 integration tests (real security hook flows)
- All tests passing, 100% backward compatible
DOCUMENTATION:
- examples/README.md - comprehensive guide with use cases
- examples/project_allowed_commands.yaml - template (all commented)
- examples/org_config.yaml - org config template (all commented)
- PHASE3_SPEC.md - mid-session approval spec (future enhancement)
- Updated CLAUDE.md with security model documentation
USE CASES:
- iOS projects: Add Swift toolchain (xcodebuild, swift*, etc.)
- Rust projects: Add cargo, rustc, clippy
- Enterprise: Block aws, kubectl, terraform org-wide
- Custom scripts: Allow ./scripts/build.sh
PHASES:
✅ Phase 1: Project YAML + blocklist (implemented)
✅ Phase 2: Org config + hierarchy (implemented)
📋 Phase 3: Mid-session approval (spec ready, not implemented)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
14 KiB
AutoCoder Security Configuration Examples
This directory contains example configuration files for controlling which bash commands the autonomous coding agent can execute.
Table of Contents
- Quick Start
- Project-Level Configuration
- Organization-Level Configuration
- Command Hierarchy
- Pattern Matching
- Common Use Cases
- Security Best Practices
Quick Start
For a Single Project (Most Common)
When you create a new project with AutoCoder, it automatically creates:
my-project/
.autocoder/
allowed_commands.yaml ← Automatically created from template
Edit this file to add project-specific commands (Swift tools, Rust compiler, etc.).
For All Projects (Organization-Wide)
If you want commands available across all projects, manually create:
# Copy the example to your home directory
cp examples/org_config.yaml ~/.autocoder/config.yaml
# Edit it to add org-wide commands
nano ~/.autocoder/config.yaml
Project-Level Configuration
File: {project_dir}/.autocoder/allowed_commands.yaml
Purpose: Define commands needed for THIS specific project.
Example (iOS project):
version: 1
commands:
- name: swift
description: Swift compiler
- name: xcodebuild
description: Xcode build system
- name: swift*
description: All Swift tools (swiftc, swiftlint, swiftformat)
- name: ./scripts/build.sh
description: Project build script
When to use:
- ✅ Project uses a specific language toolchain (Swift, Rust, Go)
- ✅ Project has custom build scripts
- ✅ Temporary tools needed during development
Limits:
- Maximum 50 commands per project
- Cannot override org-level blocked commands
- Cannot allow hardcoded blocklist commands (sudo, dd, etc.)
See: examples/project_allowed_commands.yaml for full example with Rust, Python, iOS, etc.
Organization-Level Configuration
File: ~/.autocoder/config.yaml
Purpose: Define commands and policies for ALL projects.
Example (startup team):
version: 1
# Available to all projects
allowed_commands:
- name: jq
description: JSON processor
- name: python3
description: Python interpreter
# Blocked across all projects (cannot be overridden)
blocked_commands:
- aws
- kubectl
- terraform
When to use:
- ✅ Multiple projects need the same tools (jq, python3, etc.)
- ✅ Enforce organization-wide security policies
- ✅ Block dangerous commands across all projects
See: examples/org_config.yaml for full example with enterprise/startup configurations.
Command Hierarchy
When the agent tries to run a command, the system checks in this order:
┌─────────────────────────────────────────────────────┐
│ 1. HARDCODED BLOCKLIST (highest priority) │
│ sudo, dd, shutdown, reboot, chown, etc. │
│ ❌ NEVER allowed, even with user approval │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 2. ORG BLOCKLIST (~/.autocoder/config.yaml) │
│ Commands you block organization-wide │
│ ❌ Projects CANNOT override these │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 3. ORG ALLOWLIST (~/.autocoder/config.yaml) │
│ Commands available to all projects │
│ ✅ Automatically available │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 4. GLOBAL ALLOWLIST (security.py) │
│ Default commands: npm, git, curl, ls, cat, etc. │
│ ✅ Always available │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 5. PROJECT ALLOWLIST (.autocoder/allowed_commands) │
│ Project-specific commands │
│ ✅ Available only to this project │
└─────────────────────────────────────────────────────┘
Key Rules:
- If a command is BLOCKED at any level above, it cannot be allowed below
- If a command is ALLOWED at any level, it's available (unless blocked above)
- Blocklist always wins over allowlist
Pattern Matching
You can use patterns to match multiple commands:
Exact Match
- name: swift
description: Swift compiler only
Matches: swift
Does NOT match: swiftc, swiftlint
Prefix Wildcard
- name: swift*
description: All Swift tools
Matches: swift, swiftc, swiftlint, swiftformat
Does NOT match: npm, rustc
Local Scripts
- name: ./scripts/build.sh
description: Build script
Matches:
./scripts/build.shscripts/build.sh/full/path/to/scripts/build.sh- Running
build.shfrom any directory (matched by filename)
Common Use Cases
iOS Development
Project config (.autocoder/allowed_commands.yaml):
version: 1
commands:
- name: swift*
description: All Swift tools
- name: xcodebuild
description: Xcode build system
- name: xcrun
description: Xcode tools runner
- name: simctl
description: iOS Simulator control
Rust CLI Project
Project config:
version: 1
commands:
- name: cargo
description: Rust package manager
- name: rustc
description: Rust compiler
- name: rustfmt
description: Rust formatter
- name: clippy
description: Rust linter
- name: ./target/debug/my-cli
description: Debug build
- name: ./target/release/my-cli
description: Release build
API Testing Project
Project config:
version: 1
commands:
- name: jq
description: JSON processor
- name: httpie
description: HTTP client
- name: ./scripts/test-api.sh
description: API test runner
Enterprise Organization (Restrictive)
Org config (~/.autocoder/config.yaml):
version: 1
allowed_commands:
- name: jq
description: JSON processor
blocked_commands:
- aws # No cloud access
- gcloud
- az
- kubectl # No k8s access
- terraform # No infrastructure changes
- psql # No production DB access
- mysql
Startup Team (Permissive)
Org config (~/.autocoder/config.yaml):
version: 1
allowed_commands:
- name: python3
description: Python interpreter
- name: jq
description: JSON processor
- name: pytest
description: Python tests
blocked_commands: [] # Rely on hardcoded blocklist only
Security Best Practices
✅ DO
-
Start restrictive, add as needed
- Begin with default commands only
- Add project-specific tools when required
- Review the agent's blocked command errors to understand what's needed
-
Use org-level config for shared tools
- If 3+ projects need
jq, add it to org config - Reduces duplication across project configs
- If 3+ projects need
-
Block dangerous commands at org level
- Prevent accidental production deployments (
kubectl,terraform) - Block cloud CLIs if appropriate (
aws,gcloud,az)
- Prevent accidental production deployments (
-
Use descriptive command names
- Good:
description: "Swift compiler for iOS builds" - Bad:
description: "Compiler"
- Good:
-
Prefer patterns for tool families
swift*instead of listingswift,swiftc,swiftlintseparately- Automatically includes future tools (e.g., new Swift utilities)
❌ DON'T
-
Don't add commands "just in case"
- Only add when the agent actually needs them
- Empty config is fine - defaults are usually enough
-
Don't try to allow blocklisted commands
- Commands like
sudo,dd,shutdowncan NEVER be allowed - The system will reject these in validation
- Commands like
-
Don't use org config for project-specific tools
- Bad: Adding
xcodebuildto org config when only one project uses it - Good: Add
xcodebuildto that project's config
- Bad: Adding
-
Don't exceed the 50 command limit per project
- If you need more, you're probably being too specific
- Use wildcards instead:
npm-*covers many npm tools
-
Don't ignore validation errors
- If your YAML is rejected, fix the structure
- Common issues: missing
version, malformed lists, over 50 commands
Default Allowed Commands
These commands are always available to all projects:
File Operations:
ls,cat,head,tail,wc,grep,cp,mkdir,mv,rm,touch
Shell:
pwd,echo,sh,bash,sleep
Version Control:
git
Process Management:
ps,lsof,kill,pkill(dev processes only: node, npm, vite)
Network:
curl
Node.js:
npm,npx,pnpm,node
Docker:
docker
Special:
chmod(only+xmode for making scripts executable)
Hardcoded Blocklist
These commands are NEVER allowed, even with user approval:
Disk Operations:
dd,mkfs,fdisk,parted
System Control:
shutdown,reboot,poweroff,halt,init
Privilege Escalation:
sudo,su,doas
System Services:
systemctl,service,launchctl
Network Security:
iptables,ufw
Ownership Changes:
chown,chgrp
Dangerous Commands (Phase 3 will add approval):
aws,gcloud,az,kubectl,docker-compose
Troubleshooting
Error: "Command 'X' is not allowed"
Solution: Add the command to your project config:
# In .autocoder/allowed_commands.yaml
commands:
- name: X
description: What this command does
Error: "Command 'X' is blocked at organization level"
Cause: The command is in the org blocklist or hardcoded blocklist.
Solution:
- If in org blocklist: Edit
~/.autocoder/config.yamlto remove it - If in hardcoded blocklist: Cannot be allowed (by design)
Error: "Could not parse YAML config"
Cause: YAML syntax error.
Solution: Check for:
- Missing colons after keys
- Incorrect indentation (use 2 spaces, not tabs)
- Missing quotes around special characters
Config not taking effect
Solution:
- Restart the agent (changes are loaded on startup)
- Verify file location:
- Project:
{project}/.autocoder/allowed_commands.yaml - Org:
~/.autocoder/config.yaml(must be manually created)
- Project:
- Check YAML is valid (run through a YAML validator)
Testing
Running the Tests
AutoCoder has comprehensive tests for the security system:
Unit Tests (136 tests - fast):
source venv/bin/activate
python test_security.py
Tests:
- Pattern matching (exact, wildcards, scripts)
- YAML loading and validation
- Blocklist enforcement
- Project and org config hierarchy
- All existing security validations
Integration Tests (9 tests - uses real security hooks):
source venv/bin/activate
python test_security_integration.py
Tests:
- Blocked commands are rejected (sudo, shutdown, etc.)
- Default commands work (ls, git, npm, etc.)
- Non-allowed commands are blocked (wget, python, etc.)
- Project config allows commands (swift, xcodebuild, etc.)
- Pattern matching works (swift* matches swiftlint)
- Org blocklist cannot be overridden
- Org allowlist is inherited by projects
- Invalid YAML is safely ignored
- 50 command limit is enforced
Manual Testing
To manually test the security system:
1. Create a test project:
python start.py
# Choose "Create new project"
# Name it "security-test"
2. Edit the project config:
# Navigate to the project directory
cd path/to/security-test
# Edit the config
nano .autocoder/allowed_commands.yaml
3. Add a test command (e.g., Swift):
version: 1
commands:
- name: swift
description: Swift compiler
4. Run the agent and observe:
- Try a blocked command:
"Run sudo apt install nginx"→ Should be blocked - Try an allowed command:
"Run ls -la"→ Should work - Try your config command:
"Run swift --version"→ Should work - Try a non-allowed command:
"Run wget https://example.com"→ Should be blocked
5. Check the agent output:
The agent will show security hook messages like:
Command 'sudo' is blocked at organization level and cannot be approved.
Or:
Command 'wget' is not allowed.
To allow this command:
1. Add to .autocoder/allowed_commands.yaml for this project, OR
2. Request mid-session approval (the agent can ask)
Files Reference
examples/project_allowed_commands.yaml- Full project config templateexamples/org_config.yaml- Full org config templatesecurity.py- Implementation and hardcoded blocklisttest_security.py- Unit tests (136 tests)test_security_integration.py- Integration tests (9 tests)CLAUDE.md- Full system documentation
Questions?
See the main documentation in CLAUDE.md for architecture details and implementation specifics.