Skip to main content
AIP policies are declarative YAML files that define what tools an agent can use and under what conditions. This guide teaches you how to write secure, maintainable policies.

Policy Structure

Every AIP policy follows this structure:
apiVersion: aip.io/v1alpha1
kind: AgentPolicy
metadata:
  name: string           # Policy identifier
  version: string        # Semantic version (optional)
  owner: string          # Contact email (optional)
spec:
  mode: enforce | monitor
  allowed_tools: [string]
  tool_rules: [ToolRule]
  dlp: DLPConfig

Design Principle: Default Deny

If a tool is not explicitly allowed, it’s blocked. This fail-closed approach ensures agents can’t access tools you haven’t reviewed.

Metadata

metadata.name
string
required
Unique identifier for this policy. Used in audit logs.
metadata.version
string
Semantic version (e.g., “2.1.0”). Useful for policy versioning.
metadata.owner
string
Contact email for policy questions.
Example:
metadata:
  name: code-review-agent
  version: "2.1.0"
  owner: [email protected]

Mode: Enforce vs Monitor

spec.mode
string
required
Controls whether policy violations are enforced or just logged.
  • enforce - Block violations, return JSON-RPC error (default)
  • monitor - Log violations but allow through (dry-run)
Use case for monitor mode: Test new policies in production before enforcement.
spec:
  mode: monitor  # Test first, enforce later

Allowed Tools

spec.allowed_tools
array
required
Allowlist of tool names that the agent can invoke. Tool names must exactly match what the MCP server reports.
Example:
spec:
  allowed_tools:
    - read_file
    - list_directory
    - git_status
    - github_get_repo
    - github_list_pulls
If a tool is not in allowed_tools AND not in tool_rules with action: allow, it will be blocked.

Tool Rules

Fine-grained control over individual tools.
spec.tool_rules
array
Array of rules defining per-tool behavior and argument validation.

Rule Structure

spec:
  tool_rules:
    - tool: string          # Tool name (required)
      action: string        # allow | block | ask (default: allow)
      allow_args: object    # Argument validation patterns

Actions

Permit the tool call (subject to allow_args validation):
tool_rules:
  - tool: github_get_repo
    action: allow
    allow_args:
      owner: "^mycompany$"
      repo: ".*"
Only allows accessing repos under mycompany organization.

Argument Validation

Validate tool arguments using regex patterns.
spec.tool_rules[].allow_args
object
Map of argument names to regex patterns. All patterns must match for the tool call to be allowed.

Example: Path Restrictions

tool_rules:
  - tool: read_file
    action: allow
    allow_args:
      path: "^/home/user/safe-dir/.*$"  # Only allow reading from safe directory

Example: Repository Scoping

tool_rules:
  - tool: github_create_pr
    action: allow
    allow_args:
      owner: "^(mycompany|mycompany-labs)$"  # Only specific orgs
      repo: "^[a-z0-9-]+$"                   # Alphanumeric repo names only
      base: "^main$"                         # PRs only to main branch

Regex Best Practices

Use anchors (^ and $) to prevent partial matches:
  • Bad: "mycompany" - matches "evil-mycompany"
  • Good: "^mycompany$" - exact match only
Avoid catastrophic backtracking:
  • Bad: "(a+)+b" - exponential time
  • Good: "^[a-z]+$" - linear time (RE2)

Real-World Examples

Example 1: Read-Only File Agent

apiVersion: aip.io/v1alpha1
kind: AgentPolicy
metadata:
  name: read-only-agent
spec:
  mode: enforce
  allowed_tools:
    - read_file
    - list_directory
    - git_status
  tool_rules:
    - tool: write_file
      action: block
    - tool: exec_command
      action: block

Example 2: GitHub PR Review Agent

apiVersion: aip.io/v1alpha1
kind: AgentPolicy
metadata:
  name: github-pr-agent
  version: "1.0.0"
spec:
  mode: enforce
  allowed_tools:
    - github_get_repo
    - github_list_pulls
    - github_get_pull
    - github_create_comment
  tool_rules:
    - tool: github_get_repo
      allow_args:
        owner: "^mycompany$"
    - tool: github_create_comment
      action: ask  # Human reviews comments before posting
      allow_args:
        owner: "^mycompany$"

Example 3: Database Admin Agent

apiVersion: aip.io/v1alpha1
kind: AgentPolicy
metadata:
  name: db-admin-agent
spec:
  mode: enforce
  allowed_tools:
    - postgres_query
  tool_rules:
    - tool: postgres_query
      action: allow
      allow_args:
        query: "^SELECT .*$"  # Only SELECT queries
    - tool: postgres_query
      action: ask
      allow_args:
        query: "^(UPDATE|INSERT|DELETE) .*$"  # Human approval for writes
  dlp:
    patterns:
      - name: "Credit Card"
        regex: "\\b\\d{4}[- ]?\\d{4}[- ]?\\d{4}[- ]?\\d{4}\\b"
      - name: "SSN"
        regex: "\\b\\d{3}-\\d{2}-\\d{4}\\b"

Policy Versioning

1

Use semantic versioning

Version your policies with metadata.version:
metadata:
  version: "2.1.0"
2

Store in version control

Commit policies to Git for change tracking:
git add policies/agent.yaml
git commit -m "feat: add github_create_pr to allowed_tools"
3

Review changes

Require peer review for policy changes, like code reviews.
4

Test before deploying

Use mode: monitor to test changes:
spec:
  mode: monitor  # Test for 1 week, then switch to enforce

Validation

Before Deployment

Validate your policy file:
aip --validate-policy ./agent.yaml

Against JSON Schema

Use the formal JSON schema:
# Using ajv-cli
npm install -g ajv-cli
ajv validate -s spec/schema/agent-policy-v1alpha2.schema.json -d agent.yaml

Common Pitfalls

Overly permissive regexesBad: ".*" - allows anything Good: "^[a-zA-Z0-9_-]+$" - specific character class
Forgetting to anchor regexesBad: "safe-dir" - matches /unsafe-dir/file Good: "^/safe-dir/.*$" - exact path matching
Not testing monitor mode firstAlways test with mode: monitor before enforcing.

Next Steps

DLP Configuration

Add data loss prevention to your policies

Human-in-the-Loop

Configure approval workflows

Policy Schema

Complete field reference

Audit Logging

Track all policy decisions

Build docs developers (and LLMs) love