MCP TEE服务器——ACI上的Azure机密容器
⚠️ 免责声明——仅供参考 此存储库是 个人项目 作为OC3 2026演讲的伙伴分享。它是“按原样”提供的 仅供教育和参考确实如此 不 微软的官方产品 不支持 由微软,并携带 无保修或SLA 任何种类的。使用风险自负。这里表达的观点是作者自己的,并不代表微软的观点。
一个参考实现 主控程序 在具有AMD SEV-SNP的Azure容器实例上的硬件强制可信执行环境(TEE)内运行的服务器。
此示例伴随着OC3 2025演讲: “保护人工智能的新攻击面:为什么MCP服务器需要可信的执行环境”
问题
MCP服务器为其公开的每个工具聚合凭据-GitHub令牌、数据库密码、webhook URL、API密钥。传统的安全控制(IAM、保险库、网络边界、容器隔离)都无法应对单一威胁: 主机上的特权用户可以读取进程内存并以明文形式提取每个秘密。
解决方案
在ACI的机密容器内运行MCP服务器。AMD SEV-SNP硬件对所有飞地内存进行加密,即使是主机上的root也无法读取它 SKR侧三轮 执行硬件认证并释放RSA私钥,该私钥仅在TEE内部解密服务器的机密。
建筑
┌────────────────────────────────────────────────────────────────┐
│ HOST OS (untrusted — root yields nothing) │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ TEE BOUNDARY (AMD SEV-SNP, hardware-enforced) │ │
│ │ │ │
│ │ ┌────────────────────────┐ ┌────────────────────────┐ │ │
│ │ │ MCP Server │ │ SKR Sidecar │ │ │
│ │ │ (Python / FastMCP) │ │ (Go, port 9000) │ │ │
│ │ │ │ │ │ │ │
│ │ │ Tools: │ │ /key/release │ │ │
│ │ │ • github_search │ │ /attest/raw │ │ │
│ │ │ • query_database │ │ /attest/maa │ │ │
│ │ │ • send_notification │ │ │ │ │
│ │ │ • attestation_status │ │ AMD SEV-SNP quote │ │ │
│ │ │ │ │ ↕ │ │ │
│ │ │ Secrets (in-memory): │ │ Azure MAA (validate) │ │ │
│ │ │ • GITHUB_TOKEN ◄─┼──┤ ↕ │ │ │
│ │ │ • DB_CONN_STRING ◄─┼──┤ Key Vault (release) │ │ │
│ │ │ • WEBHOOK_URL ◄─┼──┤ │ │ │
│ │ └────────────────────────┘ └────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────┘秘密是如何工作的(信封加密)
秘密受到保护 信封加密 在Azure密钥保险库高级版中使用RSA-HSS密钥:
┌─ At provisioning time (your workstation) ──────────────────────┐
│ │
│ 1. Create RSA-HSM key in Key Vault with a release policy │
│ that binds the key to the container's CCE policy hash │
│ │
│ 2. Encrypt each secret with the RSA public key (OAEP-SHA256) │
│ python scripts/encrypt_secret.py --secret "ghp_xxx..." │
│ │
│ 3. Pass encrypted blobs as ENC_* env vars to the container │
│ (ciphertexts are safe to store — useless without the TEE) │
│ │
└────────────────────────────────────────────────────────────────┘
┌─ At runtime (inside the TEE) ──────────────────────────────────┐
│ │
│ 1. SKR sidecar generates AMD SEV-SNP hardware attestation │
│ quote and sends it to Azure MAA for validation │
│ │
│ 2. MAA returns a signed JWT with the CCE policy measurement │
│ │
│ 3. Key Vault evaluates the release policy — if the JWT │
│ measurement matches, the RSA private key is released │
│ │
│ 4. MCP server decrypts ENC_* env vars with the private key │
│ → plaintext secrets exist only in TEE-encrypted memory │
│ │
└────────────────────────────────────────────────────────────────┘关键属性:
- TEE之外的明文中从不存在秘密
- RSA私钥仅将密钥库留给经过验证的TEE
- 即使是Azure操作员/主机根也无法读取飞地内存
- 更改容器映像会使CCE策略哈希无效→ 密钥释放失败
项目结构
mcp-tee-sample/
├── README.md # This file
├── Dockerfile # Container image for the MCP server
├── src/
│ ├── server.py # MCP server with 4 tools + envelope decryption
│ ├── agent.py # MCP client — verifies attestation remotely
│ └── requirements.txt # Python dependencies
├── infra/
│ ├── main.bicep # ACI Confidential + KV + SKR sidecar + Identity
│ └── key-release-policy.json # Key Vault release policy template
└── scripts/
├── deploy.sh # End-to-end deployment automation
└── encrypt_secret.py # Encrypt a secret with the KV public key先决条件
| 工具 | 目的 |
|---|---|
Azure命令行界面(az) | 部署资源,管理密钥库 |
az confcom 扩展 | 生成CCE安全策略 |
| Docker | 为策略构建容器映像和哈希层 |
| Python 3.10+ | 运行MCP服务器和加密助手 |
cryptography (pip) | RSA加密 encrypt_secret.py |
# Install prerequisites
az extension add --name confcom
pip install cryptography快速开始
选项A:自动部署
# Full deploy: build → CCE policy → infra → envelope key
./scripts/deploy.sh --acr-name --resource-group
# With secrets (interactive prompts):
./scripts/deploy.sh --acr-name --resource-group --provision-secrets选项B:逐步
1.构建并推送容器镜像
docker build -t mcp-tee-server:latest .
az acr login --name
docker tag mcp-tee-server:latest .azurecr.io/mcp-tee-server:latest
docker push .azurecr.io/mcp-tee-server:latest2.生成CCE安全策略
该策略对容器映像、命令和环境进行加密测量:
# Generate from the Bicep template (includes SKR sidecar):
az confcom acipolicygen \
--template-file infra/main.bicep \
--print-policy > cce-policy.b64
# Compute the policy hash for the key-release policy:
HASH=$(cat cce-policy.b64 | base64 -d | sha256sum | cut -d' ' -f1)
echo "Policy hash: $HASH"3.更新密钥发布政策
编辑 infra/key-release-policy.json --更换 x-ms-sevsnpvm-hostdata 使用步骤2中的哈希值:
{
"claim": "x-ms-sevsnpvm-hostdata",
"equals": "
"
}4.部署基础设施
az deployment group create \
--resource-group \
--template-file infra/main.bicep \
--parameters \
acrName= \
imageTag=latest \
ccePolicy=$(cat cce-policy.b64)这将创建:密钥保险库高级版、托管身份、ACI容器组(MCP服务器+SKR侧车)。
5.创建RSA-HSS信封密钥
KV_NAME=$(az deployment group show -g -n main \
--query "properties.outputs.keyVaultName.value" -o tsv)
az keyvault key create \
--vault-name $KV_NAME \
--name mcp-envelope-key \
--kty RSA-HSM \
--size 4096 \
--exportable true \
--policy @infra/key-release-policy.json6.加密和提供机密
# Encrypt each secret with the envelope key's public key:
ENC_TOKEN=$(python scripts/encrypt_secret.py \
--vault-name $KV_NAME --secret "ghp_your_github_pat")
ENC_DB=$(python scripts/encrypt_secret.py \
--vault-name $KV_NAME --secret "postgresql://user:pass@host/db")
ENC_HOOK=$(python scripts/encrypt_secret.py \
--vault-name $KV_NAME --secret "https://hooks.slack.com/xxx")
# Redeploy with encrypted secrets:
az deployment group create \
--resource-group \
--template-file infra/main.bicep \
--parameters \
acrName= \
imageTag=latest \
ccePolicy=$(cat cce-policy.b64) \
encGithubToken=$ENC_TOKEN \
encDbConnectionString=$ENC_DB \
encWebhookUrl=$ENC_HOOK7.验证
# Check container logs:
az container logs -g -n mcp-tee-server
# Should show: "Envelope key released via SKR — decrypting secrets"
# Should show: "Decrypted GITHUB_TOKEN via envelope encryption"
# Check SKR sidecar:
az container logs -g -n mcp-tee-server -c skr-sidecar
# Test MCP endpoint:
python src/agent.py http://:8080/mcp本地开发
对于没有TEE的本地测试,设置普通环境变量(当SKR不可用时,服务器会回退到它们):
export GITHUB_TOKEN=ghp_xxxx
export DB_CONNECTION_STRING=postgresql://user:pass@host:5432/db
export WEBHOOK_URL=https://hooks.slack.com/services/xxx
cd src && python server.py这 attestation_status 工具将报告 running_in_tee: false 和 secrets_source: env.
远程验证证明
# Start the server locally:
cd src && python server.py
# In another terminal, run the agent:
python src/agent.py http://localhost:8080/mcp
# Against a deployed ACI container:
python src/agent.py http://:8080/mcp安全模型
| 层 | 控制 | 它保护什么 |
|---|---|---|
| 硬件 | AMD SEV-SNP内存加密 | 特权主机访问、物理内存转储 |
| 认证 | Azure MAA+CCE策略哈希 | 供应链攻击、图像篡改 |
| 密钥管理 | KV Premium RSA-HSM+发布政策 | 未经授权的密钥导出,流氓容器 |
| 信封加密 | RSA-OAEP加密的环境变量 | 传输中的秘密,配置暴露 |
| 应用程序 | 只读SQL,输入验证 | 提示注入,SQL注入 |
| MCP能力模型 | 默认拒绝、确认门 | 未经授权的写入操作 |
能力模型
此服务器实现 MCP能力模型:
- 默认拒绝:数据库工具只接受SELECT查询
- 读/写分离:
github_search_issues和query_database是只读的;send_notification是写入操作 - 确认门:
send_notification在代理工作流中应始终要求明确的用户确认 - 审计跟踪:所有工具调用都会记录参数(机密已编辑)
- 认证状态:The
attestation_status该工具提供运行时TEE和秘密验证
常见问题解答
Q: 为什么选择RSA-HSM而不是oct HSM(对称密钥)? A: Azure密钥保险库高级版仅支持用于安全密钥发布的非对称密钥(RSA-HSS、EC-HSS)。对称的 oct-HSM 密钥需要Azure托管HSM,这要贵得多。采用RSA-HSS的信封加密模式实现了相同的目标。
Q: 如果容器图像发生变化,会发生什么? A: CCE策略哈希值发生变化,导致密钥发布策略匹配中断。密钥库拒绝释放私钥。在重新部署之前,您必须重新生成CCE策略并更新密钥发布策略。
Q: 我可以旋转信封钥匙吗? A: 是的。使用相同的发布策略创建新的RSA-HSS密钥,使用新的公钥重新加密您的秘密,并使用新的密文和密钥名称重新部署容器。
Q: 如果我没有在本地安装Docker怎么办? A: 使用 az acr build 在云中构建: az acr build --registry --image mcp-tee-server:latest .
