Skip to content
Agentic Control Plane

Policies

A policy decides what an agent’s tool calls are allowed to do — allow, deny, rate-limit, or redact — and whether the workspace is enforcing those decisions or just watching. These endpoints read and write that policy from code. They write the same documents the console does; the console is just another client.

https://api.agenticcontrolplane.com/<workspace>/admin

Governance endpoints carry your workspace slug in the path (it must match the slug in your key). Writes require a key created by an owner or admin of the workspace.

The four layers

Policy is evaluated in layers, most-specific wins. Each layer overrides the one below it:

Layer Endpoint Scope
Workspace /admin/workspacePolicy The baseline for everything in the workspace.
Role /admin/rolePolicies/{role} Per-role overrides — owner, admin, member.
Agent type /admin/agentTypePolicies/{key} Per-agent-identity overrides, keyed client::tier::name.
User /admin/userPolicies/{uid} Per-user overrides — including stricter rules a user sets on themselves.

At request time ACP merges the layers that apply to the caller and the agent, and the strictest decision holds. This page documents the workspace layer in full; the other three take the same body shape at their own paths.

The policy object

{
  "mode": "enforce",
  "defaults": {
    "interactive": { "permission": "allow", "rateLimit": 100, "transform": "log" },
    "subagent":    { "permission": "allow", "rateLimit": 60,  "transform": "redact" },
    "background":  { "permission": "deny" },
    "api":         { "permission": "allow", "rateLimit": 30,  "transform": "redact" }
  },
  "tools": {
    "github.create_issue": {
      "interactive": { "permission": "allow", "rateLimit": 10, "transform": "log" }
    }
  }
}
Field Type Description
mode "enforce" | "audit" enforce applies decisions; audit logs what would have happened without blocking anything. Start in audit, watch the logs, then flip to enforce.
defaults object Per-tier rules applied to every tool unless a tools entry overrides them. Tiers: interactive, subagent, background, api.
tools object Per-tool overrides, each keyed by tool name, then by tier.

Each rule is:

Field Type Description
permission "allow" | "deny" Whether the call may proceed.
rateLimit number Optional. Max calls per window before the call is throttled.
transform "log" | "redact" log records the call as-is; redact strips detected secrets/PII from what’s logged and passed on.

The tiers describe how the agent is running, not who wrote it: interactive (a human in the loop), subagent (a delegated sub-task), background (autonomous/scheduled), api (driven by an API trigger). Governing by tier lets you, say, allow a tool interactively but deny it to a background run.

Read the workspace policy

GET /<workspace>/admin/workspacePolicy

Readable by any member.

curl -s "$ACP/acme/admin/workspacePolicy" \
  -H "Authorization: Bearer $ACP_KEY"

Returns the policy object, or {} if none is set (defaults apply).

Write the workspace policy

PUT /<workspace>/admin/workspacePolicy

A merge update — send only what you want to change; unset fields are left intact. Owner/admin only.

curl -sX PUT "$ACP/acme/admin/workspacePolicy" \
  -H "Authorization: Bearer $ACP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "enforce",
    "defaults": {
      "background": { "permission": "deny" },
      "interactive": { "permission": "allow", "transform": "log" }
    }
  }'
{ "ok": true }

A common rollout: set "mode": "audit", run your agents, read the audit log to see which tools they actually touch, codify rules for those, then PUT { "mode": "enforce" }.

Clear the workspace policy

DELETE /<workspace>/admin/workspacePolicy

Removes the workspace layer entirely; the built-in defaults apply at the next call. Useful for resetting a test workspace. Owner/admin only.

curl -sX DELETE "$ACP/acme/admin/workspacePolicy" \
  -H "Authorization: Bearer $ACP_KEY"

The other three layers

rolePolicies, agentTypePolicies, and userPolicies take the same body shape at their own paths, with the layer’s key as the last path segment:

# Per-role: tighten what members can do
curl -sX PUT "$ACP/acme/admin/rolePolicies/member" \
  -H "Authorization: Bearer $ACP_KEY" -H "Content-Type: application/json" \
  -d '{ "defaults": { "interactive": { "permission": "allow", "rateLimit": 50 } } }'

# Per-agent-type: rein in one agent identity (client::tier::name)
curl -sX PUT "$ACP/acme/admin/agentTypePolicies/Claude%20Code::background::" \
  -H "Authorization: Bearer $ACP_KEY" -H "Content-Type: application/json" \
  -d '{ "tools": { "shell.exec": { "background": { "permission": "deny" } } } }'

# Per-user: a user can set stricter rules on themselves
curl -sX PUT "$ACP/acme/admin/userPolicies/uid_123" \
  -H "Authorization: Bearer $ACP_KEY" -H "Content-Type: application/json" \
  -d '{ "mode": "enforce", "defaults": { "api": { "permission": "deny" } } }'

Each layer supports GET, PUT, and DELETE the same way the workspace layer does. userPolicies allows self-edits (a member tightening their own rules) in addition to admin edits.

The conceptual model

This is the reference. For why the layers merge the way they do, the tier model, and the detection passes behind redact, read Policies & scopes and the governance model.

Next

See what policy did → The policy model →