# ACP policy bundles (Rego / OPA)

## Design principles (read first)

- **Organize by governance domain** (refunds, pii, payments, …) — **not** by agent (`fraud-agent.rego` is an anti-pattern).
- **Do not** evaluate every agent against every policy file; the interceptor should **route** to the relevant domain only.
- **Agents differ via input** (role, tenant, risk, claims) inside one domain policy — one Rego bundle, many agents.
- **Target:** per-domain OPA paths (e.g. `acp/refunds/decision`, `acp/pii/access`); **MVP:** flat files + `router.rego` routes on `input.tool` (same idea, single decision entrypoint).

See [`../../architectureskills.md`](../../architectureskills.md) — *Policy organization*.

---

## MVP layout (current)

All policies load under package `acp` via `router.rego`, which routes on `input.tool` to a **domain bundle** (not per-agent files).

| Tool | Policy file | Example actions | Test scenarios |
|------|-------------|-----------------|----------------|
| `refund_api` | `refund.rego` | `issue_refund` | Allow &lt;5k; escalate &gt;5k + risk&gt;0.8; deny &gt;10k |
| `ledger_api` | `ledger.rego` | `get_balance`, `post_debit` | Allow reads; escalate debits 5k–25k; deny &gt;25k |
| `wire_transfer_api` | `transfer.rego` | `send_wire` | Blocked agents; escalate large + risky |
| `fraud_score_api` | `fraud.rego` | `get_score`, `block_account` | Deny low-confidence blocks; escalate high risk |
| `customer_data_api` | `pii.rego` | `read_profile`, `read_ssn`, `export_all` | Clearance + approval for SSN |
| `admin_api` | `admin.rego` | `list_users`, `delete_user` | Requires `extra.role: admin` |
| `audit_export_api` | `export.rego` | `export_records` | Volume limits + `extra.dpa_approved` |

Unknown tools **default allow** (`acp/default`) for MVP exploration.

## Run tests

```bash
cd interceptor/policies
opa test .
```

Or via Docker:

```bash
docker run --rm -v "$(pwd)/interceptor/policies:/policies" openpolicyagent/opa:0.69.0 test /policies
```

## Example `POST /tool-call` bodies

**Refund — escalate**

```json
{
  "agent_id": "transaction-agent",
  "tool": "refund_api",
  "action": "issue_refund",
  "amount": 6000,
  "risk_score": 0.85
}
```

**Wire — deny blocked agent**

```json
{
  "agent_id": "bad-agent",
  "tool": "wire_transfer_api",
  "action": "send_wire",
  "amount": 1000,
  "extra": { "blocked_agents": ["bad-agent"] }
}
```

**PII — escalate SSN (full clearance, no approval)**

```json
{
  "agent_id": "compliance-agent",
  "tool": "customer_data_api",
  "action": "read_ssn",
  "extra": { "clearance": "full", "approved": false }
}
```

**Admin — allow**

```json
{
  "agent_id": "ops-agent",
  "tool": "admin_api",
  "action": "list_users",
  "extra": { "role": "admin" }
}
```

**Export — deny bulk without DPA**

```json
{
  "agent_id": "compliance-agent",
  "tool": "audit_export_api",
  "action": "export_records",
  "extra": { "record_count": 5000, "dpa_approved": false }
}
```

Restart OPA after policy changes: `docker compose -f interceptor/deployments/docker/docker-compose.yml restart opa`
