--- title: "Configuring the Azure API Management Authorizer" slug: "azure-api-management-authorizer-configuration" updated: 2026-10-11T16:33:55Z published: 2026-10-11T16:33:55Z canonical: "docs.plainid.io/azure-api-management-authorizer-configuration" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.plainid.io/llms.txt > Use this file to discover all available pages before exploring further. # Configuring the Azure API Management Authorizer This page walks through creating the Authorizer's policy fragments in Azure API Management (APIM), defining the named values they read, and applying them to your API operations in three patterns: authorizing a REST API, governing an MCP server, and enabling MCP discovery and Insights. The Authorizer is modular. Each capability comes from its own fragment, so you choose which capabilities to apply and add only the fragments they need. You make this choice per operation: one API can use enforcement and Insights together, while another uses Insights alone. You create each fragment once per APIM instance and then include it in any operation, API, or product policy. Because the fragments read Policies from PlainID at request time, you can change who can call what without editing your APIM configuration. ## Prerequisites Before you start, ensure you have: - Access to the [Microsoft Azure Portal](https://portal.azure.com/) and an APIM instance with the APIs or MCP servers you want to protect. - A PlainID Environment with access to the PDP (Runtime) endpoint. - A Scope in PlainID with a Client ID and Client Secret. - For MCP tool governance, an Asset Type for MCP tools (for example `MCP-TOOL`) and Policies that grant access to it. See [Tools and MCP](/v1/docs/mcp-policy-builder-controls) for more information. - For MCP discovery or Insights, your PlainID collector endpoint URL and a client certificate for it, uploaded to your APIM instance under **Security** > **Certificates**. See [Microsoft's guide to client certificate authentication](https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-mutual-certificates) for more information. You need only the prerequisites for the capabilities you choose. ## Upgrading from an Earlier Version If you configured an earlier version of the Authorizer, make the following changes: 1. Replace the PlainID policy XML you pasted into your operations with the fragments and `include-fragment` references described on this page. 2. Create the `plainidPdpUrl` named value and set it to your PDP Runtime base URL, for example `https://<host>/api/runtime`. Earlier versions read `plainidUrl` and expected a full decision URL. The fragments now append the endpoint path themselves. 3. Add the new named values listed below. APIM rejects a policy that references a named value that doesn't exist, so define every value the fragments you use require. ## Step 1: Choose Your Capabilities and Create Their Fragments Choose the capabilities you want, then create only the fragments they use. You can add more capabilities later by creating their fragments and including them in your policies. | Capability | Fragment ID | Section | What it does | | --- | --- | --- | --- | | API authorization | `api-enforcement` | Inbound | Authorizes each REST API call against the PDP and blocks denied calls. | | MCP tool governance | `mcp-enforcement` | Inbound **and** Outbound | Authorizes MCP `tools/call` requests and filters `tools/list` responses to the tools the caller may use. | | MCP discovery | `mcp-discovery` | Outbound | Registers each MCP server's full tool inventory with PlainID for Policy authoring. | | Insights and Agent discovery | `insights-discoverer` | Inbound | Intercepts the transactions that pass through APIM and reports them to PlainID, so PlainID discovers the Agents, clients, and APIs that call through APIM. | Each capability works on its own, and you can combine them freely, with one exception: an operation is either a REST API or an MCP endpoint, so don't include `api-enforcement` and `mcp-enforcement` on the same operation. **To create a fragment:** 1. In your APIM instance, go to **APIs** > **Policy fragments**. 2. Select **+ Create**. 3. Enter the **Fragment ID** exactly as it appears in the table above. 4. Paste the contents of the matching file from the `fragments` folder of the package. 5. Select **Create**. See [Microsoft's policy fragments documentation](https://learn.microsoft.com/en-us/azure/api-management/policy-fragments) for more information. ## Step 2: Define Named Values In your APIM instance, go to **Named values** and create the keys the fragments you use require. The tables below group the named values by fragment, so you define only the ones for the capabilities you chose. Use type **Secret** for `clientSecret`, and type **Plain** for everything else. See [Use named values in Azure API Management policies](https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-properties?tabs=azure-portal) for more information. APIM doesn't allow a blank named value. For values marked *Optional*, enter `none` to turn the setting off. ### Used by All Fragments | Name | Description | | --- | --- | | `enableTracing` | `true` writes Authorizer traces to Application Insights. `false` turns tracing off. | ### Used by `api-enforcement` and `mcp-enforcement` | Name | Description | | --- | --- | | `plainidPdpUrl` | Your PDP Runtime base URL, for example `https://<host>/api/runtime`. | | `clientId` | The Client ID from your PlainID Scope. | | `clientSecret` | The Client Secret from your PlainID Scope. Required even when `authenticationMethod` is `token`. | | `authenticationMethod` | `token` forwards the caller's `Authorization` header (JWT) to the PDP. `secret` authenticates with the Client Secret instead. | | `runtimeFineTune` | *Optional*. A JSON object added to every PDP request, for example to request Policy details or set the Identity type. | | `runtimeRequestTimeout` | The PDP request timeout in seconds, for example `60`. | | `headersToForward` | *Optional*. A comma-separated list of up to **5** request headers to forward to the PDP, for example `X-User-Token,X-Agent-Token`. Header names are case-insensitive. | ### Used by `api-enforcement` Only | Name | Description | | --- | --- | | `onPreventStatusCode` | The HTTP status code APIM returns when it blocks a request, for example `403`. | | `onPreventContentType` | The `Content-Type` of the blocked response, for example `application/json`. | | `onPreventBody` | The body of the blocked response, for example `{ "code": 403, "error": "Forbidden" }`. | ### Used by `mcp-enforcement` Only | Name | Description | | --- | --- | | `toolsResourceType` | The Asset Type for MCP tools in PlainID, for example `MCP-TOOL`. | | `mcpErrorCode` | The JSON-RPC error code returned when the Authorizer denies a tool call. Must be an integer, for example `-32603`. | | `mcpErrorMessage` | The JSON-RPC error message returned when the Authorizer denies a tool call, for example `Access Denied`. | ### Used by `mcp-discovery` and `insights-discoverer` | Name | Description | | --- | --- | | `collectorUrl` | Your PlainID collector endpoint URL. | | `collectorCertificateThumbprint` | The thumbprint of the client certificate APIM presents to the collector. The certificate must exist under **Security** > **Certificates**. | ### Example Configuration This example defines every named value, for an APIM instance that uses all capabilities. ``` plainidPdpUrl: https:///api/runtime clientId: PYX9B9H5S29IBG9OEISG clientSecret: **** authenticationMethod: token enableTracing: true runtimeRequestTimeout: 60 headersToForward: X-User-Token,X-Agent-Token runtimeFineTune: { "includeAccessPolicy": "true", "includeAccessPolicyId": "true", "includeDetails": true, "includeAssetAttributes": true, "includeIdentity": true, "includeIdentityAttributes": true, "entityId": "userId", "entityAttributes": { "identityattr1": ["identityAtt1Value"] }, "entityTypeId": "User" } onPreventStatusCode: 403 onPreventContentType: application/json onPreventBody: { "code": 403, "error": "Forbidden" } toolsResourceType: MCP-TOOL mcpErrorCode: -32603 mcpErrorMessage: Access Denied collectorUrl: https:///collector collectorCertificateThumbprint: ``` ## Step 3: Apply the Fragments **To add a policy to an operation:** 1. In the Azure Portal, open the API and select the operation you want to protect. 2. In **Inbound processing**, select **Add policy** > **Other policies**. 3. Paste the matching example below into the policy editor, adjusting fragment references as needed. 4. Select **Save**. See [Azure's guide to configuring policies in the portal](https://learn.microsoft.com/en-us/azure/api-management/set-edit-policies?tabs=form#configure-policy-in-the-portal) for detailed steps. The examples below show common combinations. To match the capabilities you chose, add or remove `include-fragment` lines. For example, to use only Insights on an operation, include `insights-discoverer` and nothing else. ### Authorize a REST API This example authorizes every call to the operation and reports it to Insights. Remove the `insights-discoverer` line if you don't need Insights. ``` ``` You can also apply this policy to a whole product under **APIs** > **Products** > *your product* > **Policies** > **Inbound processing**. With this configuration, APIM handles each call as follows: | PDP result | What APIM does | | --- | --- | | Permit | Forwards the request to the backend service with an added `X-Authorized-By: PlainID` header. | | Deny | Returns `onPreventStatusCode`, `onPreventContentType`, and `onPreventBody` to the caller. | | Error or timeout | Blocks the request and returns the same deny response. | ### Govern an MCP Server This example filters the tools each Agent sees, authorizes every tool call, and registers the MCP server's tool inventory with PlainID. `mcp-enforcement` appears in both the inbound and outbound sections, and `mcp-discovery` comes before it in outbound, so PlainID receives the complete tool list before the Authorizer filters it. Remove the `insights-discoverer` or `mcp-discovery` line if you don't need that capability. ``` ``` With this configuration, APIM handles each MCP request as follows: | Request | What APIM does | | --- | --- | | `tools/list` | Returns only the tools the caller's Policies allow. If PlainID returns no entitlements, the list is empty. | | `tools/call`, permitted | Forwards the call to the MCP server. | | `tools/call`, denied, error, or timeout | Returns a JSON-RPC error with `mcpErrorCode` and `mcpErrorMessage`. The response `id` matches the request, so MCP clients match the error to the pending call. | | `POST` with a body that isn't a single JSON object, including JSON-RPC batches | Returns the same JSON-RPC error. | | `GET` and `DELETE` (SSE stream and session requests) | Passes through unchanged. | | Other JSON-RPC methods, such as `initialize` | Passes through unchanged. | The Authorizer supports both plain JSON and SSE-framed (Streamable HTTP) responses from the MCP server, and keeps the original framing when it filters a tool list. ### Enable MCP Discovery and Insights MCP discovery and Insights run alongside enforcement or on their own: - `insights-discoverer` (Insights) intercepts every transaction that reaches the operation and reports it to PlainID, including the caller's source IP, headers, URL, destination, and body. Place it first in the inbound section, before any enforcement fragment. - `mcp-discovery` (MCP discovery) registers the MCP server's full tool list each time an Agent calls `tools/list`. Neither fragment affects the authorization decision. Each report uses a one-second timeout and ignores collector errors, so a collector outage adds at most one second to a request and doesn't block it. ## Troubleshooting Set `enableTracing` to `true` to write traces to the **traces** table in Application Insights. Filter by source to find the Authorizer's entries: | Trace source | Written by | | --- | --- | | `PlainID Authorization` | `api-enforcement` | | `PlainID MCP Enforcement` | `mcp-enforcement` | | `PlainID MCP Discovery` | `mcp-discovery` | | `PlainID Insights Discoverer` | `insights-discoverer` | Each REST API trace includes the request ID, the authorization result, the request sent to the PDP, and the PDP response. The Authorizer adds an `X-Request-ID` header to requests that don't have one and returns it on blocked responses, so you can match a caller's error to its trace. Traces contain full request headers, including tokens. Turn tracing off when you finish troubleshooting. ## Notes - `mcp-enforcement` must appear in both the inbound and outbound sections of an MCP operation. Including it in only one section isn't supported. - `headersToForward` supports up to **5** headers. - To filter tool lists and register tools, `mcp-enforcement` and `mcp-discovery` read and rewrite the MCP server's response body. This can cause APIM to buffer the response. Validate this against your MCP server before relying on it in production, especially if your server streams large or long-lived responses.