Secure Your MCP Server with Service Principal Authentication for Copilot Studio

In my previous post, we explored how to secure an MCP Server using Microsoft Entra ID delegated permissions, where the user’s identity is passed through to the API.

Secure Your MCP Server with Entra ID Authentication for Copilot Studio

But what if your scenario does not require user context?

What if you want:

  • A centralized connection
  • No per-user sign-in prompts
  • A backend service-to-service integration

In this post, we’ll walk through how to secure an MCP Server using application permissions (service principal authentication) and integrate it with Copilot Studio.

Introduction

MCP Servers exposed to Copilot Studio can be secured using different OAuth patterns:

  • Delegated permissions → user context
  • Application permissions → app-only context

This post focuses on the application permission model, where:

  • Copilot Studio uses a service principal (client credentials flow)
  • MCP Server validates app tokens instead of user tokens
  • No user interaction is required at runtime

Why Use Application Permissions?

Delegated access is great when you need user context. But in many enterprise scenarios:

  • Background operations don’t need user identity
  • Shared tools should behave consistently
  • Managing per-user connections becomes overhead

With application permissions:

  • Authentication is centralized
  • No per-user connection creation
  • Better suited for automation and shared agents

Prerequisites

Before starting:

  • Access to Microsoft Entra ID
  • Access to Copilot Studio and Power Platform
  • MCP Server implementation (you can reuse the same repo)
  • Permissions to create app registrations and custom connectors

Architecture Overview

In this setup:

  • MCP Server → Protected API (App roles enabled)
  • Copilot Client → Service principal (client credentials flow)
  • Entra ID → Issues app-only tokens

Flow:

  1. Copilot (via connector) authenticates using service principal
  2. Entra ID issues app-only token
  3. Token is sent to MCP Server
  4. MCP Server validates role-based access

Step 1: Update MCP Server App Registration (Resource API)

Go to your existing MCP Server app registration created from the instructions in my other post.

Create App Roles

Navigate to App roles → Add new role:

  • Display name: Access MCP Server API
  • Allowed member types: Applications
  • Value: api.server.access
  • Description: Allows access to MCP Server as an application

This is the key difference from delegated setup.

Instead of scopes, we have defined app roles for applications. Copy the resource url from the api permissions. E.g: api//xxxxx-xxxx-xxxx-xxx

Step 2: Configure Copilot Client App (Service Principal)

Go to your second app registration (Copilot client).

Add Application Permission

  • API permissions → Add permission
  • My APIs → Select MCP Server app
  • Choose Application permission → api.server.access

Grant Admin Consent

This allows the client app to call MCP Server without a user

Copy the client id, client secret for entering in the security tab while creating the custom connector.

Step 3: Create Custom Connector in Power Platform

Unlike the delegated setup, this time we do not add MCP Server directly from Copilot Studio.

Instead:

  • Go to make.powerapps.com
  • Create a Custom Connector
  • Configure:
    • Security → OAuth 2.0
      1. Enable Service Principal support

This connector uses the service principal credentials. After the entering the above details, click create connector. After the connector is created, copy the redirect URL to enter it in the Copilot studio client app registration

Now we can add the action Invoke server as below

Update the connector. Now Toggle Swagger editor to add x-ms-agentic-protocol: mcp-streamable-1.0 as shown below

What It Does

Declares MCP Server Compatibility with Power Platform Agents

This extension tells Power Platform (and AI agents like Copilot) that your connector:

ComponentMeaning
x-ms-Microsoft-specific extension (not standard OpenAPI)
agentic-protocolIndicates the API supports agentic/AI agent operations
mcp-streamable-1.0Uses Model Context Protocol v1.0 with streaming support

What This Enables

  1. Agentic Discovery – Agents can discover available tools/operations
  2. Streaming Responses – Support for long-running async operations with streaming results
  3. Native MCP Integration – Direct compatibility with MCP clients and servers
  4. Agent Invocation – AI agents can invoke your MCP server endpoints intelligently

Step 4: Create Connection Using Service Principal

After updating the connector:

  • Create a new connection from the Test Tab in custom connector creation interface
  • Provide the below from your Copilot studio client app registration:
    • Client ID
    • Client Secret
    • Tenant ID

This creates a shared connection

Key difference:

  • No user login prompt
  • Connection is tied to service principal, not individuals

Step 5: Add MCP Server to Copilot Studio

Now go to Copilot Studio:

  • Open your agent
  • Add Tool → Browse existing MCP Servers
  • Select your MCP connector and the connection as below

Important configuration in Copilot studio after the tool/MCP server is added:

  • Credentials to use: Maker provided
  • Save

This ensures:

  • The agent always uses the same connection
  • No per-user authentication required

Step 6: Test the MCP Agent

Now test your agent:

  • Invoke MCP tool
  • Verify response

You should see:

  • No login prompts
  • Consistent responses
  • Backend authentication working

Delegated vs Application Permissions

FeatureDelegatedApplication
IdentityUserApp
Token TypeUser tokenApp token
ConsentUser/AdminAdmin only
ConnectionPer userShared
Use CaseUser-specific dataBackground/shared APIs

Summary

In this post, we covered:

  • Securing MCP Server using application permissions
  • Creating app roles for application access
  • Assigning application permissions to client app
  • Creating custom connector in Power Platform
  • Using service principal connection
  • Adding MCP server to Copilot Studio via existing connector
  • Configuring maker-provided authentication

Why This Matters

Using application permissions is critical when:

  • You want centralized authentication
  • Your MCP tools don’t require user context
  • You want to avoid connection sprawl
  • You need consistent behavior across all users

This model is especially useful for:

  • Enterprise APIs
  • Shared automation tools
  • Backend integrations

Final Thoughts

Both delegated and application permission models have their place.

  • Use delegated when user identity matters
  • Use application permissions when it doesn’t

By implementing service principal authentication for your MCP Server, you enable:

  • Scalable architecture
  • Simplified connection management
  • Secure, app-driven integrations with Copilot Studio

Multiple ways to access your On-premise data in Microsoft 365 and Azure

If your organization is using a hybrid cloud environment, this post will shed some light to integrate on-premise resources with Microsoft 365 & Azure services. Hybrid integration platforms allows enterprises to better integrate services and applications in hybrid environments (on-premise and cloud). In this blog post, I will write about the different services & tools available with in Microsoft Cloud which allows you to connect or expose your On-premises data or application in Office 365. There are still many enterprise organizations on Hybrid mode due to various factors. It can be a challenging task to integrate your on-premises network but with right tools & services in Office 365 & Azure it can be easier. Find below the high-level overview & some references on how to

  1. Access your on-premise data in Power Platform & Azure Apps (Logic Apps, Analysis Services & Azure Data factory)
  2. Programmatically access your on-premise resources in your Azure Function app
  3. Access on-premise resources in Azure automation account
  4. Expose your on-premise Application or an existing WEB API in Office 365 cloud

Access on-premise data in Power Platform & Azure Apps (Logic Apps, Analysis Services & Azure Data factory):

The on-premises data gateway allows you to connect to your on-premises data (data that isn’t in the cloud) with several Microsoft cloud services like Power BI, Power Apps, Power Automate, Azure Analysis Services, and Azure Logic Apps. A single gateway can be used to connect multiple on premise applications with different Office 365 applications at the same time.

At the time of writing, with a gateway you can connect to the following on-premises data over these connections:

  • SharePoint
  • SQL Server
  • Oracle
  • Informix
  • Filesystem
  • DB2

To install a gateway, follow the steps outlined in MS documentation Install an on-premises data gateway. Install the gateway in standard mode because the on-premises data gateway (personal mode) is available only for Power BI.

Once the data gateway is installed & configured its ready to be used in the Power platform applications.

  1. PowerApps
  2. PowerAutomate
  3. PowerBI

The other catch the gateway is not available for the users with Power Automate/Apps use rights within Office 365 licenses as per the Licensing overview documentation for the Power Platform. Data gateways can be managed from the Power Platform Admin center.

Shane Young has recorded some excellent videos on this topic for PowerApps & PowerBI.

To use in

  1. Azure Logic Apps
  2. Azure Analysis service
  3. Azure Data Factory

create a Data Gateway resource in Azure.

High Availability data gateway setup:

You can use data gateway clusters (multiple gateway installations) using the standard mode of installation to setup a high availability environment, to avoid single points of failure and to load balance traffic across gateways in the group.

No need to worry about the security of the date since all the data which travels through the gateway is encrypted.

Data gateway architecture:

Find below the architecture diagram from Microsoft on how the gateway works

I recommend you to go through On-premises data gateway FAQ.

Integration Service Environment:

As per the definition from Microsoft an integration service environment is a fully isolated and dedicated environment for all enterprise-scale integration needs. When you create a new integration service environment, it’s injected into your Azure Virtual Network allowing you to deploy Logic Apps as a service in your VNET. The private instance uses dedicated resources such as storage and runs separately from the public global Logic Apps service. Once this logic apps instance is deployed on to your Azure VNET, you can access your On-premise data resources in the private instance of your Logic Apps using

  • HTTP action
  • ISE-labeled connector for that system
  • Custom connector

For the pricing of ISE, refer this link.

Programmatically access your on-premise resources in your Azure Function app

As you all know Azure Functions helps in building functions in the cloud using serverless architecture with the consumption-based plan. This model lets the developer focus on the functionality rather than on infrastructure provisioning and maintenance. Okay let’s not more talk about what a Function app can do but let us see on how to connect to your on-premise resources (SQL, Biztalk etc) within your function.

During the creation of a Function app in Azure, you can choose the hosting plan type to be

  • Consumption (Serverless)
  • Premium
  • App Service plan

Consumption based plan is not supported for the on-premise integration so while creating the app the hosting plan has to either premium or app service based plan & the Operating system has to to be Windows. On-premise resources can be accessed using

  1. Hybrid Connections
  2. VNet Integration

Hybrid Connections:

Hybrid Connections can be used to access application resources in private networks which can be on-premise. Once the Function app resource is created in Azure, go to Networking section of the App service to setup & configure. Go through the documentation from Microsoft for the detailed instructions to set this up.

How it works:

The Azure Hybrid Connection represents a connection between Azure App Service and TCP endpoint (host and port) of an on-premise system. On the diagram below Azure Service Bus Relay receives two encrypted outbound connections. One from the side of Azure App Service (Web App in our case) and another from the Hybrid Connection Manager (HCM). HCM is a program that must be installed on your on-premise system. It takes care of the integrations between the on-premise service (SQL in this case) with Azure Service Bus Relay.

Once the setup is done, you can create a connection string in Appsettings.json file or from Azure function app interface of your function app. After this you can access the data in your function app code.

I’ve found a couple of interesting blogs about this setup.

VNet Integration:

In the Networking features of the App service, you can add an existing VNET. An Azure Virtual Network (VNet) is a representation of your own network (private) in the cloud. It is a logical isolation of the Azure cloud dedicated to your subscription.

In Azure Vnet you can connect an on-premise network to a Microsoft VNet, this has been documented from Microsoft here. Once there is integration between your Azure Vnet & on-premise network and the VNet is setup on your function app you are set to access on-premise resources in your function app.

Access on-premise resources in Azure automation account:

Azure Automation is a service in Azure that allows you to automate your Azure management tasks and to orchestrate actions across external systems from right within Azure. Hybrid runbook worker feature allows you to access on-premise resources easily. The following diagram from Microsoft explains on how this feature works

I’ve written a blogpost recently about this feature for automating on-premise active directory.

Expose your on-premise Application or an existing WEB API in Office 365 cloud:

Azure Active Directory’s Application Proxy provides secure remote access to on-premises web applications (SharePoint, intranet website etc). Besides secure remote access, you have the option of configuring single sign-on. It allows the users to access on-premise applications the same way they access M365 applications like SharePoint Online, PowerApp, Outlook etc. To use Azure AD Application Proxy, you must have an Azure AD Premium P1 or P2 license.

How it works:

The following diagram from Microsoft documentation shows how Azure AD and Application Proxy works

Find below documentations on how to

  1. Add an on-premises application for remote access through Application Proxy in Azure Active Directory
  2. Secure access to on-premises APIs with Azure AD Application Proxy
  3. Use Azure AD Application Proxy to publish on-premises apps for remote users
  4. Deploy Azure AD Application Proxy for secure access to internal applications in an Azure AD Domain Services managed domain

Once the connector service is installed from your Azure AD application proxy, you can add an on-premise app as shown below

The above step will register an application with App registrations.

Summary: I’ve given some overview about the different services & tools to connect & integrate on-premise resources with Microsoft cloud. Hope you like this post & find it useful. Let me know any feedback or comments on the comment section below