Skip to main content

Overview

The Coding Agent pack provides essential security guardrails for AI agents that execute shell commands, modify files, or interact with development environments. It prevents common destructive operations while allowing normal development workflows. Use this pack for:
  • AI coding assistants (like Cursor, GitHub Copilot, Codeium)
  • Development automation agents
  • CI/CD workflow agents
  • Infrastructure-as-code tools

Complete Policy

coding-agent.yaml
version: "1.0"
name: coding-agent-pack
description: Baseline guardrails for coding agents.
rules:
  - id: coding-agent-block-dangerous-shell-commands
    name: Block dangerous shell commands
    description: Prevent destructive shell operations.
    enabled: true
    severity: critical
    action: block
    tools:
      - execute_command
      - run_shell
      - bash
      - shell
    condition_groups:
      - - field: arguments.command
          operator: contains
          value: "rm -rf"
      - - field: arguments.command
          operator: contains
          value: "mkfs"
      - - field: arguments.command
          operator: contains
          value: "shutdown"
      - - field: arguments.command
          operator: contains
          value: "reboot"

  - id: coding-agent-restrict-sensitive-file-writes
    name: Restrict sensitive file writes
    description: Block writes to sensitive system locations.
    enabled: true
    severity: high
    action: block
    tools:
      - write_file
      - edit_file
      - append_file
    condition_groups:
      - - field: arguments.path
          operator: starts_with
          value: /etc
      - - field: arguments.path
          operator: starts_with
          value: /root
      - - field: arguments.path
          operator: contains
          value: .ssh

  - id: coding-agent-block-path-traversal-writes
    name: Block path traversal file writes
    description: Prevent writing files via traversal paths.
    enabled: true
    severity: high
    action: block
    tools:
      - write_file
      - edit_file
      - append_file
    conditions:
      - field: arguments.path
        operator: contains
        value: "../"

Rules Explained

1. Block Dangerous Shell Commands

Rule ID: coding-agent-block-dangerous-shell-commands What it does: Prevents execution of shell commands that can cause catastrophic system damage. Blocked patterns:
  • rm -rf - Recursive force deletion (can wipe entire filesystems)
  • mkfs - Format filesystem (destroys all data on a disk)
  • shutdown - System shutdown (interrupts all work)
  • reboot - System restart (interrupts all work)
Why it’s important: AI models can sometimes generate destructive commands when troubleshooting or “cleaning up.” A single rm -rf / can destroy an entire system. Example blocked call:
// This will be blocked:
await executeCommand({ command: "rm -rf /tmp/*" });
// Error: Tool call denied: dangerous shell command detected

2. Restrict Sensitive File Writes

Rule ID: coding-agent-restrict-sensitive-file-writes What it does: Prevents writing to critical system directories and sensitive configuration paths. Blocked locations:
  • /etc - System configuration files (network, users, services)
  • /root - Root user’s home directory
  • Any path containing .ssh - SSH keys and configuration
Why it’s important: Modifying system files can break the OS, create security vulnerabilities, or lock you out of the system. SSH keys should never be auto-generated or modified by an AI. Example blocked calls:
// These will be blocked:
await writeFile({ path: "/etc/hosts", content: "..." });
await editFile({ path: "/root/.bashrc", changes: [...] });
await appendFile({ path: "/home/user/.ssh/authorized_keys", content: "..." });

3. Block Path Traversal File Writes

Rule ID: coding-agent-block-path-traversal-writes What it does: Blocks file writes using relative path traversal (../). Why it’s important: Path traversal attacks allow writing files outside the intended directory. An agent working in /home/user/project should not be able to write to /home/user/../../etc/passwd via ../ sequences. Example blocked call:
// This will be blocked:
await writeFile({ 
  path: "/home/user/project/../../../etc/shadow",
  content: "malicious data"
});

Usage Example

Basic Setup

veto.config.yaml
version: "1.0"
extends: "@veto/coding-agent"

mode: "strict"
logging:
  level: "info"

With TypeScript SDK

import { Veto } from 'veto-sdk';

const veto = await Veto.init();

const tools = [
  {
    name: 'execute_command',
    description: 'Run a shell command',
    handler: async ({ command }: { command: string }) => {
      const { execSync } = await import('child_process');
      return execSync(command).toString();
    },
  },
  {
    name: 'write_file',
    description: 'Write content to a file',
    handler: async ({ path, content }: { path: string; content: string }) => {
      const { writeFileSync } = await import('fs');
      writeFileSync(path, content);
      return { success: true };
    },
  },
];

const wrappedTools = veto.wrap(tools);

// Use wrappedTools with your agent framework
// Dangerous calls are automatically blocked

Customization

Allow Specific System Paths

If you need to write to /etc for legitimate infrastructure automation:
version: "1.0"
extends: "@veto/coding-agent"

rules:
  - id: coding-agent-restrict-sensitive-file-writes
    enabled: false  # Disable the default rule
  
  # Add a more specific rule
  - id: custom-allow-etc-nginx
    name: Allow nginx config writes
    action: allow
    tools:
      - write_file
      - edit_file
    conditions:
      - field: arguments.path
        operator: starts_with
        value: /etc/nginx

Add Command Approval

Require human approval for potentially dangerous commands instead of blocking:
rules:
  - id: coding-agent-block-dangerous-shell-commands
    action: require_approval  # Changed from "block"

Add Package Manager Protection

Prevent agents from installing system packages without approval:
rules:
  - id: custom-require-approval-package-install
    name: Require approval for package installation
    action: require_approval
    tools:
      - execute_command
      - run_shell
    condition_groups:
      - - field: arguments.command
          operator: starts_with
          value: "apt install"
      - - field: arguments.command
          operator: starts_with
          value: "yum install"
      - - field: arguments.command
          operator: starts_with
          value: "brew install"

What’s NOT Protected

This pack focuses on preventing immediate catastrophic damage. It does NOT protect against:
  • Malicious code injection - An agent can still write malicious JavaScript/Python files
  • Data exfiltration - File reads are not restricted
  • Resource exhaustion - No limits on CPU/memory usage
  • Git operations - Force pushes, branch deletion, etc. are not blocked
For production use, consider:
  • Combining with other packs (e.g., @veto/data-access for database protection)
  • Adding custom rules for your specific tool names
  • Using operating system-level sandboxing (containers, VMs)
  • Implementing rate limiting for tool calls

Testing Your Configuration

Use the Veto CLI to test what would be blocked:
# Test a specific tool call
npx veto-cli guard check \
  --tool execute_command \
  --args '{"command": "rm -rf /"}' \
  --json

# Output:
# {
#   "action": "deny",
#   "rule": "coding-agent-block-dangerous-shell-commands",
#   "reason": "dangerous shell command detected"
# }

Policy Pack Overview

Learn about all available policy packs

Rule Syntax Reference

Complete YAML rule format documentation

Deployment Pack

Additional protection for CI/CD workflows

Human-in-the-Loop

Set up approval flows for sensitive operations

Build docs developers (and LLMs) love