<!-- https://avertgate.com/docs/policy-file · Policy -->

# Policy file

The policy is a YAML file evaluated deterministically on every call. There is no separate policy language like OPA/Rego.

## Full example

<!-- policy.yaml -->
```yaml
agent: support-agent-v1

tools:
  - name: "lookup_order"
    allow: true
  - name: "issue_refund"
    allow: true
    constraints:
      amount: { max: 5000 }
    require_approval_when:
      amount: { min: 500 }
  - name: "send_email"
    allow: true
    require_approval: true
    egress_scan: true
  - name: "delete_customer"
    allow: false

defaults:
  unlisted_tools: deny
  fail_closed: true

guard_model:
  enabled: false
  provider: "typesafe"

loop_breaker:
  enabled: true
  max_identical_calls: 3
```

## Top-level fields

| Field | Type | Description |
| --- | --- | --- |
| `agent` | string | The agent id the policy belongs to. |
| `tools` | list | Tool rules (below). |
| `resources` | list | Optional resource (MCP resource) rules: `uri_pattern` (regex or substring), `allow`, `require_approval`. |
| `defaults` | object | `unlisted_tools`, `fail_closed`, `shadow_mode`. |
| `mode` / `shadow_mode` | enforce \| shadow \| dry-run | Policy-level shadow. |
| `loop_breaker` | object | [Loop breaker](/docs/loop-breaker) settings. |
| `guard_model` | object | [AI Guard](/docs/ai-guard) settings. |

## Tool rule

| Field | Description |
| --- | --- |
| `name` | Tool name. |
| `allow` | If `false` the tool is always blocked. |
| `constraints` | Argument constraints: `min`, `max`, `enum`, `regex`. A violation = BLOCK. |
| `require_approval` | If `true` every call goes to human approval. |
| `require_approval_when` | Conditional approval: goes to approval when an argument reaches the threshold (`min`/`max`). |
| `egress_scan` | Arguments are scanned for secrets/PII unless set to `false` (default: on). |
| `shadow_mode` | Observe-only mode for this tool alone. |
| `max_identical` / `max_consecutive` | Loop thresholds specific to this tool. |

## Defaults

| Key | Value | Effect |
| --- | --- | --- |
| `unlisted_tools` | `deny` | Unlisted tools are blocked. **Recommended.** |
| `fail_closed` | `true` | On an inspector error a risky call is blocked/sent for approval. |

> **Careful**: If the SDK is given no policy at all it uses a permissive default: unlisted tools are allowed, but egress/ingress and the loop breaker are on. In production always use an explicit policy and `unlisted_tools: deny`.

## Validation

The dashboard's policy page validates YAML through `POST /api/policy/validate` before saving. An invalid policy is not saved.
