この記事では、Azure Container Appsで実行されている MCP サーバーを認証してセキュリティで保護する方法について説明します。 この方法は、 スタンドアロン コンテナー アプリ をホストするか、動的セッションで プラットフォームで管理される MCP サーバー を使用するかによって異なります。
[前提条件]
- アクティブなサブスクリプションを持つAzure アカウント。 無料で作成できます。
- Azure CLI バージョン 2.62.0 以降。
- 既存のコンテナー アプリまたはセッション プール。 お持ちでない場合は、 MCP サーバーのチュートリアルを参照してください。
認証モデルの概要
Azure Container Appsでは、MCP サーバー用の 2 つの認証モデルがサポートされています。 次の表は、主な相違点をまとめたものです。
| アスペクト | スタンドアロン コンテナー アプリ | 動的セッション MCP |
|---|---|---|
| 認証メカニズム | Microsoft Entra IDを使用した Container Apps の組み込み認証 |
x-ms-apikey ヘッダー経由の API キー |
| トークンの種類 | OAuth 2.0 ベアラー トークン | 不透明な API キー文字列 |
| ID プロバイダー | Microsoft Entra ID | Azure Resource Manager |
| キー/トークンのローテーション | Microsoft Entra IDによって管理される | Azure Resource Manager API を使用して再生成する |
| 認可スコープ | アプリケーションごとに構成可能 | セッション プール レベル |
| 転送の暗号化 | TLS (コンテナアプリの入口) | TLS (コンテナー アプリ セッション エンドポイント) |
Microsoft Entra ID認証を使用したスタンドアロン コンテナー アプリ
独自の MCP サーバーをコンテナー アプリとしてデプロイする場合は、認証レイヤーを所有します。 container Apps Microsoft Entra IDによってサポートされる組み込み認証機能を使用します。
組み込み認証を構成する
次の手順では、Microsoft Entra ID アプリケーションを登録し、コンテナー アプリで組み込み認証を有効にします。
Microsoft Entra IDにアプリケーションを登録します。
APP_ID=$(az ad app create \ --display-name "mcp-server-auth" \ --sign-in-audience AzureADMyOrg \ --query appId -o tsv)サービス プリンシパルを作成します。
az ad sp create --id $APP_IDアプリケーション ID URI を設定し、API スコープを公開します。 これらの設定は、クライアントが MCP サーバーのアクセス トークンを要求できるようにするために必要です。
az ad app update --id $APP_ID --identifier-uris "api://$APP_ID" OBJECT_ID=$(az ad app show --id $APP_ID --query id -o tsv) SCOPE_ID=$(uuidgen) az rest --method PATCH \ --uri "https://graph.microsoft.com/v1.0/applications/$OBJECT_ID" \ --headers "Content-Type=application/json" \ --body "{ \"api\": { \"oauth2PermissionScopes\": [{ \"id\": \"$SCOPE_ID\", \"adminConsentDescription\": \"Access the MCP server\", \"adminConsentDisplayName\": \"Access MCP Server\", \"isEnabled\": true, \"type\": \"User\", \"userConsentDescription\": \"Access the MCP server\", \"userConsentDisplayName\": \"Access MCP Server\", \"value\": \"access_as_user\" }] } }"クライアント シークレットを追加します。
CLIENT_SECRET=$(az ad app credential reset --id $APP_ID --query password -o tsv) TENANT_ID=$(az account show --query tenantId -o tsv)コンテナー アプリで組み込みの認証を有効にします。
az containerapp auth microsoft update \ --name <CONTAINER_APP_NAME> \ --resource-group <RESOURCE_GROUP> \ --client-id $APP_ID \ --client-secret $CLIENT_SECRET \ --tenant-id $TENANT_ID \ --issuer "https://login.microsoftonline.com/$TENANT_ID/v2.0" \ --yes認証されていないアクションをログインを要求するように設定します。
az containerapp auth update \ --name <CONTAINER_APP_NAME> \ --resource-group <RESOURCE_GROUP> \ --unauthenticated-client-action Return401
ベアラー トークンを使用して MCP クライアントから接続する
MCP サーバーでベアラー トークンが必要な場合は、MCP クライアントでトークンの取得を構成します。 次の例は、GitHub Copilotの .vscode/mcp.json 構成を示しています。
{
"servers": {
"my-mcp-server": {
"type": "http",
"url": "https://<CONTAINER_APP_NAME>.<REGION>.azurecontainerapps.io/mcp",
"headers": {
"Authorization": "Bearer ${input:mcpBearerToken}"
}
}
},
"inputs": [
{
"id": "mcpBearerToken",
"type": "promptString",
"description": "Enter your bearer token for the MCP server",
"password": true
}
]
}
ヒント
開発の場合は、 az account get-access-token --resource api://$APP_ID --query accessToken -o tsv を使用してトークンを取得し、メッセージが表示されたら貼り付けます。 自動化されたワークフローの場合は、組織のトークン管理システムと統合します。
CORS の構成
Web ベースの環境から接続する MCP クライアントには CORS ヘッダーが必要です。 コンテナー アプリで CORS を構成するには、次のコマンドを使用します。
az containerapp ingress cors update \
--name <CONTAINER_APP_NAME> \
--resource-group <RESOURCE_GROUP> \
--allowed-origins "https://vscode.dev" "https://github.dev" \
--allowed-methods "GET" "POST" "OPTIONS" \
--allowed-headers "Content-Type" "Authorization" "Mcp-Session-Id" \
--max-age 3600
次のヘッダーは、許可するために重要です。
-
Content-Type: JSON-RPC 要求に必要です -
Authorization: ベアラー トークン認証に必要 -
Mcp-Session-Id: ステートフル セッションに MCP クライアントによって使用されます
注
GitHub Copilotは、ブラウザーからではなく、VS Code デスクトップ アプリからリモート MCP サーバーに接続します。 CORS は、ブラウザー ベースの MCP クライアントまたは WEB 用の VS Code をサポートする場合にのみ必要です。 スタンドアロンのチュートリアルでは、わかりやすくするためにワイルドカード CORS のオリジンを使用します。運用環境の場合は、次に示すように、特定の信頼できる配信元に制限します。
スタンドアロン MCP サーバーのセキュリティに関する推奨事項
スタンドアロン MCP サーバーを強化するには、次のベスト プラクティスを適用します。
- ネットワーク制限: IP 制限 または 仮想ネットワーク統合 を使用して、既知のクライアント IP へのアクセスを制限します。
- Rate limiting: アプリケーション コードにレート制限を実装するか、Azure API Managementを使用してアプリを前面に表示します。
- 入力検証: MCP サーバー コード内のすべてのツール引数を検証します。 MCP ツールの入力は任意の JSON です。 信頼されていないものとして扱います。
-
ステートレス設計: セッションハイジャックのリスクを回避するためにステートレス MCP サーバーを使用します。 ほとんどの MCP SDK では、これはサーバー側のセッション ID の生成を無効にすることを意味します (TypeScript では
sessionIdGenerator: undefined、Python ではstateless_http=Trueなど)。 -
正常性プローブ: MCP エンドポイントではなく、別のエンドポイント (
/healthzなど) で正常性プローブを構成します。 MCP エンドポイントは、JSON-RPC POST 要求を想定し、プレーンな GET プローブのエラーを返します。
API キー認証を使用した動的セッション
Important
動的セッション用のプラットフォームで管理される MCP サーバーは プレビュー段階です。 API バージョンの 2025-02-02-preview プロパティと mcpServerSettings プロパティは変更される可能性があります。
動的セッションのプラットフォームで管理される MCP サーバーでは、API キー認証が使用されます。 キーのスコープはセッション プールであり、プール内のすべてのツールとセッションへのアクセスを許可します。
API キー認証フロー
次の手順では、動的セッションに対する API キー認証のしくみについて説明します。
- クライアントは、
x-ms-apikeyヘッダーを使用して JSON-RPC 要求を送信します。 - セッション プール プロキシは、Azure コントロール プレーンに対してキーを検証します。
- キーが有効な場合、要求はセッションに転送されます。 そうでない場合は、認証エラーが返されます。
API キーを取得する
次のコマンドを使用して、セッション プールの API キーをフェッチします。
API_KEY=$(az rest --method POST \
--uri "https://management.azure.com/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.App/sessionPools/<SESSION_POOL_NAME>/fetchMCPServerCredentials" \
--uri-parameters api-version=2025-02-02-preview \
--query "apiKey" -o tsv)
API キーをローテーションしてキャッシュする
API キーはいつでも再生成できます。 プラットフォームは検証結果を最大 5 分間キャッシュするため、キャッシュの有効期限が切れるまで、以前の有効なキーは再生成後も引き続き機能する可能性があります。
API キーをローテーションするには、セッション プールで regenerateCredentials アクションを呼び出します。
az rest --method POST \
--uri "https://management.azure.com/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.App/sessionPools/<SESSION_POOL_NAME>/regenerateCredentials" \
--uri-parameters api-version=2025-02-02-preview
再生成後、前に示したように、 fetchMCPServerCredentials を使用して新しいキーを取得します。
動的セッションのセキュリティに関する推奨事項
動的セッションの MCP デプロイをセキュリティで保護するには、次のベスト プラクティスを適用します。
- API キー スコープ: API キーは、セッション プール全体へのアクセスを許可します。 キーを持つ任意のクライアントは、環境を作成し、コードを実行できます。 信頼されていないパーティとキーを共有しないでください。
- Environment isolation: 各セッションは、Hyper-V分離されたコンテナーで実行されます。 あるセッションでのコード実行は、別のセッションのデータにアクセスできません。
-
ネットワーク エグレス: セッションが
sessionNetworkConfiguration.statusを使用してインターネットにアクセスできるかどうかを制御します。 セッションに外部ネットワーク アクセスが必要ない場合は、EgressDisabledに設定します。 -
セッションの有効期間: アイドル状態のセッションを自動的に破棄するように
coolDownPeriodInSecondsを構成します。 この設定により、セッションが侵害された場合の公開期間が制限されます。 - Secret storage: コードまたは構成ファイルではなく、Azure Key Vault または Container Apps シークレットに API キーを格納します。
一般的な認証の不一致
一般的な間違いは、スタンドアロン コンテナー アプリで API キー ヘッダー (x-ms-apikey) を使用するか、セッション MCP エンドポイントでベアラー トークンを使用することです。 次の表は、それらを混在させるとどうなるかを示しています。
| ミスマッチ | 結果 |
|---|---|
x-ms-apikey ヘッダーがスタンドアロンアプリに送信される |
ヘッダーは無視されます。要求が組み込みの認証にヒットし、認証が有効になっている場合は 401 が返されます |
Authorization: Bearer がセッション MCP に送信される |
キーの検証が失敗し、返される 401 |
| 公開された API スコープなしで要求されたベアラー トークン | トークンの取得が失敗するか、トークンに有効な対象ユーザーが存在しないため、 401 |
MCP クライアント構成が、デプロイしたホスティング モデルと一致していることを確認します。
関連するコンテンツ
- Azure Container Apps 上の MCP サーバーの概要
Azure Container Apps - Microsoft Entra ID 認証
- 動的セッションの概要
- Container Apps でシークレットを管理する
- Container Apps の CORS を構成する
- Container Apps での MCP サーバーのトラブルシューティング