· 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.

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.

Standars

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:

  1. 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.

  2. Growing complexity that doesn’t scale: As systems expand, authorization rules multiply exponentially. Embedded logic becomes unmaintainable and inconsistent across services.

  3. 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": {}
}
ComponentDescription
subjectThe entity requesting access (user, service, agent)
resourceThe target of the access request
actionThe operation being performed
contextAdditional 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.

AuthZEN Sequence 1

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:

  1. Extracts preferred_username, roles, tenant, acr, and amr from the JWT
  2. Builds an AuthZEN request with the resource set to the HTTP URI and action as the HTTP method
  3. Sends the request to the Cerbos PDP
  4. Cerbos evaluates whether the policy allows the action for this user
  5. 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_expense with 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:

AuthZEN Sequence 2

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 body
  • mcp::tool::arguments:<name>: Extracts specific tool arguments
  • enforce_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:

RoleView ExpensesApprove ExpensesDelete Expenses
Expenses > AnalystYesYesNo
Expenses > AdminYesYesYes

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:

  1. Same context extraction process
  2. AuthZEN request with action fintech_view_expenses
  3. PDP evaluates: User is analyst, authenticated with passkeys, action is view → ALLOW
  4. 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:

  1. Same context extraction process
  2. AuthZEN request with action fintech_approve_expense
  3. PDP evaluates: User is analyst, authenticated with passkeys, action is approve → ALLOW
  4. 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:

  1. Same context extraction
  2. AuthZEN request with action fintech_delete_expense
  3. PDP evaluates: User is analyst (not admin), action is delete → DENY
  4. 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:

AuthZEN Sequence 3

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

BenefitDescription
InteroperableWorks with any AuthZEN-compliant PDP—switch vendors without code changes
FlexibleSupports PBAC, ReBAC, ABAC, or hybrid models based on your requirements
Standards-basedBuilt on OpenID Foundation specifications with industry backing
MCP Apps readySecure interactive AI experiences with the same patterns as APIs
DynamicRuntime evaluation adapts to changing context and policies
AuditableCentralized 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

Reference Implementation

  • API/AI AuthZEN Gateway - MCP-aware policy enforcement with dynamic context extraction and multiple PDP support
Back to Blog