Skip to content

Policies

Policies: Agent Governance and Access Control

Section titled “Policies: Agent Governance and Access Control”

Policies are rules that govern what an agent can do:

  • Which tools it can/can’t call
  • How many actions per hour
  • How much money it can spend per day
  • Cost per tool

Policies are the guardrails that keep agents safe.

{
"agent_id": "support_bot",
"allowed_tools": [
"send_email",
"read_knowledge_base",
"create_ticket"
],
"blocked_tools": [
"delete_user",
"process_refund"
],
"max_actions_per_hour": 100,
"max_spend_usd_per_day": 500.00,
"max_calls_per_tool": {
"send_email": 200,
"create_ticket": 50
},
"pricing_rules": [
{"tool": "send_email", "price_usd": 0.001},
{"tool": "create_ticket", "price_usd": 0.05},
{"tool": "read_knowledge_base", "price_usd": 0.0}
]
}
ComponentPurpose
allowed_toolsWhitelist of tools this agent can call
blocked_toolsBlacklist of tools this agent cannot call
max_actions_per_hourRate limit: max actions per hour
max_spend_usd_per_dayBudget: max USD spend per day
max_calls_per_toolPer-tool daily limits
pricing_rulesCost in USD per tool call

Terminal window
curl -X POST https://api.onceonly.tech/v1/policies/support_bot \
-H "Authorization: Bearer once_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "support_bot",
"allowed_tools": ["send_email", "read_knowledge_base"],
"max_actions_per_hour": 100
}'

Response:

{
"agent_id": "support_bot",
"policy": {
"allowed_tools": ["send_email", "read_knowledge_base"],
"max_actions_per_hour": 100
}
}
Terminal window
curl -X POST https://api.onceonly.tech/v1/policies/billing_bot \
-H "Authorization: Bearer once_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "billing_bot",
"allowed_tools": [
"send_email",
"read_invoice",
"process_payment",
"create_refund"
],
"blocked_tools": [
"delete_invoice",
"delete_payment_history"
],
"max_actions_per_hour": 500,
"max_spend_usd_per_day": 10000,
"max_calls_per_tool": {
"send_email": 1000,
"process_payment": 200,
"create_refund": 50
},
"pricing_rules": [
{"tool": "send_email", "price_usd": 0.001},
{"tool": "read_invoice", "price_usd": 0.0},
{"tool": "process_payment", "price_usd": 0.1},
{"tool": "create_refund", "price_usd": 0.1}
]
}'

For convenience, here are copy-paste templates you can customize:

For agents that should only read, never write:

Example Policy:

{
"allowed_tools": ["read_invoice", "read_user_data", "read_logs"],
"blocked_tools": ["create", "update", "delete"],
"max_actions_per_hour": 200,
"max_spend_usd_per_day": 10,
"pricing_rules": [
{"tool": "read_invoice", "price_usd": 0.0},
{"tool": "read_user_data", "price_usd": 0.0},
{"tool": "read_logs", "price_usd": 0.0}
]
}
TemplateUse CaseMax Actions/hrMax Spend/day
strictRead-only, low-risk100$10
moderateGeneral support500$100
permissivePower user, trusted2000$1000
read_onlyAnalytics, reports1000$0
support_botCustomer support200$50

When an agent attempts an action:

POST /v1/ai/lease
{
"agent_id": "support_bot",
"key": "email_customer_123",
"tool": "send_email",
"metadata": {"customer_id": "123", "spend_estimate": 0.001}
}
OnceOnly Policy Check:
┌─ Tool allowed?
│ allowed_tools contains "send_email"? YES ✓
│ blocked_tools contains "send_email"? NO ✓
├─ Rate limit OK?
│ Actions this hour: 45
│ Max per hour: 100
│ 45 < 100? YES ✓
├─ Per-tool limit OK?
│ Calls to send_email today: 180
│ Max for send_email: 200
│ 180 < 200? YES ✓
└─ Budget OK?
Estimated cost: $0.001
Spent today: $49.50
Daily budget: $50
$49.50 + $0.001 < $50? YES ✓
All checks pass → ALLOWED ✓
Return: {"status": "acquired", ...}

Every policy decision is logged:

{
"ts": 1705322400,
"agent_id": "support_bot",
"tool": "send_email",
"allowed": true,
"decision": "executed",
"policy_reason": "ok",
"risk_level": "low",
"spend_usd": 0.001,
"policy_version": "v1"
}
{
"ts": 1705322500,
"agent_id": "support_bot",
"tool": "delete_user",
"allowed": false,
"decision": "blocked",
"policy_reason": "tool_not_in_allowed_list",
"risk_level": "medium"
}
{
"ts": 1705322600,
"agent_id": "support_bot",
"tool": "send_email",
"allowed": false,
"decision": "blocked",
"policy_reason": "rate_limit_exceeded",
"risk_level": "medium",
"message": "Max 100 actions/hour, already at 100"
}
{
"ts": 1705322700,
"agent_id": "billing_bot",
"tool": "process_payment",
"allowed": false,
"decision": "blocked",
"policy_reason": "budget_exceeded",
"risk_level": "critical",
"message": "Max $10,000/day, already spent $10,000"
}

{
"agent_id": "support_bot",
"allowed_tools": [
"send_email",
"create_ticket",
"read_knowledge_base",
"read_customer_data"
],
"blocked_tools": [
"delete_customer",
"refund_payment",
"update_invoice"
],
"max_actions_per_hour": 150,
"max_spend_usd_per_day": 25,
"max_calls_per_tool": {
"send_email": 500,
"create_ticket": 100
},
"pricing_rules": [
{"tool": "send_email", "price_usd": 0.001},
{"tool": "create_ticket", "price_usd": 0.05},
{"tool": "read_knowledge_base", "price_usd": 0.0},
{"tool": "read_customer_data", "price_usd": 0.0}
]
}

Safety features:

  • Can’t delete customers or refund payments (blocked)
  • Limited to 150 actions/hour (DoS prevention)
  • Limited to $25/day spend
  • Limited to 500 emails/day (spam prevention)
{
"agent_id": "billing_bot",
"allowed_tools": [
"send_invoice",
"process_payment",
"create_refund",
"read_invoice",
"read_payment_history",
"update_customer_billing"
],
"blocked_tools": [
"delete_customer",
"delete_invoice_history"
],
"max_actions_per_hour": 500,
"max_spend_usd_per_day": 50000,
"max_calls_per_tool": {
"process_payment": 300,
"create_refund": 100,
"send_invoice": 1000
},
"pricing_rules": [
{"tool": "send_invoice", "price_usd": 0.001},
{"tool": "process_payment", "price_usd": 0.01},
{"tool": "create_refund", "price_usd": 0.02},
{"tool": "read_invoice", "price_usd": 0.0},
{"tool": "read_payment_history", "price_usd": 0.0},
{"tool": "update_customer_billing", "price_usd": 0.005}
]
}

High trust but still guarded:

  • Can process payments and refunds (trusted operations)
  • Can’t delete historical records (audit trail preserved)
  • Still has daily budget limits
  • Per-tool limits prevent abuse
{
"agent_id": "analytics_bot",
"allowed_tools": [
"read_all_data",
"generate_report",
"export_csv"
],
"blocked_tools": [],
"max_actions_per_hour": 500,
"max_spend_usd_per_day": 10,
"max_calls_per_tool": {
"read_all_data": 1000,
"generate_report": 100,
"export_csv": 50
},
"pricing_rules": [
{"tool": "read_all_data", "price_usd": 0.0},
{"tool": "generate_report", "price_usd": 0.001},
{"tool": "export_csv", "price_usd": 0.005}
]
}

Minimal risk:

  • Only reads data, can’t modify anything
  • Very low spend budget (mostly free reads)
  • High action limit (analysis requires many reads)

Update a policy to add/remove tools or change limits:

Terminal window
curl -X POST https://api.onceonly.tech/v1/policies/support_bot \
-H "Authorization: Bearer once_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "support_bot",
"allowed_tools": [
"send_email",
"create_ticket",
"read_knowledge_base",
"process_refund" # NEW!
],
"max_actions_per_hour": 200, # Increased
"max_spend_usd_per_day": 100 # Increased
}'

When to update:

  • Agent needs new permissions
  • Rate limits need adjustment
  • New tools become available
  • Suspected abuse pattern

Get audit logs for an agent:

Terminal window
curl -H "Authorization: Bearer once_live_xxxxxxxxxxxxx" \
"https://api.onceonly.tech/v1/agents/support_bot/logs?limit=50"

Response:

[
{
"ts": 1705322400,
"agent_id": "support_bot",
"tool": "send_email",
"allowed": true,
"decision": "executed",
"policy_reason": "ok",
"risk_level": "low"
},
{
"ts": 1705322450,
"agent_id": "support_bot",
"tool": "delete_user",
"allowed": false,
"decision": "blocked",
"policy_reason": "tool_not_in_allowed_list",
"risk_level": "medium"
}
]

Monitor logs for patterns:

def check_for_abuse(agent_id: str):
"""Detect suspicious activity patterns"""
logs = get_agent_logs(agent_id, limit=200)
blocked_count = sum(1 for log in logs if log["allowed"] == False)
budget_blocks = sum(1 for log in logs if "budget" in log.get("policy_reason", ""))
rate_blocks = sum(1 for log in logs if "rate_limit" in log.get("policy_reason", ""))
if blocked_count > 10:
logger.warning(f"Agent {agent_id} had {blocked_count} blocked actions")
if budget_blocks > 0:
logger.warning(f"Agent {agent_id} exceeded budget {budget_blocks} times")
# Consider disabling the agent
disable_agent(agent_id, reason="repeated_budget_violations")
if rate_blocks > 3:
logger.warning(f"Agent {agent_id} exceeded rate limit {rate_blocks} times")
# Consider lowering limits
update_policy(agent_id, max_actions_per_hour=50)

  1. Start restrictive — Begin with minimal permissions, expand as needed
  2. Use allowed_tools — Whitelist beats blacklist
  3. Set realistic limits — Account for peak usage
  4. Monitor blocks — High block rate indicates too-strict policies
  5. Version policies — Track changes over time
  6. Use templates — Start from templates and override
# Good policy progression
policy = {
"agent_id": "new_support_bot",
"allowed_tools": ["send_email"],
"max_actions_per_hour": 50,
"max_spend_usd_per_day": 10
}
# After 1 week of safe operation, expand
update_policy({
"allowed_tools": ["send_email", "create_ticket"],
"max_actions_per_hour": 100,
"max_spend_usd_per_day": 25
})
  1. Don’t use only blocked_tools — Whitelist is safer
  2. Don’t ignore policy blocks — They’re alerts
  3. Don’t set limits too low — Causes agent to fail
  4. Don’t allow write access by default — Reads only
  5. Don’t set unlimited spend — Always cap budget

Different OnceOnly plans have different policy capabilities:

FeatureFreeStarterProAgency
Basic policies-
Rate limits-
Budget controls-
Policy templates--
Per-tool limits--
Pricing rules--
Advanced risk scoring---
Multi-agent policies--

  • Policies define agent permissions and limits
  • Allowed/blocked tools control access
  • Rate & budget limits prevent abuse
  • Pricing rules track costs
  • Audit logs show all decisions
  • Templates provide safe starting points
  • Monitoring detects violations

Next, learn about Audit Logging to investigate agent behavior.