# Policies &amp; scopes — ACP

How ACP decides allow / flag / ask / deny on every tool call. Three policy axes (tool, agent, user), scopes, most-restrictive-wins, audit vs enforce mode.

# Policies &amp; scopes

The hook sends each tool call to the gateway before it runs, and ACP decides `allow` / `flag` / `ask` / `deny` for it based on three layered policy axes. Redaction is a separate transform on tool *output*, covered [below](#pii-prompt-injection-and-secrets). This page is the mental model &mdash; the console is where you actually configure the rules.

## The four outcomes

- **`allow`** &mdash; the tool runs. The terminal prints nothing; the row appears on [Activity](https://cloud.agenticcontrolplane.com/activity) (or in `~/.acp/audit.jsonl` with `--local`).
- **`flag`** &mdash; the tool runs, and the row is marked for review.
- **`ask`** &mdash; the call is held for a human. The agent sees `[ACP] Approval required: <reason>`; the request appears on the Approvals page and the workspace owner gets an email. Approving grants a single retry within the grant window; unanswered requests expire and count as denied. Details on [Approvals](/docs/approvals).
- **`deny`** &mdash; the call is blocked. The agent sees `[ACP] Denied by policy: <reason>`.

Rules are per tool &mdash; a prefix like `Bash.rm`, `Bash.git-push`, or `WebFetch.<host>` &mdash; and per agent tier: `interactive`, `subagent`, `background`, `api`.

## The three axes

Every `/govern/tool-use` call is evaluated against three axes of policy, in this order:

### 1. Tool policies — workspace-wide defaults

**Dashboard &rarr; Policies &rarr; Tool Policies.** Workspace-wide allowlists and required scopes per tool. The question these answer: *"Is anyone in this workspace allowed to call `github.repos.delete`? What scope do they need?"*

This is the first-class way to disable a dangerous tool for everyone, or require a sensitive scope (`github.admin`) before a tool can be called.

### 2. Agent policies — per-tier rules

**Dashboard &rarr; Policies &rarr; Agent Policies.** Rules per agent tier: `interactive`, `subagent`, `background`, `api`. The question these answer: *"What can a background cron agent do that my interactive Claude Code session can&rsquo;t?"*

Typical pattern: lock down background agents tightly (read-only, rate-limited, no destructive ops), leave interactive agents permissive, keep subagents in between.

### 3. User policies — per-identity overrides

**Dashboard &rarr; Policies &rarr; User Policies.** Overrides per user identity. The question these answer: *"Alice gets to run `stripe.charge.*` because she&rsquo;s in finance; Bob does not."*

Use these for carve-outs, not broad strokes. If you&rsquo;re writing user policies for most of your team, the rule probably belongs in tool or agent policies instead.

## Most-restrictive-wins

The layers intersect. For any one tool and tier, the effective permission is the most restrictive one any applicable layer sets &mdash; workspace, role, agent type, or user &mdash; so tightening at any layer tightens the result and no layer can loosen what another has denied. Within a layer, a more specific tool entry (`Bash.curl`) decides over a broader one (`Bash`), so you can allow a family and deny one member of it.

| Workspace | Agent type | User | Result |
|---|---|---|---|
| allow | allow | allow | **allow** |
| allow | allow | deny | **deny** (the user tightened it) |
| allow | deny | &mdash; | **deny** (the agent type tightened it) |
| deny | allow | &mdash; | **deny** (workspace deny holds; a layer cannot loosen it) |
| allow | ask | allow | **ask** (the strictest of the three) |

Above every layer sit the two floors that nothing can loosen: the hardline catastrophe list (`rm -rf /`, disk wipes, force-push to a protected branch, and the like) and policy tamper (any write to the files that control the agent).

## Scopes

Scopes are short strings that describe tool capabilities (`github.pr.write`, `slack.read`, `stripe.charge.*`). They serve two jobs:

1. **Required on the tool side.** The tool policy says "`github.pr.create` requires scope `github.pr.write`."
2. **Granted to the caller.** The JWT (or the agent&rsquo;s tier configuration) carries a set of scopes. If the caller&rsquo;s scopes don&rsquo;t cover the tool&rsquo;s required scope, the call is denied.

Scopes support wildcards: `github.*` covers `github.pr.write`, `github.issue.create`, etc. `*` covers everything &mdash; use with care.

For delegation chains (agent calling agent calling tool), scopes narrow at each hop. See [agent-to-agent control](/agent-to-agent) for details.

## Audit mode vs. enforce mode

A workspace is in one of two modes:

- **Audit mode** &mdash; where every new workspace starts. Everything is recorded, nothing is blocked. Shadow evaluation shows `[ACP shadow] That was <tool> &mdash; <why>` in the agent transcript for calls the starter policy would have paused, so you see what enforce would do before it does it.
- **Enforce mode** &mdash; decisions are honored. `ask` holds the call, `deny` blocks it and returns the reason to the agent. Switch on the **Policies** page.

**Recommended rollout:** stay in audit mode for a few days. Read the shadow notices and the rows on Activity. Adjust the rules until the false-positive rate is where you want it. Then switch to enforce.

This is how you avoid the common failure mode where a well-meaning tightening of policy takes down half your agent fleet because the rules didn&rsquo;t match reality.

## Set a rule from a row

From any row on **Activity** or **Sessions**, choose **Ask next time**, **Deny next time**, or **Allow always**. That writes a standing rule for that tool and tier &mdash; no policy editor needed. Agents can also propose a rule from a denial they hit (`acp_propose_rule`); proposals wait on the Policies page until you confirm them.

## Ran ungoverned

When the gateway is unreachable, interactive calls proceed with a loud `[ACP] &#9888; UNGOVERNED` notice in the terminal, and the row is marked *ran ungoverned* in Activity. Unattended tiers (`subagent`, `background`, `api`) stay blocked until the gateway answers.

## PII, prompt injection, and secrets

These are handled by the **content-scanning** layer, which runs on the tool&rsquo;s *output* (and optionally its input). Unlike allow/deny, the primary decision type here is `redact` &mdash; the output is rewritten with sensitive strings replaced.

The three detectors today:

- **PII.** Six high-precision types: emails, phone numbers, SSNs, credit-card numbers, IBANs, IP addresses. Default policy: `detect` (SSN and credit card are hard-blocked regardless of policy); `redact` is a policy you enable.
- **Prompt injection.** Heuristic match against known injection patterns in tool output (especially web fetches). Default policy: `flag` (log but pass through); set to `redact` or `deny` for high-stakes agents.
- **Secrets.** API keys, tokens, private keys in tool output. Default policy: `redact`.

Each detector has per-agent-tier policy. A researcher bot reading public docs can have lax settings; a customer-service bot touching real records should redact aggressively.

## What you won&rsquo;t find here

This page is conceptual. For field-level details &mdash; exact JSON schema of policy objects, scope inheritance rules, the API for bulk-importing policies &mdash; see the [API reference](/docs/api/reference). The [Activity log](https://cloud.agenticcontrolplane.com/activity) is the source of truth for what policies actually did on a given call.

## Related

- [How a call is decided](/docs/governance-model) &mdash; how policy fits into the per-call pipeline.
- [Approvals](/docs/approvals) &mdash; what a held call looks like, the grant window, expiry.
- [Agent-to-agent control](/agent-to-agent) &mdash; scope narrowing across delegation chains.
- [Rules by tool, tier, and user](/three-axis-governance) &mdash; the broader identity / policy / observability frame.
