Policy templates
The 5 built-in templates, their rules and when to reach for each.
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 |
Full rule set
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"
]
}
}
]
}
#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 |
Full rule set
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."
}
}
]
}
#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 |
Full rule set
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."
}
}
]
}
#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 |
Full rule set
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
}
}
}
]
}
#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 |
Full rule set
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."
}
}
]
}