---
title: "Policy templates"
description: "The 5 built-in templates, their rules and when to reach for each."
label: "Policy templates"
generated: "the templates in packages/policy/src/templates.ts"
---


A template is a complete, valid rule set you can create a policy from and then edit. It is a starting point, not a managed policy: once created, the rules are yours and Veefore will not change them underneath you.

## Starter — safe defaults

`starter-observe-safe-defaults` · starter, recommended

Allows read-style capabilities, requires approval for anything flagged dangerous, and blocks destructive database operations.

**Why it is shaped this way.** A first policy that is meaningful without knowing the agent yet. Pair it with OBSERVE mode, review real traffic, then tighten.

Default decision when no rule matches: `ALLOW` — No rule matched; the request is within the starter policy baseline.

| Priority | Rule | Decision | What it does |
| --- | --- | --- | --- |
| 900 | Block destructive database operations | `BLOCK` | DELETE, DROP and TRUNCATE are never permitted through an agent. |
| 500 | Require approval for dangerous tools | `REQUIRE_APPROVAL` |  |
| 480 | Require approval for production deployments | `REQUIRE_APPROVAL` |  |
| 200 | Mask customer contact details | `MASK` |  |

<details><summary>Full rule set</summary>

```json
{
  "schemaVersion": 1,
  "defaultDecision": "ALLOW",
  "defaultReason": "No rule matched; the request is within the starter policy baseline.",
  "rules": [
    {
      "id": "rule-block-destructive-db",
      "name": "Block destructive database operations",
      "description": "DELETE, DROP and TRUNCATE are never permitted through an agent.",
      "priority": 900,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-destructive",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-cap-db",
            "field": "capability",
            "operator": "starts_with",
            "value": "database."
          },
          {
            "kind": "condition",
            "id": "c-op-destructive",
            "field": "parameters",
            "path": "operation",
            "operator": "in",
            "value": [
              "DELETE",
              "DROP",
              "TRUNCATE"
            ],
            "ignoreCase": true
          }
        ]
      },
      "then": {
        "decision": "BLOCK",
        "reason": "Destructive database operations are not permitted through an agent."
      }
    },
    {
      "id": "rule-approve-dangerous-tools",
      "name": "Require approval for dangerous tools",
      "priority": 500,
      "enabled": true,
      "when": {
        "kind": "condition",
        "id": "c-tool-dangerous",
        "field": "tool.dangerous",
        "operator": "is_true"
      },
      "then": {
        "decision": "REQUIRE_APPROVAL",
        "reason": "This tool is flagged as high impact and requires a human decision.",
        "approval": {
          "routingMode": "SINGLE",
          "requiredApprovals": 1,
          "ttlSeconds": 900
        }
      }
    },
    {
      "id": "rule-approve-production-deployment",
      "name": "Require approval for production deployments",
      "priority": 480,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-deploy-prod",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-cap-deploy",
            "field": "capability",
            "operator": "eq",
            "value": "deployment.create"
          },
          {
            "kind": "condition",
            "id": "c-env-prod",
            "field": "environment.type",
            "operator": "eq",
            "value": "PRODUCTION"
          }
        ]
      },
      "then": {
        "decision": "REQUIRE_APPROVAL",
        "reason": "Production deployments require human approval.",
        "approval": {
          "routingMode": "SINGLE",
          "requiredApprovals": 1,
          "ttlSeconds": 1800
        }
      }
    },
    {
      "id": "rule-mask-pii",
      "name": "Mask customer contact details",
      "priority": 200,
      "enabled": true,
      "when": {
        "kind": "condition",
        "id": "c-has-email",
        "field": "parameters",
        "path": "email",
        "operator": "exists"
      },
      "then": {
        "decision": "MASK",
        "reason": "Customer contact details are masked before forwarding and in audit.",
        "maskFields": [
          "email",
          "phone"
        ]
      }
    }
  ]
}
```

</details>

## Finance — refund thresholds

`finance-refunds` · finance, approval

Tiered refund authority: small refunds allowed, mid-size refunds require approval, large refunds blocked.

**Why it is shaped this way.** The canonical money-adjacent control. Veefore does not move money; the amount is used purely as a policy input.

Default decision when no rule matches: `BLOCK` — Only explicitly permitted refund patterns may execute.

| Priority | Rule | Decision | What it does |
| --- | --- | --- | --- |
| 950 | Block payments to unknown recipients | `BLOCK` |  |
| 900 | Block refunds above ₹1,00,000 | `BLOCK` |  |
| 700 | Require approval for refunds above ₹10,000 | `REQUIRE_APPROVAL` |  |
| 500 | Allow refunds up to ₹10,000 | `ALLOW` |  |
| 300 | Allow invoice reads | `ALLOW` |  |
| 300 | Allow invoice creation up to ₹5,00,000 | `ALLOW` |  |

<details><summary>Full rule set</summary>

```json
{
  "schemaVersion": 1,
  "defaultDecision": "BLOCK",
  "defaultReason": "Only explicitly permitted refund patterns may execute.",
  "rules": [
    {
      "id": "rule-refund-block-large",
      "name": "Block refunds above ₹1,00,000",
      "priority": 900,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-refund-large",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-cap-refund-1",
            "field": "capability",
            "operator": "eq",
            "value": "refund.create"
          },
          {
            "kind": "condition",
            "id": "c-amt-large",
            "field": "amount",
            "operator": "gt",
            "value": 10000000
          }
        ]
      },
      "then": {
        "decision": "BLOCK",
        "reason": "Refunds above ₹1,00,000 exceed the maximum authority delegated to any agent."
      }
    },
    {
      "id": "rule-refund-approve-mid",
      "name": "Require approval for refunds above ₹10,000",
      "priority": 700,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-refund-mid",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-cap-refund-2",
            "field": "capability",
            "operator": "eq",
            "value": "refund.create"
          },
          {
            "kind": "condition",
            "id": "c-amt-mid-low",
            "field": "amount",
            "operator": "gt",
            "value": 1000000
          },
          {
            "kind": "condition",
            "id": "c-amt-mid-high",
            "field": "amount",
            "operator": "lte",
            "value": 10000000
          }
        ]
      },
      "then": {
        "decision": "REQUIRE_APPROVAL",
        "reason": "Refunds between ₹10,000 and ₹1,00,000 require human approval.",
        "approval": {
          "routingMode": "SINGLE",
          "requiredApprovals": 1,
          "ttlSeconds": 900
        }
      }
    },
    {
      "id": "rule-refund-allow-small",
      "name": "Allow refunds up to ₹10,000",
      "priority": 500,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-refund-small",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-cap-refund-3",
            "field": "capability",
            "operator": "eq",
            "value": "refund.create"
          },
          {
            "kind": "condition",
            "id": "c-amt-small",
            "field": "amount",
            "operator": "lte",
            "value": 1000000
          }
        ]
      },
      "then": {
        "decision": "ALLOW",
        "reason": "Refunds up to ₹10,000 are within delegated authority."
      }
    },
    {
      "id": "rule-invoice-read",
      "name": "Allow invoice reads",
      "priority": 300,
      "enabled": true,
      "when": {
        "kind": "condition",
        "id": "c-cap-invoice-read",
        "field": "capability",
        "operator": "eq",
        "value": "invoice.read"
      },
      "then": {
        "decision": "ALLOW",
        "reason": "Reading invoices is a low-risk operation."
      }
    },
    {
      "id": "rule-invoice-create",
      "name": "Allow invoice creation up to ₹5,00,000",
      "priority": 300,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-invoice-create",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-cap-invoice-create",
            "field": "capability",
            "operator": "eq",
            "value": "invoice.create"
          },
          {
            "kind": "condition",
            "id": "c-invoice-amt",
            "field": "amount",
            "operator": "lte",
            "value": 50000000
          }
        ]
      },
      "then": {
        "decision": "ALLOW",
        "reason": "Invoice creation within the configured ceiling."
      }
    },
    {
      "id": "rule-unknown-recipient",
      "name": "Block payments to unknown recipients",
      "priority": 950,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-unknown-recipient",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-cap-payment",
            "field": "capability",
            "operator": "eq",
            "value": "payment.create"
          },
          {
            "kind": "condition",
            "id": "c-new-recipient",
            "field": "risk.signals",
            "operator": "contains",
            "value": "NEW_RECIPIENT"
          }
        ]
      },
      "then": {
        "decision": "BLOCK",
        "reason": "The recipient has never been seen for this agent. Add it to the known recipient list first."
      }
    }
  ]
}
```

</details>

## Database — read only

`database-read-only` · database, least-privilege

SELECT permitted on non-restricted resources; every write or delete blocked.

**Why it is shaped this way.** Appropriate for analytics and support agents that must never mutate data.

Default decision when no rule matches: `BLOCK` — This agent is restricted to read-only database access.

| Priority | Rule | Decision | What it does |
| --- | --- | --- | --- |
| 900 | Block database writes and deletes | `BLOCK` |  |
| 880 | Block access to restricted resources | `BLOCK` |  |
| 500 | Allow SELECT queries | `ALLOW` |  |

<details><summary>Full rule set</summary>

```json
{
  "schemaVersion": 1,
  "defaultDecision": "BLOCK",
  "defaultReason": "This agent is restricted to read-only database access.",
  "rules": [
    {
      "id": "rule-db-block-writes",
      "name": "Block database writes and deletes",
      "priority": 900,
      "enabled": true,
      "when": {
        "kind": "condition",
        "id": "c-cap-db-write",
        "field": "capability",
        "operator": "in",
        "value": [
          "database.write",
          "database.delete"
        ]
      },
      "then": {
        "decision": "BLOCK",
        "reason": "Write and delete capabilities are not delegated to this agent."
      }
    },
    {
      "id": "rule-db-block-restricted",
      "name": "Block access to restricted resources",
      "priority": 880,
      "enabled": true,
      "when": {
        "kind": "condition",
        "id": "c-res-restricted",
        "field": "resource.sensitivity",
        "operator": "eq",
        "value": "RESTRICTED"
      },
      "then": {
        "decision": "BLOCK",
        "reason": "Restricted data classification is out of scope for this agent."
      }
    },
    {
      "id": "rule-db-allow-select",
      "name": "Allow SELECT queries",
      "priority": 500,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-db-select",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-cap-db-read",
            "field": "capability",
            "operator": "eq",
            "value": "database.read"
          },
          {
            "kind": "condition",
            "id": "c-db-op-select",
            "field": "parameters",
            "path": "operation",
            "operator": "eq",
            "value": "SELECT",
            "ignoreCase": true
          }
        ]
      },
      "then": {
        "decision": "ALLOW",
        "reason": "Read-only query within the permitted resource scope."
      }
    }
  ]
}
```

</details>

## Production — change control

`production-change-control` · production, change-management

Requires step-up authentication plus approval for any production mutation, and blocks off-hours changes.

**Why it is shaped this way.** Maps an existing change-management process onto agent actions.

Default decision when no rule matches: `ALLOW` — Non-production or read-only request.

| Priority | Rule | Decision | What it does |
| --- | --- | --- | --- |
| 900 | Block production changes outside 02:00–18:00 UTC | `BLOCK` |  |
| 700 | Require step-up authentication for production mutations | `STEP_UP_AUTH` |  |
| 400 | Limit production action velocity | `LIMIT` |  |

<details><summary>Full rule set</summary>

```json
{
  "schemaVersion": 1,
  "defaultDecision": "ALLOW",
  "defaultReason": "Non-production or read-only request.",
  "rules": [
    {
      "id": "rule-prod-offhours",
      "name": "Block production changes outside 02:00–18:00 UTC",
      "priority": 900,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-offhours",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-env-prod-2",
            "field": "environment.type",
            "operator": "eq",
            "value": "PRODUCTION"
          },
          {
            "kind": "condition",
            "id": "c-tool-dangerous-2",
            "field": "tool.dangerous",
            "operator": "is_true"
          },
          {
            "kind": "group",
            "id": "g-hours",
            "operator": "or",
            "children": [
              {
                "kind": "condition",
                "id": "c-hour-early",
                "field": "time.hour_utc",
                "operator": "lt",
                "value": 2
              },
              {
                "kind": "condition",
                "id": "c-hour-late",
                "field": "time.hour_utc",
                "operator": "gte",
                "value": 18
              }
            ]
          }
        ]
      },
      "then": {
        "decision": "BLOCK",
        "reason": "High-impact production changes are restricted to the 02:00–18:00 UTC change window."
      }
    },
    {
      "id": "rule-prod-stepup",
      "name": "Require step-up authentication for production mutations",
      "priority": 700,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-prod-mutate",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-env-prod-3",
            "field": "environment.type",
            "operator": "eq",
            "value": "PRODUCTION"
          },
          {
            "kind": "condition",
            "id": "c-tool-dangerous-3",
            "field": "tool.dangerous",
            "operator": "is_true"
          }
        ]
      },
      "then": {
        "decision": "STEP_UP_AUTH",
        "reason": "Production mutations require a recent step-up authentication.",
        "stepUpMaxAgeSeconds": 300
      }
    },
    {
      "id": "rule-prod-velocity",
      "name": "Limit production action velocity",
      "priority": 400,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-prod-velocity",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-env-prod-4",
            "field": "environment.type",
            "operator": "eq",
            "value": "PRODUCTION"
          },
          {
            "kind": "condition",
            "id": "c-velocity-high",
            "field": "velocity.actions_last_minute",
            "operator": "gt",
            "value": 30
          }
        ]
      },
      "then": {
        "decision": "LIMIT",
        "reason": "Production action rate exceeded; throttling to protect downstream systems.",
        "limitVelocity": {
          "maxActionsPerMinute": 30
        }
      }
    }
  ]
}
```

</details>

## Protocol — untrusted MCP and A2A guard

`untrusted-protocol-guard` · mcp, a2a, trust

Blocks MCP and A2A interactions that lack valid trust evidence, and requires approval for newly discovered tools.

**Why it is shaped this way.** A connected MCP server or peer agent is not trusted merely because it is reachable.

Default decision when no rule matches: `ALLOW` — Protocol interaction satisfied the trust guard.

| Priority | Rule | Decision | What it does |
| --- | --- | --- | --- |
| 950 | Block agents with an active incident | `BLOCK` |  |
| 900 | Block A2A with unverified identity | `BLOCK` |  |
| 880 | Block when trust evidence has expired | `BLOCK` |  |
| 600 | Require approval for first use of an MCP tool | `REQUIRE_APPROVAL` |  |

<details><summary>Full rule set</summary>

```json
{
  "schemaVersion": 1,
  "defaultDecision": "ALLOW",
  "defaultReason": "Protocol interaction satisfied the trust guard.",
  "rules": [
    {
      "id": "rule-block-unverified-a2a",
      "name": "Block A2A with unverified identity",
      "priority": 900,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-a2a-unverified",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-proto-a2a",
            "field": "tool.protocol",
            "operator": "eq",
            "value": "A2A"
          },
          {
            "kind": "condition",
            "id": "c-identity-unverified",
            "field": "trust.identity_verified",
            "operator": "is_false"
          }
        ]
      },
      "then": {
        "decision": "BLOCK",
        "reason": "The remote agent has no valid identity verification evidence."
      }
    },
    {
      "id": "rule-block-expired-evidence",
      "name": "Block when trust evidence has expired",
      "priority": 880,
      "enabled": true,
      "when": {
        "kind": "condition",
        "id": "c-expired-evidence",
        "field": "trust.expired_evidence_count",
        "operator": "gt",
        "value": 0
      },
      "then": {
        "decision": "BLOCK",
        "reason": "Required trust evidence has expired. Refresh the evidence before retrying."
      }
    },
    {
      "id": "rule-approve-new-mcp-tool",
      "name": "Require approval for first use of an MCP tool",
      "priority": 600,
      "enabled": true,
      "when": {
        "kind": "group",
        "id": "g-new-mcp-tool",
        "operator": "and",
        "children": [
          {
            "kind": "condition",
            "id": "c-proto-mcp",
            "field": "tool.protocol",
            "operator": "eq",
            "value": "MCP"
          },
          {
            "kind": "condition",
            "id": "c-tool-new",
            "field": "history.tool_used_before",
            "operator": "is_false"
          }
        ]
      },
      "then": {
        "decision": "REQUIRE_APPROVAL",
        "reason": "First use of this MCP tool by this agent requires human review.",
        "approval": {
          "routingMode": "SINGLE",
          "requiredApprovals": 1,
          "ttlSeconds": 900
        }
      }
    },
    {
      "id": "rule-block-active-incident",
      "name": "Block agents with an active incident",
      "priority": 950,
      "enabled": true,
      "when": {
        "kind": "condition",
        "id": "c-active-incident",
        "field": "trust.active_incidents",
        "operator": "gt",
        "value": 0
      },
      "then": {
        "decision": "BLOCK",
        "reason": "An active security incident involves this agent."
      }
    }
  ]
}
```

</details>
