Agent policies
Limits, allow-lists, and approval gates for Agent actions.
An agent policy controls what the MCP server is allowed to do on behalf of your workspace. Policies live at the organization + environment level. Every agent session in the same workspace sees the same rules, so new sessions don't have to be re-authorized.
If no policy exists, defaults are conservative: only read-only tools are allowed, every write requires approval, and no spending limits are set.
Fields
| Field | Type | Default | Notes |
|---|---|---|---|
allowed_tools | AgentToolName[] | the read-only set | Whitelist of tool names. |
per_action_limit | decimal string | null | null | Max amount per single create_payment_order. |
daily_limit | decimal string | null | null | Cumulative cap per rolling 24h. |
require_approval | boolean | true | When true, every non-read tool returns pending_approval. |
per_action_limit and daily_limit are decimals in settlement-asset units
("100.00" means 100 USDC). They only apply to tools that carry an amount
argument: currently create_payment_order.
allowed_tools is enforced before any limit check. A tool that is not in the
list returns 403 tool … not allowed by policy.
Read the current policy
curl -X GET $STABLEOPS_API_URL/v1/agent/policy \
-H "authorization: Bearer $STABLEOPS_API_KEY" \
-H 'x-stableops-env: sandbox'{
"id": "agp_01",
"allowed_tools": ["get_order", "list_events", "list_webhook_deliveries"],
"per_action_limit": null,
"daily_limit": null,
"require_approval": true
}Update the policy
POST /v1/agent/policy performs an upsert. Only fields you send are touched.
curl -X POST $STABLEOPS_API_URL/v1/agent/policy \
-H "authorization: Bearer $STABLEOPS_API_KEY" \
-H 'x-stableops-env: sandbox' \
-H 'content-type: application/json' \
-d '{
"allowed_tools": [
"get_order",
"list_events",
"create_payment_order",
"request_action_approval"
],
"per_action_limit": "100.00",
"daily_limit": "500.00",
"require_approval": false
}'Send null to clear a limit:
{ "per_action_limit": null }Decision flow
tool call ─▶ /v1/agent/actions
│
├─ tool in allowed_tools? no ─▶ 403 not allowed
│
├─ amount ≤ per_action_limit? no ─▶ 403 exceeds per_action_limit
│
├─ amount + last 24h ≤ daily_limit? no ─▶ 403 exceeds daily_limit
│
├─ require_approval == true? yes ─▶ pending_approval (queue for human)
│ no ─▶ auto_allowed (agent proceeds)
└─ read-only tool? ─▶ auto_allowedThe dashboard surfaces every pending_approval action, the requested
arguments, and the agent session that asked for it. Approving an action
unblocks the tool call on the next retry; rejecting it records the operator's
reason in the audit log.
Recommended profiles
Strict: fully manual review, useful for the first live integration:
{
"allowed_tools": ["get_order", "list_events", "list_webhook_deliveries"],
"require_approval": true
}Capped: let the agent open small orders on its own, escalate the rest:
{
"allowed_tools": [
"get_order",
"list_events",
"create_payment_order",
"request_action_approval"
],
"per_action_limit": "50.00",
"daily_limit": "500.00",
"require_approval": false
}Audit-only: keep approvals on but let read tools fan out widely:
{
"allowed_tools": ["get_order", "list_events", "list_webhook_deliveries"],
"require_approval": true
}Tips
- Keep
per_action_limitanddaily_limitset even in sandbox. Agents cannot exceed them, and you'll catch policy drift on the way to live. - Revoking an agent session is separate from the policy: it blocks one conversation; updating the policy blocks every session.
- Approvals are stamped with the operator's id (the dashboard user or
the
approver_idyou send to/v1/agent/actions/:id/approve). The audit trail is queryable per session.
How is this guide?
Last updated