API管理安全网关

利用Azure API Management作为安全网关,为企业提供OAuth2认证、速率限制、请求日志和统一入口的MCP服务器访问解决方案。

  • by BandaruDheeraj
  • Bicep
  • 本地部署
  • 更新于
在 GitHub 查看 BandaruDheeraj/apim-mcp-gateway

使用说明

使用Azure API管理网关确保MCP访问安全

演示如何将Azure API管理作为 安全网关 使用企业级策略、身份验证和监控将MCP服务器暴露给Azure SRE代理。

场景概述

问题:您有MCP服务器提供对Azure资源(日志分析、Kubernetes等)的访问,但您需要企业控制:速率限制、身份验证、审计日志记录以及多个后端的单个入口点。

解决方案:Azure API管理在MCP服务器前充当安全网关。APIM提供OAuth2身份验证、速率限制、缓存、请求日志记录,并可以通过单个端点路由到多个MCP后端。

建筑

┌──────────────────────────────────────────────────────────────────────────────┐
│                                 INTERNET                                      │
│                                                                               │
│                           ❌ CLI BLOCKED                                      │
│                 az monitor log-analytics query → DENIED                       │
└───────────────────────────────────┬──────────────────────────────────────────┘
                                    │
                                    ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│                    Azure API Management (Developer SKU)                       │
│                                                                               │
│  • OAuth2/Entra ID Auth      • Rate Limiting     • Request Logging           │
│  • API Key validation        • Policy Enforcement                            │
│  • Centralized entry point for MCP access                                    │
│                                                                               │
│  https://apim-xxx.azure-api.net/log-analytics/mcp/                          │
└────────────────────────────────────┬─────────────────────────────────────────┘
                                     │ HTTPS (Public)
                                     ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│                     Virtual Network (10.0.0.0/16)                             │
│                                                                               │
│  ┌──────────────────────────────┐     ┌──────────────────────────────────┐  │
│  │   Container Apps Subnet       │     │   Private Endpoints Subnet       │  │
│  │        (10.0.0.0/23)          │     │        (10.0.2.0/24)             │  │
│  │                               │     │                                   │  │
│  │  ┌─────────────────────────┐  │     │  ┌─────────────────────────────┐ │  │
│  │  │   Log Analytics MCP     │  │     │  │  AMPLS Private Endpoint     │ │  │
│  │  │        Server           │──┼─────┼─▶│                             │ │  │
│  │  │                         │  │     │  └──────────────┬──────────────┘ │  │
│  │  │  🔑 API Key Protected   │  │     │                 │                │  │
│  │  │  External ingress       │  │     └─────────────────┼────────────────┘  │
│  │  │  VNet-integrated        │  │                       │                    │
│  │  └─────────────────────────┘  │                       │                    │
│  └──────────────────────────────┘                        │                    │
└──────────────────────────────────────────────────────────┼────────────────────┘
                                                           │ Private Link
                                                           ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│                   Azure Monitor Private Link Scope (AMPLS)                    │
│                                                                               │
│   queryAccessMode: PrivateOnly  ◀── BLOCKS public queries                    │
│                                                                               │
│   ┌───────────────────────────────────────────────────────────────────────┐  │
│   │              Log Analytics Workspace (PRIVATE)                         │  │
│   │                                                                        │  │
│   │   publicNetworkAccessForQuery: Disabled  ◀── CLI/Portal BLOCKED       │  │
│   └───────────────────────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────────────────────┘

💡 备注:此示例使用 外部容器应用程序 API关键成本效率验证(约50美元/月APIM开发人员)。对于 真正的网络隔离 其中APIM是唯一的入口点,请参阅 博客文章 这需要 高级APIM (约700美元/月),并集成ExpressRoute。

请求流:

  1. SRE代理调用APIM网关端点(外部)
  2. APIM验证API密钥(或OAuth2令牌,如果已配置)
  3. APIM应用速率限制并记录请求
  4. APIM路由到MCP服务器(具有API密钥的外部容器应用程序)
  5. MCP服务器使用托管身份+私有链接查询日志分析
  6. 响应通过APIM返回(记录+缓存)

为什么这行得通(CLI不行):

  • 日志分析工作区具有 publicNetworkAccessForQuery: Disabled
  • 外部的直接CLI查询包括 已屏蔽
  • MCP服务器运行在一个ExpressRoute集成的容器应用程序环境中
  • MCP服务器具有AMPLS(Azure Monitor专用链路作用域)的专用链路访问权限
  • MCP服务器 能 通过专用连接查询日志分析
  • 这演示了MCP如何桥接对锁定资源的访问

主要优势

挑战 没有MCP网关 有MCP网关
🔒 私人资源 CLI被网络规则阻止 MCP通过专用链路桥接
🔐 认证 每个MCP服务器的API密钥 集中式OAuth2/Entra ID
⚡ 速率限制 无-过载风险 每个客户端配额和限制
📊 监控 分散的日志 统一的应用程序洞察
🔄 多个后端 要管理的多个URL 单个网关端点
🛡️ 安全策略 按服务器实施 集中式策略管理
📝 审计跟踪 可见性有限 完整的请求/响应日志记录

私有资源访问——核心价值主张

问题:

# This FAILS from your laptop - Log Analytics blocks public queries
az monitor log-analytics query --workspace $workspaceId --analytics-query "Heartbeat | take 5"
# ERROR: Access denied. publicNetworkAccessForQuery: Disabled

解决方案:

# This WORKS via MCP Gateway - MCP Server has Private Link access
curl -X POST "https://your-apim.azure-api.net/log-analytics/mcp/" \
  -H "Authorization: Bearer $token" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"query_logs","arguments":{"query":"Heartbeat | take 5"}},"id":1}'
# SUCCESS: Query results returned via MCP Server inside VNet

✅ 测试和验证(2026年1月)

该样本经过端到端测试,结果如下:

组件 状态 注释
容器映像构建 ✅ 通过以下方式构建 az acr build 到 sreagentmcpacr
MCP服务器(容器应用程序) ✅ 外部入口,VNet集成,API密钥保护
IMAP+专用链接 ✅ AMPLS带 queryAccessMode: PrivateOnly
管理身份+RBAC ✅ 分配了日志分析阅读器角色
MCP tools/list ✅ 返回5个工具(query_logs、list_tables等)
MCP list_tables ✅ 已成功查询私有日志分析工作区
APIM网关 ✅ 开发人员SKU,使用API密钥路由到MCP后端
APIM→ MCP → 私人洛杉矶 ✅ 全E2E流量通过网关工作

测试环境:

  • APIM : apim-apim-mcp-vnet-test-sdtn6z2y5uxmy.azure-api.net
  • MCP服务器: log-analytics-mcp.agreeablesea-122937a2.eastus2.azurecontainerapps.io
  • 日志分析工作区ID: 87fb2e86-b0f2-492c-be65-6a819471dc66
  • API密钥: demo-api-key-sdtn6z2y5uxmy

样本测试命令:

$headers = @{ "Content-Type" = "application/json"; "X-API-Key" = "demo-api-key-xxx" }
$body = '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_tables"}}'
Invoke-RestMethod -Uri "https://apim-xxx.azure-api.net/log-analytics/mcp/" -Method POST -Headers $headers -Body $body

先决条件

  • 具有参与者访问权限的Azure订阅
  • 已安装Azure CLI
  • 输入租户ID

快速开始

1.使用现有或部署API管理

选项A:使用现有的APIM实例(推荐)

# List existing APIM instances
az apim list --query "[].{name:name,rg:resourceGroup,sku:sku.name}" -o table

# Use an existing instance - no deployment wait time!
$apimName = "your-existing-apim"
$apimRg = "your-resource-group"

选项B:部署一个新的APIM实例(30-45分钟)

# Create resource group
az group create --name apim-mcp-gateway-rg --location eastus

# Create APIM instance (Developer tier - takes 30-45 min)
az apim create `
  --name mcp-gateway `
  --resource-group apim-mcp-gateway-rg `
  --publisher-name "Contoso" `
  --publisher-email "admin@contoso.com" `
  --sku-name Developer

2.构建并推送容器镜像

⚠️ 必须首先构建容器映像。 图像 ghcr.io/bandarudheeraj/log-analytics-mcp:latest 不公开存在。

# Build using Azure Container Registry (no local Docker needed)
az acr build `
  --registry <your-acr-name> `
  --image log-analytics-mcp:latest `
  ./prototypes/log-analytics-mcp-server

3.部署MCP服务器后端

# Create Container Apps environment
az containerapp env create `
  --name mcp-servers-env `
  --resource-group apim-mcp-gateway-rg `
  --location eastus

# Deploy with ACR image and credentials
az containerapp create `
  --name log-analytics-mcp `
  --resource-group apim-mcp-gateway-rg `
  --environment mcp-servers-env `
  --image <your-acr-name>.azurecr.io/log-analytics-mcp:latest `
  --registry-server <your-acr-name>.azurecr.io `
  --target-port 8000 `
  --ingress external `
  --env-vars "LOG_ANALYTICS_WORKSPACE_ID=your-workspace-id"

4.配置APIM后端

# Create backend pointing to Container App
az apim backend create `
  --resource-group apim-mcp-gateway-rg `
  --service-name mcp-gateway `
  --backend-id log-analytics-mcp `
  --url "https://log-analytics-mcp.internal.eastus.azurecontainerapps.io"

5.在APIM中创建API

# Create API
az apim api create `
  --resource-group apim-mcp-gateway-rg `
  --service-name mcp-gateway `
  --api-id log-analytics-mcp `
  --path log-analytics `
  --display-name "Log Analytics MCP"

# Create operation for MCP endpoint
az apim api operation create `
  --resource-group apim-mcp-gateway-rg `
  --service-name mcp-gateway `
  --api-id log-analytics-mcp `
  --operation-id mcp-post `
  --display-name "MCP POST" `
  --method POST `
  --url-template "/mcp/"

6.应用安全策略

创建 policy.xml:

⚠️ 重要: renewal-period 必须为1-300秒。 cache-store 需要 cache-lookup 入境。

<policies>
    <inbound>
        <base />
        
        <!-- OAuth2 Validation (uncomment after Entra ID setup) -->
        <!--
        <validate-azure-ad-token tenant-id="{{TenantId}}">
            <client-application-ids>
                <application-id>{{SREAgentAppId}}</application-id>
            </client-application-ids>
        </validate-azure-ad-token>
        -->
        
        <!-- Rate Limiting: 100 requests per 5 min (max 300 seconds) -->
        <rate-limit calls="100" renewal-period="300" />
        
        <!-- Set backend -->
        <set-backend-service backend-id="log-analytics-mcp" />
        
        <!-- Cache lookup (REQUIRED for cache-store) -->
        <cache-lookup vary-by-developer="false" vary-by-developer-groups="false" downstream-caching-type="none" />
    </inbound>
    
    <backend>
        <base />
    </backend>
    
    <outbound>
        <base />
        <!-- Cache responses for 5 minutes -->
        <cache-store duration="300" />
    </outbound>
</policies>

应用策略:

az apim api policy create `
  --resource-group apim-mcp-gateway-rg `
  --service-name mcp-gateway `
  --api-id log-analytics-mcp `
  --policy-format xml `
  --value-path ./policy.xml

7.配置SRE代理

name: EnterpriseObservabilityAgent
description: Query Azure resources through enterprise MCP gateway

mcp_tools:
  - LogAnalyticsMCP

tool_definitions:
  LogAnalyticsMCP:
    type: mcp
    transport: streamable_http
    url: https://mcp-gateway.azure-api.net/log-analytics/mcp/
    auth:
      type: oauth2
      tenant_id: ${TENANT_ID}
      client_id: ${CLIENT_ID}
      client_secret: ${CLIENT_SECRET}
      scope: api://${APIM_APP_ID}/.default

8.测试网关

# Get OAuth2 token
$token = (az account get-access-token --resource api://$APIM_APP_ID --query accessToken -o tsv)

# Call MCP through APIM
curl -X POST "https://mcp-gateway.azure-api.net/log-analytics/mcp/" `
  -H "Authorization: Bearer $token" `
  -H "Content-Type: application/json" `
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"list_tables"},"id":1}'

9.清理

az group delete --name apim-mcp-gateway-rg --yes --no-wait

此示例中的文件

文件 描述
azure.yaml Azure开发人员CLI配置
deploy-sample.ps1 完整部署脚本
policy.xml 带有OAuth2的APIM策略,速率限制
cleanup.ps1 删除所有资源
blog-post.md 完整教程文章
infra/ 二头肌基础结构模板
src/ MCP服务器源代码

预计成本

资源 每月成本 备注
API管理(开发人员) ~$50 不用于生产
API管理(基础) ~150美元 小型生产
API管理(标准) ~700美元 带有SLA的生产
容器应用程序 ~50-100美元 MCP服务器后端
应用洞察 可变 基于数据量

💡 小贴士:使用开发人员层进行学习,使用基础或标准层进行生产。

安全特性

1.OAuth2+Entra ID

  • 基于令牌的身份验证(无静态API密钥)
  • 根据客户身份
  • 可配置令牌到期

2.费率限制

  • 每客户配额
  • 防止滥用和DoS
  • 优雅降级

3.审计追踪

  • 完整的请求/响应日志记录
  • 应用洞察集成
  • 合规性就绪

4.立即撤销

  • 撤销客户的应用程序注册
  • 无需到处旋转按键

何时使用此模式

✅ 适合:

  • 多台MCP服务器 -用于日志分析、Kubernetes、Cosmos DB MCP的单网关端点
  • 企业身份验证 -需要OAuth2/Entra ID而不是API密钥
  • 需要速率限制 -保护后端免受过载或滥用
  • 审计要求 -完整的请求/响应日志记录到Application Insights
  • 现有APIM基础设施 -利用现有投资(无需新部署!)
  • 缓存需求 -缓存频繁查询以减少后端负载

❌ 考虑替代方案:

  • 单MCP服务器,简单认证 -使用API密钥直接访问更简单
  • 仅用于开发/测试 -跳过APIM开销,直接使用容器应用程序
  • 对成本敏感 -APIM增加了成本(根据级别,每月约50-700美元)
  • 私有Direct3D要求 -请参阅 私有Direct3D可观察性 改为取样

Direct3D集成选项

选项1:APIM外部模式(推荐)

APIM具有公共IP,但连接到ExpressRoute后端:

Internet → APIM (Public) → VNet → MCP Server (Internal) → Private Resources

选项2:APIM内部模式

APIM仅可从DateTime:

VPN/ExpressRoute → VNet → APIM (Private) → MCP Server → Private Resources

选项3:带专用端点的APIM

APIM使用专用链接来访问ExpressRoute资源:

Internet → APIM (Public) → Private Endpoint → VNet → Private Resources

后续步骤

  • 添加更多MCP服务器(Kubernetes、Cosmos DB、SQL)
  • 配置自定义域
  • 设置违反速率限制的警报
  • 与现有的APIM基础架构集成

相关样本