容器应用代理服务

一个基于Azure容器应用的零秘密认证代理服务,支持企业级安全和基础设施即代码部署。

  • by abossard
  • HCL
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 abossard/aca-mcp-proxy-obo-flow

使用说明

🚀 具有联合身份的Azure容器应用MCP代理

模型上下文协议(MCP)包装器/代理 部署在Azure容器应用程序上 零秘密 使用Entra ID联合凭据进行身份验证。

🎯 这有什么作用?

该项目展示了 生产就绪模式 用于在Azure上部署具有企业级安全性的容器化API:

  • 🔐 没有秘密存储在任何地方 -使用联合身份凭据
  • 🎫 Entra ID身份验证 通过容器应用程序上的EasyAuth
  • 🏗️ 基础设施即代码 使用Terraform和Azure Developer CLI
  • ⚡ 本地AOT编译 用于快速启动和最小内存
  • 📊 内置可观察性 应用洞察

🏛️ 建筑

graph TB
    subgraph "🌐 Azure Cloud"
        subgraph "Container App Environment"
            API[("🔵 API Container<br/>.NET 9 AOT")]
        end
        
        ACR[("📦 Container Registry<br/>ACR")]
        ENTRA[("🎫 Entra ID<br/>App Registration")]
        MI[("🔑 Managed Identity")]
        APPINS[("📊 App Insights")]
        
        API -->|pulls image| ACR
        API -->|uses| MI
        MI -.->|federated credential| ENTRA
        API -->|auth via EasyAuth| ENTRA
        API -->|telemetry| APPINS
    end
    
    USER[("👤 User")] -->|HTTPS + Auth| API
    
    style API fill:#0078D4,stroke:#003d7a,color:#fff
    style ENTRA fill:#00A4EF,stroke:#0078D4,color:#fff
    style MI fill:#7FBA00,stroke:#5e8700,color:#fff
    style ACR fill:#0078D4,stroke:#003d7a,color:#fff
    style APPINS fill:#E81123,stroke:#a30d1a,color:#fff

🔐 零秘密身份验证流程

sequenceDiagram
    participant U as 👤 User
    participant CA as 🔵 Container App
    participant EA as 🎫 EasyAuth
    participant MI as 🔑 Managed Identity
    participant ENTRA as 🏢 Entra ID
    
    U->>CA: Request (no token)
    CA->>EA: Check authentication
    EA->>ENTRA: Redirect for login
    ENTRA->>U: Login page
    U->>ENTRA: Authenticate
    ENTRA->>EA: Return token
    EA->>CA: Forward with token
    CA->>U: Response
    
    Note over MI,ENTRA: MI ↔ App Registration<br/>via Federated Credential

🚦 快速开始

先决条件

🎬 部署一切

# One command to rule them all
azd up

这将:

  1. 📦 使用AOT编译构建容器映像
  2. 🏗️ 提供Azure基础架构(容器应用程序、ACR、Entra ID应用程序)
  3. 🔐 配置联合身份凭据
  4. 🚀 部署容器
  5. 🔗 输出API端点URL

🧪 本地开发

cd src/MCPWrapper/MCPWrapper.Api
dotnet run

访问地址: http://localhost:5000 (或检查控制台输出端口)

📁 项目结构

📂 aca-mcp-proxy-obo-flow/
├── 📂 .github/
│   └── copilot-instructions.md    # 🤖 AI agent guidance
├── 📂 infra/                       # 🏗️ Terraform IaC
│   ├── identity.tf                 # 🔐 Managed Identity + Entra ID
│   ├── containerapps.tf            # 🔵 Container App + Auth config
│   ├── main.tf                     # 🏛️ Core resources (ACR, Log Analytics)
│   ├── rbac.tf                     # 👥 Role assignments
│   └── provider.tf                 # ⚙️ Provider configuration
├── 📂 src/MCPWrapper/
│   └── MCPWrapper.Api/             # 💻 .NET 9 API
│       ├── Program.cs              # 🎯 Minimal API with AOT
│       ├── Dockerfile              # 🐳 Multi-stage build
│       └── MCPWrapper.Api.csproj   # 📦 Project config
└── azure.yaml                      # 🎛️ Azure Developer CLI config

🔑 主要特点

🛡️ 安全

  • 零秘密 -联合身份凭证模式
  • EasyAuth -平台级身份验证(无需更改代码)
  • 管理身份 -用于ACR拉取和未来的Azure服务访问
  • Entra ID集成 -企业身份提供者

⚡ 演出

  • 本地AOT编译 -启动速度更快,内存更少
  • 苗条的建设者 -最小运行时间占用
  • 容器优化 -高效图像层

🔧 开发者体验

  • Azure开发者命令行界面 -简化部署工作流程
  • 基础设施即代码 -可再生环境
  • 应用洞察 -内置可观测性

🎯 为什么选择AzAPI提供商?

这 azurerm Terraform提供程序尚不支持容器应用程序身份验证块(在中跟踪 第22213期).我们使用 AzAPI提供商 直接调用ARM API:

resource "azapi_resource" "api_auth_config" {
  type = "Microsoft.App/containerApps/authConfigs@2023-05-01"
  # ... EasyAuth configuration
}

🔄 常见任务

📊 查看日志

azd monitor --overview

🔄 重新部署代码

azd deploy

🗑️ 清理资源

azd down

🧹 本地地形操作

cd infra
terraform plan -var-file=main.tfvars.json
terraform apply -var-file=main.tfvars.json

🚀 部署场景和配置

该项目支持两种不同的部署模型,以适应不同的组织约束(例如,“M团队”与“J团队”)。

场景A:完全配置(“M团队”/开发)

适用于: 开发人员、POC和您有权创建Entra ID应用程序注册的环境。

在此模式下,Terraform管理 一切:

  • Azure基础架构(容器应用程序、ACR等)
  • Entra ID资源 (应用程序注册、服务主体、联合凭据)
  • 管理员同意 (通过Terraform中的API调用)

配置:

enable_entra_setup = true
entra_app_name     = "mcp-proxy-dev"

场景B:预先配置的身份(“J团队”/制作)

适用于: 由单独团队管理身份资源的生产环境或受限组织。

在此模式下,Terraform 仅 部署Azure基础架构。它期望Entra ID资源存在,并将其ID作为输入。

配置:

enable_entra_setup = false

# Pass the details of the pre-created App Registration
existing_entra_config = {
  client_id = "00000000-0000-0000-0000-000000000000"
  tenant_id = "00000000-0000-0000-0000-000000000000"
  object_id = "00000000-0000-0000-0000-000000000000" # Service Principal Object ID
}

🌐 网络选项

该项目通过Terraform变量支持灵活的网络配置:

变量 默认值 描述
enable_public_network true 真:应用程序可通过公共互联网访问。
错误的:应用程序仅是私有的(需要私有端点或ExpressRoute集成)。
create_dummy_vnet true 真:创建用于测试的新的Direct3D/子网。
错误的:使用现有的ExpressRoute(必须提供 container_apps_subnet_id).
container_apps_subnet_id "" 容器应用程序环境的现有子网ID(如果是必需的 create_dummy_vnet = false).
private_endpoint_subnet_id "" 放置专用终结点的子网ID(如果 enable_public_network = false).

🎨 环境变量

容器应用程序会自动接收:

变量 描述 来源
AZURE_TENANT_ID Entra ID租户 自动注入
AZURE_CLIENT_ID 托管身份客户端ID 自动注入
APPLICATIONINSIGHTS_CONNECTION_STRING 遥测端点 地形输出
API_ENDPOINT 容器应用程序URL 已计算
ASPNETCORE_ENVIRONMENT 运行时环境 配置

🤝 贡献

看 .github/copilot-instructions.md 了解详细的架构指导和惯例。

📚 了解更多

📄 许可证

MIT许可证-有关详细信息,请参阅许可证文件


🌟 内置于❤️ 使用Azure容器应用程序和Terraform