VT Code implements a comprehensive, defense-in-depth command security system that enables non-powered users to run safe commands by default while protecting against dangerous operations. This system helps the agent use system and build tools properly via environment PATH configuration.
Safe-by-default: All known safe commands for development and system utilities are enabled without requiring user confirmation or configuration.
Layered Defense: Multiple validation layers (allow_list, allow_glob, deny_list, deny_glob, allow_regex, deny_regex) work together to prevent dangerous commands from executing.
Deny-rules-first: If a command matches any deny pattern, it is blocked regardless of allow patterns.
- vtcode.toml - User/project-level overrides (highest priority)
- vtcode-config/src/core/commands.rs - Code defaults (runtime)
- vtcode-config/src/constants.rs - System constants (backup)
Commands are validated against these layers in order:
Input: command → Check deny_list → Check deny_glob → Check deny_regex
↓ MATCH = DENY
Check allow_list → Check allow_glob → Check allow_regex
↓ MATCH = ALLOW
Otherwise → DENY (fail-closed)
Safely query and display file information without modification:
- Basic:
ls,pwd,cat,head,tail,echo,printf - Search:
grep,find,locate - Analysis:
wc,sort,uniq,cut,awk,sed - Inspection:
file,stat,diff,tree,du,df
Inspect repository state and manage commits safely:
- Inspection:
git status,git log,git show,git diff,git branch - Safe workflows:
git fetch,git pull,git add,git commit,git stash,git tag - Other VCS:
hg,svn,git-lfs
Core compilation and build tool execution:
- Make-based:
make,cmake,ninja,meson,bazel - Rust ecosystem:
cargo,rustc,rustfmt,rustup,cargo test - All major subcommands:
cargo build,cargo test,cargo check,cargo run, etc.
Execution and dependency management for all major languages:
- Python:
python,python3,pip,pip3,virtualenv,pytest,black,flake8,mypy,ruff - Node.js:
npm,node,yarn,pnpm,bun,npx - Go:
go,gofmt,golint - Java:
java,javac,mvn,gradle - C/C++:
gcc,g++,clang,clang++
Safe data compression without system-level access:
tar,zip,unzip,gzip,gunzip,bzip2,bunzip2,xz,unxz
Docker and container platforms:
docker,docker-compose(with restrictions ondocker run)- Note:
docker run *is denied; containers require careful review
Safe read-only system monitoring:
ps,top,htop- Process listing and monitoringdf,du- Disk usagewhoami,hostname,uname- System identity
Patterns like git *, cargo *, npm run * enable entire command families:
allow_glob = [
"git *", # All git subcommands
"cargo *", # All cargo workflows
"cargo test *", # Test execution
"python *", # Python with any flags
"npm run *", # NPM script execution
"docker *", # All docker (except restricted)
]- Root deletion:
rm -rf /,rm -rf /*,rm -rf /home,rm -rf /usr,rm -rf /etc - Home deletion:
rm -rf ~ - Filesystem tools:
mkfs,mkfs.ext4,fdisk,dd if=/dev/*
shutdown,reboot,halt,poweroffsystemctl poweroff,systemctl reboot,systemctl haltinit 0,init 6
- Any
sudocommand:sudo rm,sudo chmod,sudo bash, etc. - Root switching:
su root,su - - Admin shells:
sudo -i,nohup bash -i,exec bash -i
mount,umount- Prevent unauthorized filesystem manipulation
format,fdisk,mkfs,shred,wipedd if=/dev/zero,dd if=/dev/random,dd if=/dev/urandom
chmod 777,chmod -R 777- Make files world-writable (dangerous)chown -R,chgrp -R- Recursive ownership changes
- Fork bomb:
:(){ :|:& };: - Code evaluation:
eval- Prevents arbitrary code injection - Config sourcing:
source /etc/bashrc,source ~/.bashrc
- User databases:
cat /etc/passwd,cat /etc/shadow - SSH keys:
cat ~/.ssh/id_*,rm ~/.ssh/*,rm -r ~/.ssh - System logs:
tail -f /var/log, direct log access
kill,pkill- Process termination- Note: Allows monitoring (
ps,top,htop) but not process killing
systemctl *- System service manipulation (denied at glob level)service *- Legacy service managementcrontab,at- Task scheduling (dangerous for automation)
VT Code supports automation through internal scheduling primitives instead:
/loopfor session-scoped recurring prompts in interactive chatvtcode schedulefor durable local automation and reminders
kubectl *- Kubernetes operations (admin access)docker run *- Container creation (requires careful review)
Exact command matches allowed without confirmation.
[commands]
allow_list = [
"ls",
"pwd",
"git status",
"cargo build",
]Exact command patterns that are always blocked.
deny_list = [
"rm -rf /",
"rm -rf ~",
"sudo rm",
":(){ :|:& };:",
]Wildcard patterns for command families.
allow_glob = [
"git *", # All git commands
"cargo *", # All cargo commands
"npm run *", # NPM scripts
]Blocks entire command families.
deny_glob = [
"rm *", # All rm variations
"sudo *", # All sudo usage
"chmod *", # All chmod variations
]Regular expressions for complex allow rules.
allow_regex = [
r"^cargo (build|test|run|check|clippy|fmt)\b",
r"^git (status|log|show|diff|branch)\b",
]Regular expressions to block patterns.
deny_regex = [
r"rm\s+(-rf|--force|--recursive)",
r"sudo\s+.*",
r"docker\s+run\s+.*--privileged",
]The system extends the shell PATH with safe, common locations:
[commands]
extra_path_entries = [
"$HOME/.cargo/bin", # Rust tools (rustup, cargo)
"$HOME/.local/bin", # User-installed binaries
"$HOME/.nvm/versions/node/*/bin", # Node.js versions
"/opt/homebrew/bin", # Homebrew (macOS)
]This allows the agent to access:
- Rust tools:
cargo,rustc,rustfmt,rustup - Python tools:
pytest,black,flake8,mypy - Node tools:
npm,yarn,node - Go tools:
go,gofmt - And all other build/development tools installed via package managers
Configuration for tool execution:
[commands.environment]
RUST_BACKTRACE = "1"
PATH = { append = ["$HOME/.cargo/bin"] }
HOME = "$HOME"The permission system logs all decisions for security and debugging:
[permissions]
enabled = true
audit_enabled = true
audit_directory = "~/.vtcode/audit"
log_allowed_commands = true
log_denied_commands = true
cache_ttl_seconds = 300Audit logs track:
- Allowed commands executed
- Blocked/denied commands attempted
- Permission decision cache hits
- Command resolution paths
Out of the box:
- Agent can execute all safe commands from
allow_list - Agent can use pattern-based commands like
git *,cargo * - Dangerous commands are automatically blocked with no prompt
To enable additional safe commands:
[commands]
allow_list = [
# ... existing commands ...
"custom-build-tool",
"my-deployment-script",
]Or via globs:
allow_glob = [
"my-tool *",
"custom-build *",
]When using run_pty_cmd, set confirm=true for commands that need approval:
# Example from agent
run_pty_cmd(
command=["git", "reset", "--hard"],
confirm=True # Requires user confirmation despite being in allow_glob
)[commands]
# Only allow explicit commands
allow_list = [
"ls", "pwd", "cat", "git", "cargo", "python"
]
# Block everything else
allow_glob = []
allow_regex = []
# Extensive deny lists
deny_glob = [
"*", # Deny everything by default
][commands]
# Allow development tools broadly
allow_glob = [
"git *",
"cargo *",
"npm *",
"python *",
"*-cli *", # CLI tools
"*-build *", # Build tools
]
# Still block dangerous patterns
deny_glob = [
"rm *",
"sudo *",
"chmod *",
][commands]
allow_list = [
"ls", "pwd", "cat", "grep",
]
# Allow project-specific tools
allow_glob = [
"make *",
"./scripts/*",
"docker compose *",
]
deny_glob = [
"rm -rf",
"sudo *",
]Accidental destructive commands Privilege escalation attempts Malicious shell exploits (forkbombs, eval injection) Sensitive data exposure (SSH keys, password files) System shutdown/corruption Filesystem manipulation
Compromised agent LLM (if it's compromised, it can craft allowed commands to cause harm)
Commands that are allowed but have dangerous flags (e.g., cargo build --offline with missing dependencies)
Zip bombs or other valid-but-malicious allowed file operations
Side effects of running safe commands in a bad state
- Keep deny_list comprehensive - Always block system-altering commands
- Use allow_glob sparingly - More specific allow_list entries are safer
- Monitor audit logs - Review
~/.vtcode/audit/regularly for suspicious patterns - Test configurations - Validate with
cargo testbefore deploying - Avoid eval-like patterns - Never allow
eval,source, dynamic command construction - Isolate workspaces - Consider separate configurations for different project types
[commands]
allow_list = [
"ls", "pwd", "cat", "grep", "find",
"git", "cargo", "rustc", "rustfmt",
]
allow_glob = [
"git *",
"cargo *",
"cargo test *",
]
deny_glob = [
"rm *", "sudo *", "chmod *", "kill *",
][commands]
allow_list = [
"ls", "pwd", "cat", "grep", "find",
"python", "python3", "pip", "pip3",
"jupyter", "git",
]
allow_glob = [
"python *",
"python3 *",
"pip *",
"git *",
"conda *",
]
deny_glob = [
"rm *", "sudo *", "chmod *",
][commands]
allow_list = [
"ls", "pwd", "cat", "grep", "find",
"git", "npm", "node", "python",
"docker", "docker-compose",
]
allow_glob = [
"git *",
"npm *",
"npm run *",
"node *",
"python *",
"docker *",
"docker-compose *",
]
deny_glob = [
"rm *", "sudo *", "chmod *", "kill *",
"docker run *", # Explicit deny for container creation
]Test command permissions using VT Code's built-in validation:
# Build and test
cargo build
cargo test
# Check configuration
cargo run -- ask "list safe commands"
# Run with debug logging
RUST_LOG=debug cargo run- docs/development/EXECUTION_POLICY.md - Overall execution policy
- docs/environment/ALLOWED_COMMANDS_REFERENCE.md - Complete command reference
- vtcode-config/src/core/commands.rs - Implementation
- vtcode.toml.example - Configuration examples