Skip to main content

Your Next Platform User Isn't Human: RBAC and Quotas for AI Agents as Platform Consumers

11 min readDora NodaDora Noda
Share
On this page

Machine identities now outnumber humans 82 to 1 inside the enterprise, according to CyberArk's 2026 research — and that count was taken before this year's wave of AI agents started minting credentials of their own. Half of the organizations surveyed have already suffered a breach tied to a compromised machine identity. Your platform's next user is not a developer with a laptop. It is software with an API key, operating at machine speed, at 3 a.m., with no human watching the terminal.

On July 6, 2026, CNCF published "Evolving platform engineering for AI-native workloads" by Pankaj Gupta (VMware by Broadcom), and it names the shift plainly: "AI agents are recognized as non-human platform consumers with their own access, scope, and governance needs." Not future users. Current consumers, owed the same governance, access controls, and operational guardrails as the humans. This post turns that sentence into a concrete RBAC-and-quotas design for a self-hosted PaaS: per-agent identity instead of shared admin tokens, least-privilege roles for software subjects, quotas that count agent-initiated deploys against the same budget as human ones — and why your deploy-from-chat MCP server has to be built agent-first from day one.

Shared admin tokens are the default — and the failure mode

Be honest about how agents authenticate to your platform today. In most shops the answer is one long-lived admin token pasted into the agent's environment: full deploy rights, readable secrets, no expiry, shared across every automation that ever needed "just one quick API call." It works right up until it doesn't, and the failure modes are specific to non-human callers.

A leaked human credential gets noticed — the human sees the strange session, the SSO logs show an odd login. A leaked agent token gets used: silently, programmatically, at a rate no human would sustain, with every action attributed in your audit log to whatever username created the token three quarters ago. There is no "who did this" — there is only "which of the fourteen automations sharing this token did this." And revocation is a self-inflicted outage, because that one token powers the deploy bot, the nightly scaler, and the chat integration all at once.

The fix direction is the entire thesis of this post: give every agent its own identity, scope it to the least privilege its job needs, and count everything it does against a budget. The rest is implementation detail — but the detail matters, because agents break assumptions baked into human permission models in at least four places. Start with identity.

Per-agent identity: what the options actually look like

An agent needs a credential that answers three questions: which agent is calling, what is it allowed to touch, and when does this permission expire. Four mechanisms cover the realistic design space for a self-hosted platform in 2026:

MechanismWhat it isUse when
Kubernetes ServiceAccountsPer-agent namespaced identity with projected short-lived tokens, bound to Roles via RBACThe agent runs in-cluster and only needs Kubernetes API access
SPIFFE/SPIRE SVIDsCryptographically attested workload identity (X.509 or JWT SVID) issued after node + workload attestationAgents span clusters or clouds and you need identity that survives outside any one cluster's trust domain
IdP agent identities (Entra Agent ID, Okta for AI Agents)Agents as first-class directory objects with Conditional Access, lifecycle management, and kill-switch revocation; both went GA in April 2026You already centralize human identity in Entra or Okta and want one revocation plane for both
MCP OAuth 2.1 tokensThe MCP server as OAuth Resource Server validating audience-bound Bearer [REDACTED] from a third-party Authorization Server (the model since the June 2025 spec)The agent reaches your platform through a deploy-from-chat MCP server rather than raw APIs

None of these is exotic anymore. Google Cloud's Agent Identity went GA with SPIFFE-based principals; AWS Bedrock AgentCore ships per-agent IAM roles; the MCP authorization spec is stable enough that Okta, Anthropic, and VS Code shipped zero-touch enterprise SSO against it in June 2026. Pick the mechanism that matches where your agents live — in-cluster agents get ServiceAccounts, chat-driven agents get MCP OAuth tokens — and make the identity per agent, not per team, not per platform. The marginal cost of one more ServiceAccount is zero. The marginal cost of one more shared secret is another unattributable blast radius.

RBAC when the subject is software

Kubernetes RBAC does not care whether the subject is a person or a process — a RoleBinding happily points at a ServiceAccount. What changes is the shape of the roles, because an agent's job is narrower than any human's and its failure mode is faster. A human with edit in a namespace fat-fingers one bad kubectl apply and notices. An agent with edit applies the bad manifest in a retry loop.

Design agent roles around three rules:

  1. Namespace-scoped, never cluster-wide. A deploy agent needs create/update on Deployments and Services in its tenant namespace. It does not need get on Secrets (inject secrets via the platform, not via agent reads), and it certainly does not need cluster-admin. If an agent's job genuinely spans namespaces, that is two identities with two bindings, not one broad one.
  2. Verbs, not vibes. Grant the exact verbs the job needs — typically get, list, create, update, patch on the workload resources — and withhold delete unless the agent's documented job includes teardown. Deletion is the verb most often granted "just in case" and most often regretted.
  3. No token passthrough. The MCP authorization spec is explicit: a server MUST validate that tokens were issued specifically for its use and MUST NOT pass the client's token upstream. When your MCP server calls the Kubernetes API on an agent's behalf, it exchanges or mints its own credential for that hop. A Bearer [REDACTED] that flows unchanged from chat client to MCP server to cluster is a confused-deputy incident waiting for a prompt injection to trigger it.

A minimal deploy-agent role looks like this:

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deploy-agent
  namespace: tenant-acme
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["services", "configmaps"]
    verbs: ["get", "list", "create", "update", "patch"]

No Secrets. No delete. No wildcards. Bound to one ServiceAccount, in one namespace, for one agent. If that reads as paranoid, compare it against the shared admin token it replaces: every line you didn't write here is an incident you already prevented. Per-tool scopes on the MCP layer mirror the same idea one level up — the agent's token authorizes deploy:staging, not platform:admin — so the chat surface and the cluster surface enforce the same boundary.

Quotas: count the agent's deploys against the same budget

Here is the failure mode RBAC alone cannot catch: a perfectly authenticated, minimally scoped agent that deploys two hundred times an hour because its control loop has a bug, or because a user asked it to "keep trying until it works" and walked away. Identity answers who; RBAC answers what; only quotas answer how much. And "how much" is where agents differ most from humans — a human's deploy rate is bounded by typing speed and sleep, while an agent's is bounded by nothing unless you bound it.

The CNCF post's Embedded FinOps pillar makes the same point at enterprise scale: cost accountability has to become a platform primitive, with real-time attribution and pre-deployment cost gates, not a dashboard somebody reads next quarter. For a self-hosted PaaS, that translates into mirroring every human quota with an agent equivalent — same budget, same enforcement point:

Human quotaAgent equivalentWhy it differs
Rate limits per user/API keyRate limits per agent token, set lower than the human defaultAgents burst; a human's "generous" limit is an agent's steady state
Concurrent pipeline cap per teamConcurrent-job cap per agent identityOne runaway loop must not starve every other tenant's deploys
Monthly spend alerts per projectCost attribution per agent identity, in real timeAgent-initiated GPU hours and egress look identical to human spend in the bill unless tagged at the source
Manual approval for production deploysPolicy gate evaluated at machine speed (budget remaining, change window, blast radius)A click-to-approve step the agent cannot pass becomes either a permanent blocker or a rubber stamp — design the gate for a non-human caller

The key row is the third one. When the invoice arrives, "the agent did it" is not a cost center. Tag every agent-provisioned resource with the agent's identity at creation time, so the FinOps reckoning the CNCF post warns about can actually name its counterparty.

Agent-first vs retrofitted: why the MCP server's auth can't be a dashboard hand-me-down

This is the thesis the whole post has been building toward: if your deploy-from-chat MCP server inherits its auth from the human dashboard — same sessions, same roles, same approval clicks — you have not given agents access. You have given a human permission model to callers it was never designed for, and the breakage is concrete:

Human dashboard assumptionWhat breaks with an agent callerAgent-first design
Session cookies with sliding expiryNo browser, no cookie jar; the agent needs a credential it can present programmaticallyShort-lived audience-bound Bearer [REDACTED] via OAuth 2.1, refreshed by flow not by cookie
Click-to-approve gates ("deploy to prod?")The agent cannot click; the gate becomes a hang or gets bypassed with a standing approvalMachine-evaluable policy gates: budget, window, blast radius, all checkable in code
Audit log records the usernameFourteen agents share deploy-bot; the log answers nothingAudit records agent identity plus delegation chain (which user tasked which agent)
Coarse roles (viewer / editor / admin)editor is simultaneously too broad (all namespaces) and too narrow (no tool-level distinction)Per-tool MCP scopes (deploy:staging) aligned with namespace-scoped Kubernetes Roles

Every row in the right column is cheaper to build on day one than to retrofit. Token passthrough prohibitions, audience validation, per-tool scopes — the MCP spec already requires the important parts, so "agent-first" mostly means actually implementing the spec instead of bolting the MCP server onto the dashboard's session middleware. The teams that retrofit will discover, one incident at a time, that a permission model designed around "a person is looking at the screen" has no graceful answer when nobody is.

The gap the protocols don't close for you

An honest caveat before the checklist: the agent-interop protocols standardize how agents talk, not who they are. Agent-to-Agent (A2A) — Google's protocol, now a Linux Foundation project under the Agentic AI Foundation with v1.0 in production — identifies agents through Agent Cards: self-declared JSON documents at /.well-known/agent-card.json where any agent can claim any name and any capability. There is no persistent identity in the card, no verification that the presenter earned the claims. A2A tells you what an agent says it can do, not whether it is the agent it claims to be.

So treat protocol identity as a hint and platform identity as the truth. When an external agent arrives via A2A or MCP, your platform verifies the presenter — validate the token against your Authorization Server, check the SPIFFE ID against your trust bundle, bind the session to the ServiceAccount you issued — and authorizes against that, never against the self-declared card. The card is a business card: useful for introductions, worthless as a passport. The platform issues the passports.

Monday-morning checklist for a self-hosted PaaS

If this post has earned its place in your backlog, here is the work, ordered by leverage:

  1. Inventory agent callers. List every automation holding a platform credential today. Each shared token is one incident of unattributable access waiting to happen — and the list is shorter now than it will ever be again.
  2. Issue per-agent identity. One ServiceAccount or IdP agent object per agent, short-lived tokens, no shared secrets. Revocation should disable one agent, not page the whole team.
  3. Write agent-shaped Roles. Namespace-scoped, exact verbs, no Secrets reads, no delete without a documented reason. Align MCP per-tool scopes with the Kubernetes Roles underneath.
  4. Enforce quotas at the agent identity. Token-scoped rate limits, concurrent-job caps, real-time cost attribution, machine-speed policy gates on production. Mirror the human budget; don't invent a separate, unenforced one.
  5. Verify presenters, don't trust cards. A2A Agent Cards and MCP client claims describe capabilities; your Authorization Server and trust bundle establish identity. Authorize against the latter.

CNCF's Platform Engineering 2.0 framing ends where this post began: the platform teams that treat the new consumers — agents alongside ML engineers, FinOps practitioners, and security teams — as first-class design inputs are the ones whose governance survives contact with the agentic future. The caller is already an agent. Build like it.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Agents are first-class operators here: machine-readable infrastructure state, API-first everything. Star the repo on GitHub or deploy your first app today.

Related articles

Give your agents a chain backend

Autonomous agents hit RPC endpoints very differently than people do. See what bex router handles on their behalf.

Read the agents guide