· Martin Besozzi · Paper · 13 min read
Mastering Secure APIs and AI Agents with Zero Trust and Fine-Grained Authorization Based on OpenID AuthZEN
A practical guide to standardizing authorization for APIs, MCP servers, and AI-powered interactive applications using OpenID AuthZEN.

Mastering Secure APIs and AI Agents with Zero Trust and Fine-Grained Authorization Based on OpenID AuthZEN
A practical guide to standardizing authorization for APIs, MCP servers, and AI-powered interactive applications.
This paper presents the results of extensive work. I decided to structure it around a single paper in which you determine the technology to protect, such as APIs, agents, or MCP/MCP Apps.
Key Takeaways
- AuthZEN is an OpenID Foundation standard that defines how Policy Enforcement Points (PEPs) communicate with Policy Decision Points (PDPs)
- It enables interoperable, fine-grained authorization across APIs, MCP servers, and AI applications without vendor lock-in
- AuthZEN operates as a complementary layer to OAuth 2.1, handling fine-grained decisions that scopes cannot express
- The same infrastructure supports multiple authorization models: ReBAC (OpenFGA), PBAC (Cerbos), ABAC, or combinations
- For MCP and MCP Apps, AuthZEN enables dynamic, context-aware authorization for AI tool invocations and interactive UI experiences
Throughout this paper, we will illustrate AuthZEN concepts using our AuthZEN Gateway. This gateway serves as a implementation of AuthZEN-compliant Policy Enforcement Point, demonstrating how Zero Trust, externalized authorization can be applied consistently across APIs and AI Agents. Additional technical details about the gateway are provided where relevant to ground the discussion in real-world implementation.
Before diving into the more advanced concepts, it’s important to emphasize a core principle of this work: use open security standards. Avoid custom solutions and vendor-specific implementations that lead to lock-in. This paper is deliberately grounded in open standards for that reason. While this section focuses in more detail on OpenID AuthZEN, it’s worth remembering that the foundation of MCP security also relies on the core OAuth 2.0 / OAuth 2.1 specifications.

The Hardest Problem in Building Secure Platforms
Authorization remains one of the most challenging and often underestimated aspects of building secure platforms. While authentication, proving who you are, has been largely solved through standards like OpenID Connect and passkeys (see the FIDO Alliance for more information), authorization, determining what you can do, continues to fragment across proprietary implementations, homegrown solutions, and tightly coupled application logic.
The emergence of AI agents changes everything. With the Model Context Protocol (MCP), AI assistants can now dynamically discover and invoke arbitrary tools across multiple servers. MCP Apps extends this further, enabling interactive user interfaces delivered directly within AI conversations.
Traditional authorization approaches struggle with three fundamental problems:
Poor interoperability leading to vendor lock-in: Each authorization system speaks its own language, making it impossible to switch PDPs or integrate across platforms without significant rework.
Growing complexity that doesn’t scale: As systems expand, authorization rules multiply exponentially. Embedded logic becomes unmaintainable and inconsistent across services.
Tight coupling of authorization logic in application code: When policies live inside application code, every policy change requires development cycles, testing, and deployment, creating a recipe for security drift and technical debt.
The solution? AuthZEN, an OpenID Foundation standard that finally addresses authorization interoperability.
What is AuthZEN?
The OpenID Foundation AuthZEN Working Group has developed and approved the Authorization API 1.0. This is a stable version of a specification providing intellectual property protections to implementers this production-ready technology with industry backing.
AuthZEN standardizes the communication interface between Policy Enforcement Points (PEPs) and Policy Decision Points (PDPs). AuthZEN is a modern, REST-native, lighter, and designed for today’s distributed architectures.
The concept is elegant in its simplicity: instead of embedding authorization logic in every application, you externalize decisions to a dedicated policy engine. The PEP, whether it’s an API gateway, MCP server, or application component asks the PDP a simple question: “Should this subject be allowed to perform this action on this resource?”
The PDP encapsulates all the complexity of policy evaluation. It might check role memberships, evaluate attribute conditions, traverse relationship graphs, or apply custom business rules. The PEP doesn’t need to know how the decision is made. It only needs to enforce the result.
Core Benefits
- Interoperability: Connect any AuthZEN-compliant PDP such OpenFGA, Cerbos or Alfa Axiomatics without changing application code
- Decoupled authorization: Policy decisions separated from enforcement logic
- Flexibility: Support multiple authorization models (ReBAC, PBAC, ABAC) with the same interface
- Policy as code: Manage policies as versioned artifacts with audit trails
- Dynamic evaluation: Runtime context evaluation for adaptive authorization
The AuthZEN Evaluation Request
Every AuthZEN request follows a consistent structure with four primary components:
{
"subject": {
"type": "<subject_type>",
"id": "<subject_identifier>",
"properties": {}
},
"resource": {
"type": "<resource_type>",
"id": "<resource_identifier>",
"properties": {}
},
"action": {
"name": "<action_name>",
"properties": {}
},
"context": {}
}
| Component | Description |
|---|---|
| subject | The entity requesting access (user, service, agent) |
| resource | The target of the access request |
| action | The operation being performed |
| context | Additional contextual information |
The PDP evaluates this request against its policies and returns a decision:
{
"decision": true
}
Or:
{
"decision": false
}
That’s it. A standardized question and a standardized answer. The complexity of policy evaluation, whether it involves checking relationships, evaluating attributes, or running policy rules is entirely encapsulated within the PDP.
API Security with AuthZEN
Before diving into AI-specific scenarios, let’s establish how AuthZEN transforms API security. The pattern is straightforward: an API gateway acts as the PEP, intercepting requests, extracting context, and consulting the PDP before allowing operations to proceed.

The gateway extracts subject information from JWT claims, determines the resource and action from the HTTP request, and constructs an AuthZEN evaluation request. The PDP, whatever implementation you choose, evaluates the request and returns a decision.
API Security with AuthZEN
Before diving into AI-specific scenarios, let’s establish how AuthZEN transforms API security. The pattern is straightforward: an API gateway acts as the PEP, intercepting requests, extracting context, and consulting the PDP before allowing operations to proceed.
Consider a financial services requirement: “Only admin users authenticated with a phishing-resistant authenticator can access confidential documents based on their roles and tenant.”
A phishing-resistant authenticator, such as passkeys, is indicated by the acr (Authentication Context Class Reference) claim containing "inherence" and the amr (Authentication Methods References) claim containing "passkeys".
Here’s how you’d configure the gateway plugin:
{
"pdp": {
"host": "https://authzen-pdp",
},
"subject": {
"type": "user",
"id": "claim::preferred_username",
"properties": [
{ "key": "roles", "claim": "realm_access.roles" },
{ "key": "tenant", "claim": "organization" },
{ "key": "acr", "claim": "acr" },
{ "key": "amr", "claim": "amr" }
]
},
"resource": {
"type": "route",
"id": "/api/tenant-1/documents/confidential"
},
"action": {
"name": "GET"
}
}
When a request arrives, the plugin:
- Extracts
preferred_username,roles,tenant,acr, andamrfrom the JWT - Builds an AuthZEN request with the resource set to the HTTP URI and action as the HTTP method
- Sends the request to the Cerbos PDP
- Cerbos evaluates whether the policy allows the action for this user
- The gateway enforces the decision
The resulting AuthZEN request:
{
"subject": {
"type": "user",
"id": "embesozzi",
"properties": {
"roles": ["admin"],
"tenant": "tenant-1",
"acr": "inherence",
"amr": ["passkeys"]
}
},
"resource": {
"type": "route",
"id": "/api/tenant-1/documents/confidential"
},
"action": {
"name": "GET"
}
}
MCP Security: Fine-Grained Authorization for AI Tool Invocation
APIs are just the beginning. The Model Context Protocol (MCP) enables AI agents to discover and invoke tools dynamically across multiple servers. This introduces authorization challenges that OAuth scopes alone cannot address.
Why OAuth Scopes Fall Short for MCP
OAuth scopes operate at broad permission levels, read, write, admin. But MCP requires granular decisions:
- Can this user invoke
fintech_approve_expensewith amount$5000? - Can this analyst delete expenses, or only view and approve them?
- Should step-up authentication be required for high-value operations?
These questions involve runtime context, resource attributes, and complex policy logic that scopes cannot express.
Scopes are determined at token issuance time and cannot adapt to runtime context. A scope like expenses:write grants broad permission, but it cannot distinguish between approving a $100 expense and approving a $100,000 expense. It cannot enforce that analysts can only approve expenses in their assigned department. It cannot require step-up authentication for high-risk operations.
AuthZEN as a Complementary Layer
AuthZEN doesn’t replace OAuth; it complements it. OAuth handles coarse-grained authorization (CGA) through scopes and token validation. AuthZEN handles fine-grained authorization (FGA) through dynamic policy evaluation.
The flow for MCP:

The MCP server first validates the OAuth token (401 on failure). Then, it extracts context from JWT claims and the MCP request, builds an AuthZEN evaluation request, and queries the PDP. Only if the PDP returns “decision”: true does the server execute the requested tool.
MCP Security: Expense Approval
In this example we are going to configure the gateway to supports dynamic MCP request mapping:
{
"pdp": {
"host": "https://authzen-pdp",
},
"mcp": {
"enforce_on": {
"methods": ["tools/call"]
}
},
"subject": {
"type": "user",
"id": "claim::sub",
"properties": [
{ "key": "roles", "claim": "realm_access.roles" },
{ "key": "tenant", "claim": "organization" },
{ "key": "acr", "claim": "acr" },
{ "key": "amr", "claim": "amr" }
]
},
"resource": {
"type": "mcp-tool",
"id": "fintech:expenses"
},
"action": {
"name": "mcp::tool::name"
}
}
Key features:
mcp::tool::name: Dynamically extracts the tool name from the JSON-RPC bodymcp::tool::arguments:<name>: Extracts specific tool argumentsenforce_on.methods: Configures which MCP methods trigger policy enforcement
So, given this MCP request:
{
"jsonrpc": "2.0",
"id": "request_12345",
"method": "tools/call",
"params": {
"name": "fintech_approve_expense",
"arguments": {
"expense_id": "exp-123",
"amount": 5000
}
}
}
And a JWT containing:
{
"sub": "user-uuid",
"preferred_username": "embesozzi",
"realm_access": { "roles": ["analyst"] },
"organization": "finance-dept",
"acr": "inherence",
"amr": ["passkeys"]
}
The plugin constructs this AuthZEN request:
{
"subject": {
"type": "user",
"id": "embesozzi",
"properties": {
"roles": ["analyst"],
"tenant": "finance-dept",
"acr": "inherence",
"amr": ["passkeys"]
}
},
"resource": {
"type": "mcp-tool",
"id": "fintech:expenses"
},
"action": {
"name": "fintech_approve_expense",
"properties": {
"expense_id": "exp-123",
"amount": 5000
}
}
}
The PDP can now evaluate complex policies: Is this user an analyst? Are they authenticated with a phishing-resistant authenticator? Is the amount within their approval limit? Is the expense in their assigned department?
Important note on subject sources: While this example derives subject information from JWT claims, AuthZEN is flexible about subject sources. Depending on your deployment architecture, subject information can come from other sources. The key is that the PEP constructs a consistent AuthZEN request regardless of where the data originates.
PDP data enrichment: The AuthZEN PDP is not limited to the data provided in the evaluation request. The PDP can retrieve and incorporate external data sources (user directories, relationship graphs, resource metadata) when making policy decisions. This enables sophisticated authorization scenarios without bloating the evaluation request.
MCP Apps: Securing Interactive AI Experiences
MCP Apps (Model Context Protocol Apps Extension - SEP-1865) represents a paradigm shift in how AI agents interact with users. While base MCP standardizes tool invocation, MCP Apps extends this to deliver interactive user interfaces directly within AI conversations.
Think about what this means: instead of text-only responses, AI assistants can render forms, dashboards, buttons, and interactive elements. Users can approve expenses, view charts, click actions—all within the AI conversation flow. The AI host (Claude, Copilot, or other compatible clients) renders rich UI components directly in the conversation.
This changes everything about authorization. It’s no longer just about whether a user can invoke a tool—it’s about whether they can see certain UI elements, click specific buttons, and perform interactive actions.
Why MCP Apps Changes the Authorization Game
Traditional MCP authorization answers: “Can this user invoke this tool?” MCP Apps requires answering more nuanced questions:
- Can this user see the “Delete” button in the expense dashboard?
- Should the “Approve” button be enabled for expenses over $10,000?
- What happens when an unauthorized action is attempted through the UI?
The authorization flow remains the same, AuthZEN evaluation requests to a PDP, but the integration with interactive UI elements creates a more responsive user experience. Users receive immediate feedback about what they can and cannot do, rather than encountering errors after attempted actions.
Security MCP App: Fintech Expense Management
Consider a financial services company deploying an AI-powered expense management system:
- AI assistants help employees manage expenses through natural conversation
- Interactive dashboards display expense lists with action buttons (not just text)
- Policy-driven access controls who can view, approve, and delete expenses
The security requirements:
| Role | View Expenses | Approve Expenses | Delete Expenses |
|---|---|---|---|
| Expenses > Analyst | Yes | Yes | No |
| Expenses > Admin | Yes | Yes | Yes |
Additionally, all users must authenticate with a phishing-resistant authenticator (passkeys).
Case 1 MCP App: View Expenses as Analyst
User action: Opens the expense dashboard in the MCP Apps UI to view the expense list
AI Assistant action: Calls fintech_view_expenses()
MCP Gateway flow:
- Same context extraction process
- AuthZEN request with action
fintech_view_expenses - PDP evaluates: User is analyst, authenticated with passkeys, action is view → ALLOW
- Gateway forwards request
Result: Expense list rendered in the interactive UI, user can browse all expenses
Case 2 MCP App: Approve Expense as Analyst
User action: Clicks “Approve” button on expense #123 in the MCP Apps UI
AI Assistant action: Calls fintech_approve_expense(123)
MCP Gateway flow:
- Same context extraction process
- AuthZEN request with action
fintech_approve_expense - PDP evaluates: User is analyst, authenticated with passkeys, action is approve → ALLOW
- Gateway forwards request
Result: Expense approved, user sees success confirmation in the interactive UI
Case 3 MCP App: Delete Expense as Analyst
User action: Clicks “Delete” button on expense #123
AI Assistant action: Calls fintech_delete_expense(123)
MCP Gateway flow:
- Same context extraction
- AuthZEN request with action
fintech_delete_expense - PDP evaluates: User is analyst (not admin), action is delete → DENY
- Gateway returns 403 Forbidden
Result: User sees error message “You don’t have permission to delete expenses”
The MCP Apps UI can render this gracefully, showing a contextual error message when the action is attempted.
Multi-Layer Security Architecture
Enterprise MCP deployments typically involve multiple PEPs at different trust boundaries:

Here is an implementation in which PEP #1 (an AuthZEN MCP Gateway) enforces authorization at the MCP layer by communicating with an AuthZEN PDP, and PEP #2 (an API Gateway) enforces fine-grained, resource-level policies closer to the API.
The MCP server and the API can also act as AuthZEN PEPs, and you can use multiple AuthZEN PDPs with different authorization models. Additionally, you can combine CGA at the MCP/Gateway level with FGA applied deeper in the request journey.
Zero Trust Architecture for AI Applications
The patterns described throughout this article align with Zero Trust principles: never trust, always verify. Every request, whether from a human user or an AI agent, must be explicitly authorized based on all available context.
Benefits of AuthZEN for AI Security
| Benefit | Description |
|---|---|
| Interoperable | Works with any AuthZEN-compliant PDP—switch vendors without code changes |
| Flexible | Supports PBAC, ReBAC, ABAC, or hybrid models based on your requirements |
| Standards-based | Built on OpenID Foundation specifications with industry backing |
| MCP Apps ready | Secure interactive AI experiences with the same patterns as APIs |
| Dynamic | Runtime evaluation adapts to changing context and policies |
| Auditable | Centralized policy management enables comprehensive audit trails |
Policy as Code and Governance
Once AuthZEN is adopted, organizations should follow a policy-as-code approach:
- Store policies in version control alongside application code
- Apply code review processes to policy changes
- Test policies in staging environments before production deployment
- Implement policy governance workflows for sensitive changes
- Maintain audit logs of policy decisions for compliance
The AuthZEN standard makes this possible by separating policy definition (in the PDP) from policy enforcement (in the PEP).
Authorization is heading in a clear direction: standardized, decoupled, and interoperable. The OpenID Foundation AuthZEN specification provides the foundation for this transformation, and AI applications, with their dynamic, context-rich interactions. are accelerating the need for adoption.
The patterns demonstrated in this paper work today:
- API Security: Deploy an AuthZEN-compliant gateway PEP in front of your APIs
- MCP Security: Extend the same gateway to handle MCP tool invocations with dynamic context extraction
- MCP Apps Security: Secure interactive AI experiences with fine-grained, policy-driven authorization
Thanks to interoperability, the sky is the limit.
If you’re curious about implementing AuthZEN for your API or AI applications, or want to discuss MCP Apps security patterns, I’d be happy to connect.
Resources
Specifications
- AuthZEN Authorization API 1.0
- OpenID Foundation AuthZEN Working Group
- Model Context Protocol Specification
Reference Implementation
- API/AI AuthZEN Gateway - MCP-aware policy enforcement with dynamic context extraction and multiple PDP support