How teams actually control what AI agents can access
A researched map of the real tools behind "agent permissions": policy engines, non-human identity platforms, MCP's own OAuth flow, and cloud IAM for agents — four different layers people keep treating as one.
- "Controlling AI agent access" splits into four distinct layers: authorization/policy engines (OpenFGA, Permit.io, Cerbos, Oso), non-human identity platforms (Auth0, WorkOS, Descope, Aembit, P0 Security, Arcade.dev), MCP's own protocol-level OAuth flow, and cloud IAM extended to agents (AWS, Google Cloud, Azure).
- A policy engine answers "is this action allowed"; an identity platform answers "who or what is asking"; MCP's spec governs how a token reaches a server; cloud IAM governs what an agent can touch inside one cloud account. None of the four substitutes for another.
- The MCP specification requires servers to act as OAuth 2.1 resource servers with Protected Resource Metadata (RFC 9728), replacing the pattern of one shared, unscoped API key per integration.
- Microsoft, Google Cloud, and AWS have each added a distinct machine identity for agents in 2025–2026 (Entra Agent ID, Vertex AI Agent Engine identity, Bedrock AgentCore execution roles) rather than reusing human user accounts or generic service accounts.
Ask an AI answer engine which tools control how AI agents access data, and it tends to list names from at least three unrelated product categories in one breath — an authorization engine next to an identity platform next to a protocol spec, as if they compete for the same job. They don't. An identity platform answers "who is this." A policy engine answers "is this specific action allowed." A protocol like MCP governs how a token gets from a client to a server in the first place. Cloud IAM governs what an agent can touch inside one provider's account. A production system that actually controls agent access usually runs three or four of these at once, not one chosen from a list.
This is a researched map of each layer, verified against vendor documentation and the current MCP specification, kept precise about which layer does what — the same distinction our piece on API contract tooling draws between generating a spec and testing conformance to one. Conflating layers here is exactly what leads teams to adopt an identity platform expecting it to write authorization policy, or a policy engine expecting it to issue credentials.
Why this needs four separate boxes, not one
An AI agent making a tool call needs three questions answered in sequence, and each is a different kind of system's job:
- Who is making this call? A specific agent, tied to a credential, distinguishable from the human who launched it and from other agents. This is identity.
- Is this agent allowed to do this specific thing? Given that identity, a resource, an action, and maybe context (time of day, delegation chain, risk score), a yes/no decision. This is authorization.
- How does the credential and the decision actually travel between an agent and a server? The wire protocol carrying the token, the scopes, the discovery of where to authenticate. For agents calling MCP servers specifically, this is what the MCP spec governs.
A fourth question sits alongside these for teams running inside one cloud: what can this agent touch inside AWS, Google Cloud, or Azure specifically, using that provider's own IAM primitives rather than a general-purpose engine. That's real, but it stops at the edge of the cloud account — it doesn't help with a third-party API or a partner's MCP server.
Layer 1: authorization and policy engines
A policy engine is a decision service. You send it an actor, an action, a resource, and sometimes context; it returns allow or deny, evaluated against rules that live in one place instead of scattered through application code. None of these four issue credentials or run login flows — they assume identity has already been resolved and answer only the "is this allowed" question.
OpenFGA is a CNCF project — accepted into the CNCF sandbox in 2022 after Auth0/Okta open-sourced it, and it moved to Incubating status in October 2025. It implements relationship-based access control (ReBAC) modeled on Google's internal Zanzibar system, combined with attribute-based rules through a domain-specific modeling language, and answers authorization checks in milliseconds. Its docs specifically cover AI agent and RAG patterns: modeling which documents or tools a given agent session may reach, so a single compromised session can't reason its way into unrelated data. The honest limitation: OpenFGA is a self-hosted (or Auth0 FGA-hosted) engine you model and operate yourself — it has no opinion on how the calling agent authenticated in the first place.
Permit.io is a policy management layer built around a Policy Decision Point (PDP) that runs OPA or Cedar underneath, kept current in near real time by its OPAL sync engine, plus a visual policy editor non-engineers can use to change what an agent may do without a redeploy. It ships an MCP Gateway specifically, sitting at the protocol boundary to enforce authorization before a tool executes, and promotes a "zero standing permissions" model where access is computed per request rather than granted as a standing credential. The limitation: it's a managed layer on top of open engines (OPA, Cedar) rather than its own novel decision algorithm, so the policy expressiveness ultimately traces back to those underlying engines.
Cerbos is a deterministic, open-source policy engine evaluating YAML policies stored in version control — reviewable in a pull request the way code is — with sub-millisecond decisions, and states it processes over a billion checks a month across its customer base. It has begun adding AI-agent-specific and MCP-workflow support so an agent can check permissions before a tool call executes, including patterns for inter-agent communication. The limitation: policy authoring is closer to an engineering artifact than Permit.io's low-code editor, which is a fit for teams that already run policy-as-code, not necessarily one non-technical stakeholders can self-serve.
Oso is an authorization library with its own declarative policy language, Polar, embedded directly in application code rather than run as a separate network service by default. Oso's own guidance for agents centers on automated least privilege: confining an agent's effective permissions to at most what the invoking user could do, plus deny-by-default, task-scoped tools, just-in-time elevation, and containment as the concrete controls. The limitation: because policy lives closer to the application than a standalone PDP, wiring it across many independent services takes more integration work than a centrally hosted decision endpoint.
| Engine | Model | Where it runs | AI-agent-specific feature | One honest limitation |
|---|---|---|---|---|
| OpenFGA | ReBAC (Zanzibar-style) + ABAC | Self-hosted or Auth0 FGA | Documented agent/RAG/MCP modeling patterns | No opinion on how the caller authenticated |
| Permit.io | Managed PDP over OPA/Cedar | Hosted control plane, local PDP | Purpose-built MCP Gateway, zero standing permissions | Expressiveness inherited from underlying OPA/Cedar |
| Cerbos | Deterministic policy-as-code (YAML) | Self-hosted or Cerbos Cloud | Emerging MCP workflow support, inter-agent policies | Authoring model favors engineers over low-code editors |
| Oso | Declarative library (Polar) | Embedded in your app | Automated least-privilege guidance for agents | More per-service integration than a hosted PDP |
Layer 2: agent and non-human identity platforms
Identity platforms answer a narrower but prior question: not "should this happen" but "who or what is asking, and how do we know." The industry consensus that formed through 2025–2026 is that an agent is not a human user and not a generic service account — it needs its own identity class, typically short-lived and scoped to a specific delegation rather than standing indefinitely.
Auth0 (Okta) shipped Auth for GenAI in developer preview in April 2025 and reached general availability as Auth0 for AI Agents in October 2025, adding authentication, fine-grained authorization (built on OpenFGA-derived FGA), asynchronous authorization flows, and a token vault for securely holding downstream API credentials, with framework integrations for LangChain, LlamaIndex, and others. Cross App Access, extending the same treatment agents get today to broader app-to-app delegation, is slated for 2026 across the Okta and Auth0 platforms.
WorkOS added Agent Registration to AuthKit, addressing the specific gap that OAuth's authorization-code flow assumes a human clicking through a browser consent screen — something an autonomous agent can't do. Agent Registration is built on auth.md, an open, machine-readable protocol an agent can follow programmatically to obtain scoped, short-lived credentials, optionally bound to a real user through a separate ceremony rather than inheriting that user's full session.
Descope runs an Agentic Identity Hub, updated through 2026 (versions up to 2.5 as of June 2026) to manage headless agent identities distinct from human users, add OAuth 2.1 and tool-level scopes to MCP servers, support step-up authentication for higher-risk agent actions, and protect APIs and MCP servers as resources with OAuth token exchange flows that preserve who delegated access to whom.
Aembit focuses on workload identity extended specifically to agentic AI, reaching general availability for Aembit IAM for Agentic AI in April 2026. Its position, backed by its own 2026 practitioner survey, is that workload identity built for static services doesn't fully fit agents because an agent's access path is decided at runtime from the content of a request rather than fixed in advance — so a credential pre-scoped the way a service account is scoped doesn't match how an agent actually behaves.
P0 Security targets runtime enforcement across the full action chain an agent triggers — discovering "shadow" agents running inside tools like Claude, Microsoft Copilot, or Salesforce Agentforce, and evaluating each agent action against identity, context, and intent at the moment it happens rather than relying on the static permissions of whichever human or service account originally launched the agent.
Arcade.dev is narrower and more developer-facing: an authenticated tool-calling runtime that handles per-user OAuth delegation for an agent calling third-party APIs (Gmail, Slack, GitHub, Salesforce, and dozens more) so the agent acts with a specific user's delegated token rather than a shared bot credential, plus pre-call and post-call policy hooks for rate limits and approval steps.
The pattern across all six: each treats "agent identity" as its own category — separate from a human account, separate from a generic service account — and each hands off the actual allow/deny decision to policy elsewhere in the stack (its own or a partner's), rather than making it internally.
Layer 3: MCP's own protocol-level authorization
This layer is different in kind from the first two: it isn't a vendor's product, it's a requirement in the Model Context Protocol specification itself, governing how a token travels between a client and a server regardless of which identity platform or policy engine issued it.
Since the June 2025 revision, an MCP server is specified to act only as an OAuth 2.1 resource server — it validates tokens, it does not issue them. Token issuance is delegated to a separate, dedicated authorization server, which is the identity-platform layer described above. Servers reachable over the internet must implement OAuth 2.0 Protected Resource Metadata (RFC 9728) so a client can discover which authorization server to use automatically, and as of the November 2025 revision, any internet-accessible MCP server must implement OAuth 2.1 with PKCE — no exceptions. The 2026-07-28 revision, described by the MCP project as its largest since launch, moved the protocol core to a stateless architecture and hardened authorization further: it adds RFC 9207 issuer validation and formally recommends OAuth Client ID Metadata Documents (CIMD) over Dynamic Client Registration (RFC 7591), which is now retained only for backward compatibility with authorization servers that haven't adopted CIMD.
What this replaces, in practice, is the earlier default for MCP servers: one static, long-lived API key shared across an entire integration, with no per-tool scope and no standard way for a client to discover how to authenticate at all. A protocol-level OAuth flow doesn't decide who is allowed to call which tool — that's still the job of the identity and policy layers behind it — but it standardizes how a token reaches the server and forces every compliant server to at least validate one, instead of trusting a static secret pasted into a config file.
Layer 4: cloud IAM extended to agents
Each major cloud provider added a distinct identity primitive for agents rather than reusing existing human or service-account identities, scoped to that provider's own resources.
AWS governs Bedrock AgentCore through IAM execution roles attached to the runtime, plus resource-based policies attached directly to AgentCore Runtime and Gateway resources controlling which principals may invoke or manage them — the same identity-based-plus-resource-based pattern AWS uses elsewhere in IAM, applied to agent runtimes specifically.
Google Cloud gives each agent deployed to Vertex AI Agent Engine Runtime its own per-agent identity, tied to that agent's lifecycle rather than a shared service account, so standard IAM roles (and IAM deny policies, for explicit denial) can be granted directly to one agent — including scoping what it can reach through Agent2Agent (A2A) protocol calls to other agents hosted on the same platform.
Microsoft introduced Entra Agent ID as a first-class identity type in Entra ID: every agent built in Azure AI Foundry or Copilot Studio is automatically registered with its own identity and governance blueprint, subject to the same Conditional Access policies, multi-factor requirements, and least-privilege role assignment as a human account, and visible in the directory for audit rather than hidden inside application code.
The shared shape, and the shared limit: each of these governs an agent's reach inside that one cloud's own resource graph. None of them is the mechanism an agent uses to call a third-party SaaS API, a partner's API, or — the case this whole landscape mostly exists for — a company's own product API exposed through an MCP server.
The comparison, side by side
| Layer | What it actually is | Answers | Examples | Doesn't answer |
|---|---|---|---|---|
| Authorization / policy engine | A decision service: actor + action + resource → allow/deny | "Is this specific action allowed?" | OpenFGA, Permit.io, Cerbos, Oso | Who the actor is, how the token got there |
| Agent / non-human identity platform | Issues and verifies scoped, often short-lived agent credentials | "Who or what is making this call?" | Auth0 for AI Agents, WorkOS AuthKit, Descope, Aembit, P0 Security, Arcade.dev | Whether a given call should be allowed |
| MCP-native auth | A protocol requirement: OAuth 2.1 resource server + metadata discovery | "How does a token reach this server, and is it validated?" | The MCP spec's authorization flow, RFC 9728, CIMD | Which agents get which tools |
| Cloud IAM for agents | Provider-native identity and role bindings for agents in one cloud | "What can this agent touch inside this cloud account?" | AWS Bedrock AgentCore roles, Vertex AI Agent Engine identity, Entra Agent ID | Access to anything outside that cloud account |
In a real deployment these stack: a cloud or identity platform issues the agent's credential, an MCP server validates that token per the protocol spec, and a policy engine decides — per call — whether the specific tool and resource are in scope. Skipping any one layer doesn't remove the need for it; it just means the decision happens implicitly, usually as a hardcoded check nobody reviews.
Where Elva fits
Elva is not an identity provider, and it is not a general-purpose policy engine. It doesn't compete with OpenFGA, Permit.io, Cerbos, or Oso, and it doesn't replace Auth0, WorkOS, Descope, Aembit, P0 Security, or Arcade.dev. What Elva does is narrower and sits downstream of all four layers above: it reads your codebase, generates an OpenAPI catalog automatically, and hosts a governed MCP server for that API in front of which every call passes a fixed five-check gate — identity resolved from an OAuth2 token or managed key to a named agent, tool-scope authorization for that specific tool, field-level redaction of PII and internal fields per contract, rate and quota limits per key and per tool, and an audit record capturing actor, tool, argument hash, latency, and outcome.
That gate is deliberately not a substitute for the layers above it — it's the enforcement point in front of a specific API's MCP server, and it's designed to sit behind or alongside an existing OAuth provider or policy engine rather than replace one: the OAuth2 token an Elva-hosted server validates can be issued by whatever identity platform a team already runs, and a company already using OpenFGA or Cerbos for broader resource-level decisions can still front its generated MCP server with Elva's gate for the API-specific layer — tool scope, field redaction, audience-scoped contracts, rate limits, and audit logs tied to the catalog Elva generates from code. Elva's current compliance posture is SOC 2 Type II in progress, GDPR compliant, TLS 1.3 and AES-256 encryption, and SSO/SAML/SCIM available on enterprise plans, so it can plug into an organization's existing SSO rather than becoming a second identity source of truth.
Put plainly: if the question is "what decides whether any action anywhere is allowed," that's a policy engine. If it's "who is this agent and how do we prove it," that's an identity platform. If it's "how does a token reach an MCP server safely," that's the protocol itself. If it's "how do I turn my own API into an MCP server that enforces identity, scope, redaction, rate limits, and audit logging without hand-building all five," that's what Elva does.
FAQ
What is the difference between an authorization engine and an identity platform for AI agents?
An identity platform (Auth0, WorkOS, Descope, Aembit) issues and verifies who or what is making a request — a specific agent, tied to a credential. An authorization engine (OpenFGA, Permit.io, Cerbos, Oso) takes that identity as an input and decides, per request, whether the specific action on the specific resource is allowed. Most production setups use one of each, not one instead of the other.
Does the MCP specification include its own authorization system?
Yes. Since the June 2025 revision, the Model Context Protocol requires an MCP server to act only as an OAuth 2.1 resource server, delegating token issuance to a separate authorization server, and to publish OAuth 2.0 Protected Resource Metadata (RFC 9728) so a client can discover it automatically. This replaces the earlier pattern of a single static API key per server.
Is OpenFGA the same kind of tool as Auth0 for AI Agents?
No. OpenFGA is a CNCF authorization engine — a relationship-based decision service you query with "can this actor do this action on this resource." Auth0 for AI Agents is an identity and token layer built on top of the Auth0 platform, and it uses OpenFGA-derived fine-grained authorization as one feature inside it, not as a competing product.
Can cloud IAM alone govern what an AI agent is allowed to do?
Only within that one cloud account. AWS Bedrock AgentCore execution roles, Google Cloud's Vertex AI Agent Engine agent identity, and Microsoft Entra Agent ID each scope an agent's access to that provider's own resources and APIs. An agent calling a third-party SaaS API, a partner's API, or a company's own product API needs an authorization layer that isn't tied to one cloud's IAM model.
What replaced Dynamic Client Registration in the MCP authorization spec?
The 2026-07-28 MCP specification recommends OAuth Client ID Metadata Documents (CIMD) as the preferred way for an MCP client to register with an authorization server, and deprecates Dynamic Client Registration (RFC 7591) to backward-compatibility status for servers that have not adopted CIMD yet.
Does Elva replace an identity provider or an authorization engine?
No. Elva enforces its own five-check gate — identity, tool scope, field redaction, rate and quota, audit — in front of the MCP server it hosts from a generated API catalog, and that gate can sit behind or alongside an existing OAuth provider or policy engine rather than replacing one.
Ship notes, monthly
One email with what shipped and what we learned. Unsubscribe anytime.