使用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。
请求流:
- SRE代理调用APIM网关端点(外部)
- APIM验证API密钥(或OAuth2令牌,如果已配置)
- APIM应用速率限制并记录请求
- APIM路由到MCP服务器(具有API密钥的外部容器应用程序)
- MCP服务器使用托管身份+私有链接查询日志分析
- 响应通过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 Developer2.构建并推送容器镜像
⚠️ 必须首先构建容器映像。 图像 ghcr.io/bandarudheeraj/log-analytics-mcp:latest 不公开存在。# Build using Azure Container Registry (no local Docker needed)
az acr build `
--registry `
--image log-analytics-mcp:latest `
./prototypes/log-analytics-mcp-server3.部署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 .azurecr.io/log-analytics-mcp:latest `
--registry-server .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入境。
{{SREAgentAppId}}
-->
应用策略:
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.xml7.配置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}/.default8.测试网关
# 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基础架构集成
相关样本
- 私有Direct3D可观察性 -MCP服务器位于私有的ViewModel中
- 日志分析MCP服务器 -此示例中使用的MCP服务器
