Our State of Authorization: AI Edition is now available Get it now »

What Are MCP Apps and How Do You Secure Them? Using Dynamic Authorization for Enterprise AI Agents

Learn how to govern MCP applications, agentic UI, with attribute-based access control (ABAC).

You have probably read some version of this sentence already: “AI agents are moving beyond chat”. The first wave was mostly about retrieval and text generation: answer a question, summarize a document, draft an email, write a query. The second wave added action: agents calling APIs, writing records, triggering workflows. The wave now arriving brings something different — agents that can open and interact with rich user interfaces.

That idea has a name most of us already know.

JARVIS — the AI assistant from the Iron Man and Avengers films — did not just answer Tony Stark’s questions. It understood context, opened the right interface at the right moment, surfaced relevant data, let him interact with it, and acted on the results, all within a single fluid conversation.

That is the grand goal behind “MCP Apps”, or sometimes called MCP-UI. The Model Context Protocol (MCP) gives models a standard way to connect to tools and data. MCP Apps extend that pattern so an MCP server can return interactive HTML interfaces that render inside an MCP host. MCP Apps are not JARVIS yet, but they are the first concrete architecture that points in that direction. The official MCP Apps documentation describes interactive UI applications rendered in hosts such as Claude Desktop, with UI resources fetched by the host and displayed in a sandboxed iframe. The MCP Apps announcement describes tools returning dashboards, forms, visualizations, and multi-step workflows directly in the conversation.

OpenAI is moving in the same direction. ChatGPT developer mode supports full MCP client access for apps and tools, including write-capable developer workflows. The broader OpenAI Apps and MCP direction shows the same shift: agentic applications are becoming interactive workspaces where the host, the model, tools, and UI cooperate.

That brings us to a less flashy, but very enterprise-shaped, question: If agents can open rich UIs, inspect sensitive data, generate artifacts, and trigger business actions, where does authorization live?

Why MCP Apps Change Authorization

In a traditional web application, authorization is usually tied to routes, API endpoints, service calls, and database queries. The app knows the logged-in user, the page being rendered, the record being accessed, and the operation being attempted.

MCP Apps make the interaction more dynamic. A user can begin with a vague business request: “Can you check whether this customer is likely to churn before renewal?”

From that single prompt, the agent may call tools, open a UI, let the user interact with that UI, call more tools from those UI actions, generate a downloadable document, and write back to operational state.
Each step has a different authorization question:

  • Can this user open the customer workspace UI?
  • Can they see commercial fields?
  • Can they see support history?
  • Can they see billing status?
  • Can they export a renewal brief?
  • Can they create a support escalation?

Those decisions should not disappear just because the workflow began in a chat window. If anything, they matter more because the model is orchestrating the path through tools and interfaces at runtime.

The UI also changes the shape of the risk. A text answer might leak a sentence. An interactive workspace can expose fields, actions, generated documents, and operational writes. That makes authorization part of the UI contract, not just the API contract.

A Concrete Example: Customer Churn Risk

Imagine an enterprise customer-risk assistant.

A user asks: “Show me the churn and renewal risk for Acme Bank.”

The agent opens a customer-risk workspace through an MCP tool. The MCP server returns an interactive UI in the conversation. The workspace can show renewal risk, customer health, commercial context, support status, billing information, open escalations, and action buttons.

Example of MCP application

The important part is that the workspace is not identical for every user.

A Sales user with the right regional responsibility and clearance may see commercial, support, and billing sections. A Support user may open the same customer workspace but see commercial and billing details masked as “Sensitive Information (Access Denied).” An external contractor may be denied the workspace entirely for certain customers.

The UI is shaped by authorization decisions before it reaches the user. The same is true for actions. Exporting a renewal brief and creating a support escalation are separate capabilities, each checked independently.

“Couldn’t I Just Build a Web App?”

Yes. That is the fair question, and it deserves a straight answer.

If the workflow is already centered in a web application, and the assistant is mainly helping inside that app, a normal AI-enabled web UI may be the right choice. There is no prize for adding a protocol layer to a screen that is already exactly where it belongs.

MCP Apps become compelling when the conversation is the starting point and the UI is needed because the agent has reached a task that text cannot handle well. The user asks a business question. The agent decides a workspace is useful. The tool supplies the UI associated with that business capability. The host renders it in context, next to the conversation that caused it to appear.

That creates a different product shape:

  • The MCP server owns the business capability and the UI resource.
  • The host application owns the user session and renders the UI safely.
  • The agent decides when the UI is needed.
  • The UI can call back into MCP tools for follow-up actions.
  • The same capability can be surfaced across MCP-capable hosts.
  • Authorization can be enforced consistently at the MCP server boundary.

This matters for workflows where a text answer would be awkward, shallow, or risky. Churn investigation, contract review, entitlement changes, financial approvals, incident response, procurement reviews, and regulated case work all benefit from interfaces that let users inspect, compare, filter, and act.

The Architectural Big Picture

The architecture has five main participants: the user, the MCP host, the LLM agent, the MCP server, and the authorization engine. The MCP App UI appears inside the host, but sensitive reads and writes still go through the MCP server.

MCP architecture picture

The UI renders inside the host and should not be treated as the authorization boundary. Sensitive data and write operations still go through the MCP server, which calls the authorization engine.

The diagram also shows why a single “can use the app” check is not enough. Opening the workspace is a different decision from viewing billing fields. Exporting a renewal brief is a different decision from creating a support escalation. The authorization model needs to follow the workflow as it unfolds.

Why RBAC Gets Uncomfortable

The natural instinct at this point is to reach for roles. Most enterprise systems already have them, and they feel like a reasonable way to express who can do what. Role-based access control (RBAC) is familiar, useful, and often a perfectly reasonable starting point. It just gets uncomfortable here very quickly.

Suppose we start with four roles:

  • Sales
  • Support
  • Contractor
  • Admin

Sales users should not see every customer globally. They may only be responsible for a region. Support users may need support history but not commercial concession notes. A customer may be sensitive. Exporting a renewal brief may require higher clearance than opening a workspace. Creating an escalation may be appropriate for Support but not for Sales. External contractors may be allowed into a tightly scoped matter but not into broad customer browsing.
If we try to model all of that with roles, the role catalog starts breeding in the walls:

  • EMEA Sales
  • EMEA Sales Confidential
  • US Sales Confidential
  • Support Internal
  • Support Internal EMEA
  • Support Internal EMEA No Billing
  • Contractor Restricted

And we are still not done.

Dynamic authorization, also referred to as ABAC, is a better fit because the decision can use attributes about the subject, resource, action, and environment.

Category Example attributes
Subject department, region, clearance, employment type
Resource customer id, customer region, sensitivity, field group
Action open workspace, view field group, export brief, create escalation
Environment host, runtime context, purpose, risk level

Instead of creating a role for every combination, the policy evaluates the actual situation.

What the Policy Looks Like

The policy in this example is intentionally small. It is understandable in a few minutes while still showing why dynamic authorization is useful.

User Type Open customer workspace Commercial Fields Support Fields Billing Fields Export Renewal Brief Create support escalation
Sales, matching region, confidential 🟢 Permit 🟢 Permit 🟢 Permit 🟢 Permit 🟢 Permit 🔴 Deny
Sales, mismatched region 🔴 Deny 🔴 Deny 🔴 Deny 🔴 Deny 🔴 Deny 🔴 Deny
Support, matching region, internal 🟢 Permit 🔴 Deny 🟢 Permit 🔴 Deny 🔴 Deny 🟢 Permit
Support, mismatched region 🔴 Deny 🔴 Deny 🔴 Deny 🔴 Deny 🔴 Deny 🔴 Deny
External contractor 🔴 Deny 🔴 Deny 🔴 Deny 🔴 Deny 🔴 Deny 🔴 Deny

This compact policy already gives us a lot:

  • The same workspace renders differently for different users.
  • Customer region and user region can both matter.
  • Field visibility and action permission are separate.
  • Generated documents are protected by the same authorization model as UI data.
  • Operational writes, such as support escalation creation, are checked before state changes.

The same rules can be expressed in Abbreviated Language for Authorization (ALFA) so that policy remains readable while still being enforceable by the authorization engine.

policy AccessPolicy {
    apply denyUnlessPermit
    rule SalesOpenRegionalWorkspace {
        target clause subject.department == "Sales" and action.actionName == "open_customer_workspace"
        condition subject.region == resource.customerRegion
        permit
    }
    rule SupportOpenRegionalWorkspace {
        target clause subject.department == "Support" and action.actionName == "open_customer_workspace"
        condition subject.region == resource.customerRegion
        permit
    }
    rule SalesViewCommercial {
        target clause subject.department == "Sales" and subject.clearance == "confidential" and action.actionName == "view_commercial_fields"
        permit
    }
    rule SalesViewSupport {
        target clause subject.department == "Sales" and subject.clearance == "confidential" and action.actionName == "view_support_fields"
        permit
    }
    rule SalesViewBilling {
        target clause subject.department == "Sales" and subject.clearance == "confidential" and action.actionName == "view_billing_fields"
        permit
    }
    rule SupportViewSupportFields {
        target clause subject.department == "Support" and action.actionName == "view_support_fields"
        permit
    }
    rule SalesExportBrief {
        target clause subject.department == "Sales" and subject.clearance == "confidential" and action.actionName == "export_renewal_brief"
        permit
    }
    rule SupportCreateEscalation {
        target clause subject.department == "Support" and action.actionName == "create_support_escalation"
        permit
    }
}

MCP Server Enforces the Policy

The host app owns login. After sign-in, it passes the authenticated user to the MCP server as a bearer token. The agent does not log in to MCP separately, and the UI does not get to decide what is sensitive.

MCP server exposes business tools such as:

  • open_customer_risk_workspace
  • export_renewal_brief
  • create_support_escalation

Each tool converts the current request into authorization attributes: who the user is, what action is being attempted, which customer or field group is involved, and what runtime context applies. The authorization engine returns a decision, and the MCP server uses that decision before rendering UI, generating a document, or mutating state.

The workspace flow is the simplest example:

workspace_decision = authorize(
    subject=current_user,
    action="open_customer_workspace",
    resource=customer,
    environment=env,
)

field_decisions = {
    "commercial": authorize(subject=current_user, action="view_commercial_fields", resource=customer, environment=env),
    "support": authorize(subject=current_user, action="view_support_fields", resource=customer, environment=env),
    "billing": authorize(subject=current_user, action="view_billing_fields", resource=customer, environment=env),
}

return render_workspace(customer, visible=field_decisions) if workspace_decision.permitted else None

The exact code in a production system will vary, but the shape is the important part. The MCP server does not ask the model whether the user should see billing data. It asks the authorization engine and renders the workspace from those decisions.

The same rule applies to generated content. If the user cannot see commercial fields, those fields should not be included in the prompt context used to generate a renewal brief. The model should not become a polite, well-formatted side channel around authorization.

For write actions, the MCP server checks authorization before changing anything:

decision = authorize(
    subject=current_user,
    action="create_support_escalation",
    resource=customer,
    environment=env,
)

if decision.permitted:
    create_support_escalation(customer)

This is the core enforcement pattern: authorize at the server boundary, then shape the UI, generated content, and business action from the result.

Demo Video

In the video, we see three scenarios:

  1. A Sales user gets a rich customer workspace, exports a renewal brief, and sees the policy trace behind those decisions.
  2. A Support user sees the same workspace with commercial and billing data masked, then creates a support escalation that appears when the workspace is reopened.
  3. A restricted user is denied access to a protected workspace, showing that authorization applies before the UI is rendered, not just after the screen appears.

The conclusion to draw is simple: MCP Apps make agent workflows feel much more like real business applications, and that makes authorization a first-class design concern. If the UI can show sensitive data, generate documents, and trigger actions, policy needs to govern the whole path.

Other Use Cases

The same approach applies to many enterprise workflows.

Workflow MCP App UI Example policy decisions
Contract review Contract viewer, clause panel, approval buttons Who can see privileged notes? Who can approve risky clauses?
Financial operations Invoice, payment, and risk dashboard Who can approve by amount, region, or vendor sensitivity?
Security operations Incident timeline and containment actions Who can view affected systems? Who can trigger containment?
Healthcare operations Operational case or patient-related views Who can access data by purpose, role, location, or care team?
Procurement Supplier risk and sourcing actions Who can approve exceptions based on spend and region?

Customer churn risk is one example of the broader architecture. The useful part is the combination: the agent handles intent, the MCP server exposes capabilities, the MCP App provides the interface, and the authorization engine governs sensitive decisions.

Where Axiomatics Fits

This is where Axiomatics becomes important.

Agentic applications need authorization that can keep up with dynamic workflows. The model may choose tools at runtime. A UI may be returned by a tool. The user may trigger follow-up actions from inside the UI. Data may be summarized, transformed, or used to generate artifacts.

Hardcoded authorization checks inside every tool become difficult to reason about as the number of tools, hosts, and workflows grows. Application-specific conditionals also make policy harder to audit, explain, and reuse.
Axiomatics Authorization Engine gives teams a centralized ABAC decision point for these workflows. The application sends subject, action, resource, and environment attributes. The engine evaluates policy and returns a decision. That same policy model can support classic web apps, APIs, data services, MCP servers, agentic UI workflows, and batch processes generating reports.

MCP Apps make the user experience richer. ABAC makes the experience governable. Together, they give enterprise teams a realistic path for building agents that are useful enough to act and controlled enough to trust.

A Practical Path Forward

Technical teams experimenting with MCP Apps should treat authorization as part of the architecture from the beginning. Start with a few concrete workflows. Identify the data boundaries, action boundaries, and generated artifacts. Decide which attributes matter. Externalize the policy before tool logic turns into scattered conditionals.

For teams already thinking this way, Axiomatics Authorization Engine provides a mature dynamic authorization foundation for the next generation of agentic applications. The same policy discipline that protects APIs and applications can be brought into MCP servers and interactive agent workflows.

The interesting part of MCP Apps is not just that agents can render UI. It is that agents can invite users into richer workflows. The dream was always an agent like JARVIS — context-aware, interface-rich, capable of action. The gap between that vision and a production-ready MCP App is not just more AI. It is also the authorization layer that governs what the AI can see, do, and hand to the user.

Have 30 minutes? Let's show you a demo!

See how our award-winning solution can help you meet today's access control and Zero Trust needs.

Request a demo

  Join us on LinkedIn for more insights
Archived under:
About Ezzeldin Shereen

Ezzeldin Shereen is an AI engineer at Axiomatics where he works on integrating Axiomatics' award-winning authorization solutions into AI-driven systems and workflows. He received his PhD in Electrical Engineering from the Royal Institute of Technology in Stockholm, Sweden. His research background spans artificial intelligence, cybersecurity, and smart power grids, with numerous publications in top-tier peer-reviewed venues.