# What Is an Agentic Control Plane (ACP)?

The agentic control plane is the layer in the call path between an AI agent and its tools — every tool call checked against your rules before it runs, priced, and recorded, across every harness and framework.

<style>
  .acp-chain-strip {
    display: flex;
    gap: 16px;
    margin: 24px 0 12px;
    align-items: stretch;
  }
  .acp-chain-strip .acp-chain-hop {
    flex: 1;
    min-width: 0;
    padding: 16px 14px;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background: var(--color-surface);
    position: relative;
    box-shadow: 0 1px 3px rgba(91,91,214,0.06);
  }
  .acp-chain-strip .acp-chain-hop:not(:last-child)::after {
    content: "→";
    position: absolute;
    right: -14px;
    top: 50%;
    transform: translateY(-50%);
    width: 22px;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-accent);
    color: #fff;
    font-weight: 700;
    font-size: 13px;
    border-radius: 50%;
    z-index: 2;
  }
  .acp-chain-tag {
    display: inline-block;
    font-family: var(--acp-font-mono, 'JetBrains Mono', monospace);
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 2px 7px;
    border-radius: 3px;
    margin-bottom: 10px;
  }
  .acp-chain-tag.h { color: #4f46e5; background: rgba(79,70,229,0.08); }
  .acp-chain-tag.a { color: #7c3aed; background: rgba(124,58,237,0.08); }
  .acp-chain-tag.t { color: #b45309; background: rgba(217,119,6,0.08); }
  .acp-chain-who { font-size: 14px; font-weight: 600; color: var(--color-text-primary); margin-bottom: 6px; }
  .acp-chain-scope { font-family: var(--acp-font-mono, 'JetBrains Mono', monospace); font-size: 11px; color: var(--color-text-secondary); line-height: 1.6; }
  .acp-chain-scope b { color: var(--color-accent); font-weight: 600; }
  .acp-chain-foot {
    display: flex;
    justify-content: space-between;
    padding: 10px 14px;
    border: 1px dashed var(--color-border);
    border-radius: 8px;
    font-family: var(--acp-font-mono, 'JetBrains Mono', monospace);
    font-size: 11px;
    color: var(--color-text-muted);
    margin-top: 14px;
    flex-wrap: wrap;
    gap: 8px;
  }
  .acp-chain-foot .narrow { color: var(--color-accent); font-weight: 600; }
  @media (max-width: 720px) {
    .acp-chain-strip { flex-direction: column; gap: 22px; }
    .acp-chain-strip .acp-chain-hop:not(:last-child)::after {
      right: 50%;
      top: auto;
      bottom: -18px;
      transform: translateX(50%) rotate(90deg);
    }
  }

  .acp-gate-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    margin-top: 16px;
  }
  .acp-gate-card {
    padding: 18px 16px;
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--color-accent);
    border-radius: 10px;
    background: var(--color-surface);
    box-shadow: 0 1px 3px rgba(91,91,214,0.06);
  }
  .acp-gate-card .gn {
    font-family: var(--acp-font-mono, 'JetBrains Mono', monospace);
    font-size: 10px;
    letter-spacing: 0.12em;
    color: var(--color-accent);
  }
  .acp-gate-card .gt {
    font-size: 15px;
    font-weight: 600;
    color: var(--color-text-primary);
    margin-top: 4px;
  }
  .acp-gate-card .gs {
    font-size: 13px;
    color: var(--color-text-secondary);
    margin-top: 6px;
    line-height: 1.5;
  }
  @media (max-width: 820px) { .acp-gate-grid { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 520px) { .acp-gate-grid { grid-template-columns: 1fr; } }

  .acp-stack-flow {
    display: flex;
    align-items: stretch;
    gap: 0;
    margin: 20px 0;
    flex-wrap: wrap;
  }
  .acp-stack-node {
    flex: 1;
    min-width: 140px;
    padding: 16px 14px;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background: var(--color-surface);
    text-align: center;
  }
  .acp-stack-node.accent {
    border-color: var(--color-accent);
    background: rgba(79,70,229,0.04);
    box-shadow: 0 2px 8px rgba(91,91,214,0.12);
  }
  .acp-stack-node .sn-title { font-size: 14px; font-weight: 600; color: var(--color-text-primary); }
  .acp-stack-node .sn-sub { font-size: 12px; color: var(--color-text-muted); margin-top: 4px; line-height: 1.4; }
  .acp-stack-arrow {
    align-self: center;
    color: var(--color-text-muted);
    font-size: 18px;
    padding: 0 10px;
  }
  @media (max-width: 720px) {
    .acp-stack-flow { flex-direction: column; }
    .acp-stack-arrow { padding: 6px 0; transform: rotate(90deg); }
  }
</style>

# What Is an Agentic Control Plane (ACP)?

An **Agentic Control Plane** (ACP) — also called an agent control plane, and what some teams still call agent governance — is the layer that sits in the call path between an AI agent and the tools it uses. Every tool call the agent makes is checked against your rules before it runs, priced, and recorded, across every harness and framework you run: Claude Code, Codex, Cursor, CrewAI, LangGraph and the rest.

<div style="margin:20px 0 8px;padding:18px 20px;border:1px solid var(--color-border);border-radius:10px;background:var(--color-surface);">
  <p style="margin:0 0 10px;font-size:14px;line-height:1.6;color:var(--color-text-primary);">See this on your own agents in about a minute — one command adds it to Claude Code, Codex, Cursor, and the other harnesses you run:</p>
  <pre data-track="WhatIsACP: TopBox Install Copy" style="margin:0 0 10px;background:var(--color-bg,#fff);border:1px solid var(--color-border);border-radius:8px;padding:10px 14px;overflow-x:auto;"><code>curl -sf https://agenticcontrolplane.com/install.sh | bash</code></pre>
  <p style="margin:0;font-size:12.5px;color:var(--color-text-secondary);">No account? Add <code>--local</code> and every decision stays on your machine. <a href="/getting-started" data-track="WhatIsACP: TopBox Docs Click" style="font-weight:600;">Full getting-started guide &rarr;</a></p>
</div>

Think of it as the permission system your agents would have if they all shared one.

---

## AI doesn't make calls. It makes chains of calls.

A user asks Claude Code to review a PR. Claude delegates to a security subagent. The subagent runs a SAST scan. At depth three, a tool call hits your repo. Without control across the chain, identity is dropped at the first hop, scopes widen, and your audit log is a row that says `api_key=sk-shared`.

That's what an ACP fixes — control that survives the graph.

<div class="acp-chain-strip">
  <div class="acp-chain-hop">
    <span class="acp-chain-tag h">● Human</span>
    <div class="acp-chain-who">Alice</div>
    <div class="acp-chain-scope"><b>github.*</b> · <b>slack.*</b> · <b>jira.*</b><br/>budget $5.00</div>
  </div>
  <div class="acp-chain-hop">
    <span class="acp-chain-tag a">◆ Agent</span>
    <div class="acp-chain-who">PR Reviewer</div>
    <div class="acp-chain-scope"><b>github.pr.*</b><br/>budget $5.00 <span style="color:var(--color-text-muted);">(narrowed)</span></div>
  </div>
  <div class="acp-chain-hop">
    <span class="acp-chain-tag a">◆ Subagent</span>
    <div class="acp-chain-who">Security Scanner</div>
    <div class="acp-chain-scope"><b>secrets.scan</b><br/>budget $1.00 <span style="color:var(--color-text-muted);">(narrowed)</span></div>
  </div>
  <div class="acp-chain-hop">
    <span class="acp-chain-tag t">■ Tool</span>
    <div class="acp-chain-who">sast.run</div>
    <div class="acp-chain-scope">x-user-uid: <b>alice</b><br/><span style="color:#059669;font-weight:600;">ALLOW · 2.3s · $0.14</span></div>
  </div>
</div>

<div class="acp-chain-foot">
  <span>CHAIN · d=3 · root=auth0|alice · tool=sast.run</span>
  <span class="narrow">SCOPE NARROWED 3× · ROOT IDENTITY PRESERVED</span>
</div>

Each hop inherits a narrower slice of the user's permission. Every call carries verified root identity all the way to the tool. Audit reconstructs the whole chain.

---

## What an ACP does: record, learn, control

Three things, on every call, in every harness.

<div class="acp-gate-grid">
  <div class="acp-gate-card"><div class="gn">/ 01</div><div class="gt">Record</div><div class="gs">Every tool and model call, in order, with its cost, latency, the decision, and the identity behind it. Audit-only by default: everything runs and is logged until you write a rule.</div></div>
  <div class="acp-gate-card"><div class="gn">/ 02</div><div class="gt">Learn</div><div class="gs">Any row becomes a standing rule in one click. Agents propose rules from the denials they hit; you confirm them. New workspaces start in shadow, so nothing blocks until you switch to enforce.</div></div>
  <div class="acp-gate-card"><div class="gn">/ 03</div><div class="gt">Control</div><div class="gs">Allow, ask, or deny per tool, per tier (interactive, subagent, background), per person. Budget caps that halt a run. Each agent's declared tool surface, one click to deny what it never uses.</div></div>
</div>

Underneath those three: identity (a workspace key for coding agents; the end user's IdP token on the framework path), PII detection on every call, rate and budget limits, and a structured, queryable audit log. Every hop in a delegation chain passes through the same checks.

---

## What goes wrong without one

<div class="acp-grid-cards">
  <div class="acp-linkcard">
    <div class="acp-linkcard-title">Shadow AI</div>
    <div class="acp-linkcard-desc">Shared API keys passed around Slack. No idea which user made which request. When something breaks, no way to trace it.</div>
  </div>
  <div class="acp-linkcard">
    <div class="acp-linkcard-title">Data leakage</div>
    <div class="acp-linkcard-desc">SSNs, PHI, and access tokens flow into LLM prompts unchecked — straight to a third-party model with no record.</div>
  </div>
  <div class="acp-linkcard">
    <div class="acp-linkcard-title">No audit trail</div>
    <div class="acp-linkcard-desc">"Who accessed patient data through the AI last Tuesday?" If the answer is "we don't know," SOC 2 fails.</div>
  </div>
  <div class="acp-linkcard">
    <div class="acp-linkcard-title">Runaway cost</div>
    <div class="acp-linkcard-desc">One agent loop, 10,000 calls, a month's budget gone overnight. Request counting isn't cost control.</div>
  </div>
</div>

---

## Where it fits in your stack

<div class="acp-stack-flow">
  <div class="acp-stack-node">
    <div class="sn-title">User</div>
    <div class="sn-sub">SSO / OAuth</div>
  </div>
  <div class="acp-stack-arrow">→</div>
  <div class="acp-stack-node">
    <div class="sn-title">LLM Runtime</div>
    <div class="sn-sub">ChatGPT, Claude, agent framework, MCP</div>
  </div>
  <div class="acp-stack-arrow">→</div>
  <div class="acp-stack-node accent">
    <div class="sn-title">Agentic Control Plane</div>
    <div class="sn-sub">Record · Learn · Control</div>
  </div>
  <div class="acp-stack-arrow">→</div>
  <div class="acp-stack-node">
    <div class="sn-title">Your Backend</div>
    <div class="sn-sub">APIs · DBs · tools</div>
  </div>
</div>

For coding agents the plane is a hook inside the harness plus the gateway it reports to; for framework agents it is an SDK wrapper around your tools plus a proxy in front of the model. Same rules, same audit trail, one console.

- **Not an LLM gateway.** Portkey, LiteLLM, and OpenRouter choose *which model* answers. An ACP decides *whether the user is allowed to ask*.
- **Not an agent framework.** LangChain, CrewAI, AutoGen decide *what* an agent does. An ACP decides *whether it's allowed*.
- **Not an API gateway.** Kong and Apigee manage HTTP traffic. An ACP propagates verified human identity through the AI layer and produces identity-attributed audit trails.

Use all of them. They solve different problems at different points in the request flow. [Full comparison →](/comparison)

---

## How identity flows on the framework path

When your agent runs inside an app you built — CrewAI, LangGraph, the Anthropic or OpenAI SDKs — ACP can verify the end user's token and carry it through to your backend, so a tool call is attributed to a person rather than a shared key. Coding agents on a laptop don't need any of this: they are identified by their workspace key and agent identity. For the framework path, the flow is:

The user authenticates with your IdP (Auth0, Okta, Entra ID, Firebase — any OIDC provider) and receives an RS256-signed JWT:

```json
{
  "sub": "auth0|8f3a2b1c9d4e5f6a",
  "aud": "https://api.yourapp.com",
  "scope": "tool:crm:read tool:jira:write",
  "org_id": "org_acme_corp",
  "exp": 1739145600
}
```

The ACP verifies the signature against your IdP's JWKS, extracts the user, checks scope, scans for PII, enforces budget, and routes to your backend with identity injected.

**Without an ACP**, your backend gets:

```
POST /api/crm/contacts
Authorization: Bearer sk-shared-api-key-for-everyone
```

No user identity. No scopes. No way to filter per user.

**With an ACP**, your backend gets:

```
POST /api/crm/contacts
x-user-uid: auth0|8f3a2b1c9d4e5f6a
x-user-scope: tool:crm:read
x-user-org: org_acme_corp
x-request-id: req_7f8a9b0c
x-chain-depth: 3
x-chain-root: auth0|8f3a2b1c9d4e5f6a
```

Verified identity. Scoped permissions. Tenant context. Full chain provenance. `SELECT * WHERE org_id = $1` works again.

---

## When you need one

- You run a coding agent for hours a day and can't say what it did, what it could have done, or what it cost
- You're about to let an agent run unattended, and the checks you rely on live in a prompt
- Your agents take real actions: create tickets, modify records, push code, process transactions
- Every team ships in a different harness or framework and there is no one set of rules across them
- Your model spend surprises you, and per-key limits can't tell you which agent or which step
- You're in a regulated industry and need an identity-attributed record of every call

---

## Get started

<div class="acp-grid-cards">
  <a href="/getting-started" class="acp-linkcard" style="text-decoration:none;" data-track="What-Is: CLI Install">
    <div class="acp-linkcard-title">One-line install →</div>
    <div class="acp-linkcard-desc">One curl registers the hook in Claude Code, Codex, Cursor and the other harnesses you have. Free up to 5 agents; your first audit row in about a minute.</div>
  </a>
  <a href="/install-explained" class="acp-linkcard" style="text-decoration:none;" data-track="What-Is: Local">
    <div class="acp-linkcard-title">Run it on-device →</div>
    <div class="acp-linkcard-desc">Add <code>--local</code>: no account, decisions on your machine, every call logged to a file. What each mode writes, file by file.</div>
  </a>
  <a href="/integrations" class="acp-linkcard" style="text-decoration:none;" data-track="What-Is: Frameworks">
    <div class="acp-linkcard-title">Framework SDKs →</div>
    <div class="acp-linkcard-desc">Wrap your tools with one decorator in CrewAI, LangGraph, the OpenAI or Anthropic SDKs; <code>init()</code> prices the model calls.</div>
  </a>
</div>

---

<details style="margin-top:32px;border:1px solid var(--color-border);border-radius:10px;padding:16px 20px;background:rgba(0,0,0,0.02);">
<summary style="cursor:pointer;font-weight:600;color:var(--color-text-primary);">Background: where this category started — the three-party problem</summary>

Traditional web apps have two parties: a user and a backend. Authentication is solved. Access control follows.

AI apps introduced a third party — the LLM runtime. The user authenticates with the LLM, the LLM calls your backend with a shared API key, and the backend has no idea *who* made the request. Identity is severed. Every control failure in production AI systems traces back to this.

We call this the **three-party problem**: user, LLM, backend — and identity has to flow across all three. It's the clearest framing for *why* the control layer needs to exist. The delegation-chain framing above is the same idea, extended: when an agent calls another agent, identity has to flow across every hop, not just the first one. Three-party trust is the foundation; delegation chains are how it scales.

For the longer write-ups, see [agent-to-agent control](/agent-to-agent) and [agent delegation chains](/what-is-an-agent-delegation-chain).

</details>

---

## Related concepts

- [Agent delegation chains](/what-is-an-agent-delegation-chain) — the authorization primitive behind chain-of-calls control
- [Agentic data plane](/what-is-an-agentic-data-plane) — the execution layer, distinct from the control layer
- [MCP control plane](/what-is-an-mcp-control-plane) — the MCP-specific specialization
- [Runtime authorization](/what-is-runtime-authorization) — per-call policy evaluation, the decision model behind gate 03
- [Agent identity](/agent-identity) — how individual agents are identified
- [Three-axis control](/three-axis-governance) — tool / agent / user ABAC model
- [Reference architecture](/reference-architecture) — the six composable modules in detail

---

[Get started →](/getting-started) · [Agent-to-agent control →](/agent-to-agent) · [Reference architecture →](/reference-architecture) · [GitHub →](https://github.com/agentic-control-plane)

<!-- Structured data: FAQ schema -->

<!-- Structured data: TechArticle schema -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "TechArticle",
  "headline": "What is an Agentic Control Plane?",
  "description": "The definitive guide to agentic control planes — the identity and control layer for AI agents and the agents they call. Covers delegation chains, the six control gates, and where the ACP fits in your stack.",
  "author": {
    "@type": "Person",
    "name": "David Crowe",
    "url": "https://reducibl.com"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Agentic Control Plane",
    "url": "https://agenticcontrolplane.com"
  },
  "datePublished": "2026-02-10",
  "dateModified": "2026-09-02",
  "mainEntityOfPage": "https://agenticcontrolplane.com/what-is-an-agentic-control-plane",
  "keywords": "agentic control plane, agent control plane, agent control, agent identity, agent-to-agent control, delegation chain, LLM identity, MCP control, AI security",
  "proficiencyLevel": "Beginner"
}
</script>

<!-- Structured data: Organization schema -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Agentic Control Plane",
  "url": "https://agenticcontrolplane.com",
  "description": "Open-source Agentic Control Plane — the identity and control layer for AI agents and the agents they call.",
  "foundingDate": "2025",
  "founder": {
    "@type": "Person",
    "name": "David Crowe",
    "url": "https://reducibl.com",
    "jobTitle": "Founder"
  },
  "sameAs": [
    "https://github.com/agentic-control-plane",
    "https://www.npmjs.com/search?q=%40agenticcontrolplane",
    "https://www.linkedin.com/in/mrdavidcrowe"
  ]
}
</script>
