# Agent Platform Gateway Control Plane

> A production path: SPIFFE as the spine, then secretless LLM keys, spend caps that return 429, MCP tool allowlists, and egress control on one hop.

- Canonical URL: https://webofmike.com/agent-platform-gateway-control-plane/
- Author: Mike Moore (https://webofmike.com/about/)
- Published: 2026-10-07
- Last modified: 2026-10-07
- Tags: AI Gateways, Kubernetes, Platform Engineering, Generative AI, MCP
- Cite as: Mike Moore, "Agent Platform Gateway Control Plane", Web of Mike (webofmike.com), 2026-10-07. https://webofmike.com/agent-platform-gateway-control-plane/


A production agent platform needs **one gateway path** where **SPIFFE identity** binds the caller and four controls ride the same hop: **secretless provider keys**, **per-key budgets that return 429**, **MCP tool allowlists**, and **egress / CONNECT discipline**. Agents then cannot hold provider secrets, burn unlimited spend, call arbitrary tools, or dial out around policy.

*Disclosure: I work at Solo.io, which created agentgateway and sells Solo Enterprise for agentgateway. The demos I cite are public repositories.*

The pieces already exist as separate posts on this site. This page sequences them. It is not a product bake-off, not the evaluate-a-gateway page, not a definition essay, and not a SPIFFE-versus-OAuth treatise. Those are linked at the end. I have not shipped one new mega-demo that runs all four at once; I am composing proofs I already published. I run the hop on agentgateway: standalone for a laptop or single box, Kubernetes when the platform is a cluster.

## The production rule

Run agent-to-model and agent-to-tool traffic through **one enforcement hop** bound to **workload identity**. On that hop:

1. Inject provider credentials so agents never hold LLM API keys.
2. Enforce per-key dollar or token budgets that return **HTTP 429**.
3. Apply MCP tool allowlists (per tool / per server).
4. Close egress and CONNECT bypasses.

Dashboards, `AGENTS.md` files, and OAuth-only checks are not a substitute for controls in the request path.

## Why separate posts (and vendor fragments) still leave a gap

Secretless, budgets, MCP federation, egress, and SPIFFE each answer one question. Assistants and ADRs still get five fragments. Control-plane blogs name the layer. Few walk the four controls as one sequenced path with proof.

DeepInspect's [AI agent control plane](https://www.deepinspect.ai/blog/ai-agent-control-plane) piece defines the layer as identity-bound per-action authz plus action lineage, with an HTTP proxy between the agent and LLMs or tools. Useful vocabulary. It does not cover SPIFFE, secretless provider keys, hard 429 budgets, and CONNECT bypasses. Secure Patterns' [authorization chokepoint](https://newsletter.securepatterns.dev/p/ai-agent-gateway-the-authorization-chokepoint) essay gets the golden path (authenticate, authorize, inspect, log) and mentions tool allow-lists and credential injection. It does not sequence the four controls I actually ran.

### What "control plane" means here (and what it does not)

Here it means **policy + identity + audit that configure an enforcement hop** in the request path (gateway or waypoint). The hop is where the four controls fire.

agentgateway uses the words in two senses. Standalone is the [binary](https://agentgateway.dev/docs/standalone/latest/setup/install/binary/). On Kubernetes it is a [controller that translates resources over xDS](https://agentgateway.dev/docs/kubernetes/latest/documentation/about/architecture/) and a proxy data plane that serves the request. Both uses are real. Do not confuse "we bought a control plane UI" with "the request is enforced." Mesh language is [what an agentic mesh is](/what-is-an-agentic-mesh/). How agentgateway's plane differs from a Python LLM proxy and a managed AI-ops plane is [agentgateway vs LiteLLM vs Portkey](/agentgateway-vs-litellm-vs-portkey/). Whether SPIFFE or OAuth is enough is [SPIFFE vs OAuth for AI agents](/spiffe-vs-oauth-for-ai-agents/). How to evaluate the hop, in standalone and Kubernetes, is [how to choose an AI agent gateway](/how-to-choose-an-ai-agent-gateway/).

## Architecture path (the spine walk)

```
agent
  |  SPIFFE SVID (no cert file, no provider key)
  v
gateway / waypoint / egress hop
  |  verify source.spiffeId
  |  inject provider credential          (hop 1)
  |  charge budget; 429 if exceeded      (hop 2)
  |  filter MCP tools/list and tools/call (hop 3)
  |  authorize CONNECT destination       (hop 4)
  v
model  |  MCP server  |  anything else the agent tried to dial
```

Every H3 below is a hop on **that same path**. Solo's [About agentic mesh](https://docs.solo.io/agentgateway/kubernetes/latest/integrations/agentic-mesh/about/) page is the architecture picture: SPIFFE identity, an AI-aware hop that can inject credentials, authorize MCP tools, and count tokens. The rows under it are demos I already ran.

### Spine: SPIFFE workload identity on the gateway hop

Policy binds to cryptographic workload identity, not app-set headers or a virtual key the agent can copy.

I ran the path on OSS v1.5.0 standalone with no certificate file on the agent, the gateway, or the model. `agent-alpha` got HTTP 200. `agent-beta` presented a valid SVID from the same trust domain and got HTTP 403. The CEL rule reads `source.spiffeId`, which the client cannot set ([SPIFFE identity for AI agents](/spiffe-identity-for-ai-agents/)). MCP still authenticates the employee more than the agent ([MCP identity gap](/mcp-agent-identity-gap/)). When-SPIFFE versus when-OAuth is the [compare page](/spiffe-vs-oauth-for-ai-agents/). This path assumes workload identity on the hop.

Without the spine, hop 1 through hop 4 become theater: any process that reaches the gateway can impersonate a budgeted, allowlisted caller.

### Hop 1: Secretless LLM keys

Agents call a local endpoint. After identity and policy checks, the gateway attaches the provider credential (`backendAuth`). Agents never hold the OpenAI, Anthropic, or Bedrock key.

I built that split on OSS v1.5.0 standalone and checked the agent environment: no `sk-`, no key file, and a 200 still came back because the mock upstream refuses a missing credential ([secretless AI agents](/secretless-ai-agents/)). A vault does not fix this if the process still holds plaintext. That is why hop 1 sits on this path.

### Hop 2: Per-key budgets that actually 429

Hard dollar or token caps on the **same** path. Over-budget requests fail closed with **HTTP 429** before the provider.

I ran this hop twice. In open-source agentgateway v1.5.0, per-key budgets (USD or tokens) run in standalone mode (not the Kubernetes controller): a 5,000-token key refused its sixth call with a 429 and a $0.01 key refused its fourth ([per-key LLM budgets](/agentgateway-per-key-llm-budgets/)). Open-source Kubernetes budgets are token-based (global rate limiting, `unit: Tokens`). On a Kubernetes waypoint path I ran dollar budgets on Solo Enterprise for agentgateway: the seventh request flipped, alice 429, bob on his own bucket still 200 ([cost controls](/llm-cost-controls-ai-gateway/)). Token counts are not dollars until a catalog prices the model. A dashboard increment is accounting. An alert is not a cap. Write the exhaustion status code into the runbook.

Hop 2 without hop 1 still leaves a stealable `sk-`. Hop 2 without the spine shares one key across every impersonator.

### Hop 3: MCP tool allowlists

Per-tool and per-server allowlists on the MCP session. Unauthorized tools are hidden from `tools/list` and denied on `tools/call`. Multi-tenant federation sits behind one endpoint.

I ran three callers against the same three MCP URLs and got three different catalogs from deny-by-default CEL. The six servers held no auth, quota, or billing code ([multi-tenant MCP federation](/multi-tenant-mcp-federation/), run on Solo Enterprise for agentgateway). MCP's shipped identity still names the employee ([identity gap](/mcp-agent-identity-gap/)), so the allowlist has to bind to the spine, not to a session cookie.

`AGENTS.md` is not this hop. I ran a policy file that forbade deletes, plus an in-band classifier, and watched it delete all five customer records. The gateway allowlist stopped the call the file did not ([AGENTS.md is not a security control](/agents-md-not-a-security-control/)).

### Hop 4: Egress / CONNECT discipline

Assume agents will try GET-shaped writes, address literals, a permitted relay, and NO_PROXY plus /etc/hosts plus a Host override. Enforce at CONNECT time, and with platform NetworkPolicy / rogue-agent controls.

I reproduced four bypasses in a Docker Compose lab, then watched all four fail behind a CONNECT-time gateway (a Python stand-in, not agentgateway) ([egress control](/agent-egress-control-bypasses/)). That is why this hop exists: an application gateway that only sees requests it was sent is bypassable. I am not litigating kernel products. I am saying hop 1 through hop 3 do not matter if the agent never hits the hop.

agentgateway documents the same pattern as a standalone HTTP CONNECT proxy: clients point proxy settings at it, and it decides which destinations they are allowed to reach, by TLS SNI (tunnel mode) or by the CONNECT authority (route mode). See the [egress proxy](https://agentgateway.dev/docs/standalone/latest/documentation/configuration/egress-proxy/) docs. I have not tested agentgateway egress on this page.

When the agent has already left the intended path, [rogue-agent Kubernetes controls](/rogue-agent-kubernetes-controls/) is the stage map (privileged pods, projected tokens, over-broad RBAC).

## Failure modes if you skip a hop

| If you ship | What breaks |
| --- | --- |
| Secretless without budgets | Spend runaway on the injected key. The agent has no `sk-` and still burns the quarter. |
| Budgets without identity | Shared-key blast radius. Anyone who copies the virtual key inherits the bucket. |
| MCP allowlists without egress | Tools via raw HTTP to the same APIs the MCP server would have called. |
| Egress without secretless | Keys still sit in the agent. A sandbox that cannot dial out can still leak `sk-` through a permitted channel. |
| Any hop without the SPIFFE spine | Spoofable caller. Headers and bearer tokens the agent minted are not who. |
| All four hops, prompt policy only | You already know this one. The file sits in the attacker's context window. |

## Acceptance tests (copy into the design review)

One bullet per hop, mapped to a demo I already published.

- **Spine.** Denied SPIFFE identity returns **403** before the provider. Valid SVID not in the CEL allowlist is still 403. ([SPIFFE](/spiffe-identity-for-ai-agents/))
- **Hop 1.** Agent environment contains **no** provider LLM key. A completion still returns. ([secretless](/secretless-ai-agents/))
- **Hop 2.** Over-budget key returns **HTTP 429**. A second key on its own bucket still 200. ([per-key budgets](/agentgateway-per-key-llm-budgets/))
- **Hop 3.** Disallowed MCP tool is denied, and absent from `tools/list`. ([federation](/multi-tenant-mcp-federation/) on Solo Enterprise, [AGENTS.md](/agents-md-not-a-security-control/))
- **Hop 4.** A GET-shaped write, an address literal, a permitted link-chain relay, and `NO_PROXY` plus `/etc/hosts` plus a Host override all **fail**. ([egress](/agent-egress-control-bypasses/); pattern lab: Python CONNECT gateway, not agentgateway)

kagent [Agent Substrate](/kagent-agent-substrate/) is runtime density (many agents, few pods). It is not a fifth control on this path.

## Where this sits vs scorecard / plane / define

- **This page** = wire the path (how).
- **[How to choose an AI agent gateway](/how-to-choose-an-ai-agent-gateway/)** = how to evaluate a gateway for AI agents. agentgateway is the hop in standalone and Kubernetes.
- **[agentgateway vs LiteLLM vs Portkey](/agentgateway-vs-litellm-vs-portkey/)** = how agentgateway's plane differs from a Python LLM proxy and a managed AI-ops plane.
- **[What is an agentic mesh](/what-is-an-agentic-mesh/)** = definition.
- **[SPIFFE vs OAuth for AI agents](/spiffe-vs-oauth-for-ai-agents/)** = identity compare.

One paragraph, no second scorecard. If you cannot point at the hop and the four tests, you are not ready to call the path production.

## Where to go next on webofmike

Proof, in path order:

- [SPIFFE identity for AI agents](/spiffe-identity-for-ai-agents/)
- [Secretless AI agents](/secretless-ai-agents/)
- [LLM cost controls](/llm-cost-controls-ai-gateway/) (Solo Enterprise)
- [Per-key LLM budgets](/agentgateway-per-key-llm-budgets/)
- [Multi-tenant MCP federation](/multi-tenant-mcp-federation/) (Solo Enterprise)
- [MCP agent identity gap](/mcp-agent-identity-gap/)
- [AGENTS.md is not a security control](/agents-md-not-a-security-control/)
- [Agent egress control bypasses](/agent-egress-control-bypasses/) (pattern lab: Python CONNECT gateway, not agentgateway)
- [Rogue-agent Kubernetes controls](/rogue-agent-kubernetes-controls/)
- [kagent Agent Substrate](/kagent-agent-substrate/) (runtime context)

Siblings for the other questions: [evaluation](/how-to-choose-an-ai-agent-gateway/), [how agentgateway's plane differs from an LLM proxy or a managed AI-ops plane](/agentgateway-vs-litellm-vs-portkey/), [define](/what-is-an-agentic-mesh/), [SPIFFE vs OAuth](/spiffe-vs-oauth-for-ai-agents/).

External primaries:

- [Standalone binary](https://agentgateway.dev/docs/standalone/latest/setup/install/binary/)
- [agentgateway architecture](https://agentgateway.dev/docs/kubernetes/latest/documentation/about/architecture/) (control plane / data plane, xDS)
- [Solo: About agentic mesh](https://docs.solo.io/agentgateway/kubernetes/latest/integrations/agentic-mesh/about/) (SPIFFE enforcement hop + MCP tool policy)

DeepInspect and Secure Patterns are linked above as contrast on "control plane" and "chokepoint" language, not as the authority on this four-control path.

*The OSS project is [agentgateway/agentgateway](https://github.com/agentgateway/agentgateway). This page composes those demos; it is not a new lab and not a product ranking.*

