Partager via


Sécuriser les serveurs MCP sur Azure Container Apps

Cet article explique comment authentifier et sécuriser les serveurs MCP s’exécutant sur Azure Container Apps. L’approche diffère selon que vous hébergez une application conteneur autonome ou que vous utilisiez le serveur MCP géré par la plateforme dans les sessions dynamiques.

Prerequisites

Vue d’ensemble des modèles d’authentification

Azure Container Apps prend en charge deux modèles d’authentification pour les serveurs MCP. Le tableau suivant récapitule les principales différences.

Aspect Application conteneur autonome Sessions dynamiques MCP
Mécanisme d’authentification Authentification intégrée des Applications conteneur avec Microsoft Entra ID Clé API via l’en-tête x-ms-apikey
Type de jeton Jeton du porteur OAuth 2.0 Chaîne de clé API opaque
Fournisseur d’identité Microsoft Entra ID (système d'identification de Microsoft) Azure Resource Manager
Rotation de clé/jeton Géré par l’ID Microsoft Entra Régénérer via l’API Azure Resource Manager
Étendue d’autorisation Configurable par application Niveau du pool de sessions
Chiffrement du transport TLS (entrée Container Apps) TLS (point de terminaison de sessions Container Apps)

Application conteneur autonome avec l’authentification Microsoft Entra ID

Lorsque vous déployez votre propre serveur MCP en tant qu’application conteneur, vous possédez la couche d’authentification. Utilisez la fonctionnalité d’authentification intégrée Container Apps sauvegardée par l’ID Microsoft Entra.

Configurer une authentification intégrée

Les étapes suivantes inscrivent une application d’ID Microsoft Entra et activent l’authentification intégrée sur votre application conteneur.

  1. Inscrivez une application dans l’ID Microsoft Entra :

    APP_ID=$(az ad app create \
        --display-name "mcp-server-auth" \
        --sign-in-audience AzureADMyOrg \
        --query appId -o tsv)
    
  2. Créez un principal de service :

    az ad sp create --id $APP_ID
    
  3. Ajoutez une clé secrète client :

    CLIENT_SECRET=$(az ad app credential reset --id $APP_ID --query password -o tsv)
    TENANT_ID=$(az account show --query tenantId -o tsv)
    
  4. Activez l’authentification intégrée sur l’application conteneur :

    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
    
  5. Définissez l’action non authentifiée pour exiger la connexion :

    az containerapp auth update \
        --name <CONTAINER_APP_NAME> \
        --resource-group <RESOURCE_GROUP> \
        --unauthenticated-client-action Return401
    

Se connecter à partir d’un client MCP avec un jeton du porteur

Lorsque votre serveur MCP nécessite un jeton du porteur, configurez la récupération de jeton dans votre client MCP. L’exemple suivant montre une .vscode/mcp.json configuration pour GitHub Copilot :

{
    "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
        }
    ]
}

Conseil / Astuce

Pour le développement, obtenez un jeton à l'aide de az account get-access-token --resource $APP_ID --query accessToken -o tsv et collez-le lorsque vous êtes invité à le faire. Pour les flux de travail automatisés, intégrez-les au système de gestion des jetons de votre organisation.

Configuration de CORS

Les clients MCP qui se connectent à partir d’environnements web ont besoin d’en-têtes CORS. Utilisez la commande suivante pour configurer CORS sur votre application conteneur :

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

Les en-têtes suivants sont essentiels pour permettre :

  • Content-Type: requis pour les demandes de JSON-RPC
  • Authorization : obligatoire pour l’authentification par jeton porteur
  • Mcp-Session-Id : utilisé par les clients MCP pour les sessions avec état

Note

GitHub Copilot se connecte aux serveurs MCP distants à partir de l’application de bureau VS Code, et non à partir d’un navigateur. CORS est nécessaire uniquement si vous envisagez de prendre en charge les clients MCP basés sur un navigateur ou VS Code pour le web. Les didacticiels autonomes utilisent des origines CORS génériques pour simplifier ; pour la production, limitez les origines approuvées spécifiques, comme indiqué ici.

Recommandations de sécurité pour les serveurs MCP autonomes

Appliquez les meilleures pratiques suivantes pour renforcer votre serveur MCP autonome.

  • Restrictions réseau : utilisez des restrictions IP ou l’intégration de réseau virtuel pour limiter l’accès aux adresses IP clientes connues.
  • Limitation de débit : implémentez la limitation de débit dans votre code d’application ou frontez l’application avec Gestion des API Azure.
  • Validation d’entrée : validez tous les arguments d’outil dans votre code de serveur MCP. Les entrées de l’outil MCP sont json arbitraires. Traitez-les comme non fiables.
  • Conception sans état : Il est conseillé de privilégier les serveurs MCP sans état pour éviter les risques de détournement de session. Dans la plupart des kits SDK MCP, cela signifie désactiver la génération d’ID de session côté serveur (par exemple, sessionIdGenerator: undefined en TypeScript ou stateless_http=True en Python).
  • Sondes d’intégrité : configurez des sondes d’intégrité sur un point de terminaison distinct (par exemple /healthz), et non sur le point de terminaison MCP. Les points de terminaison MCP attendent des requêtes POST JSON-RPC et renvoient des erreurs pour les sondes GET simples.

Sessions dynamiques avec authentification par clé API

Important

Le serveur MCP géré par la plateforme pour les sessions dynamiques est en préversion. La version 2025-02-02-preview et les propriétés mcpServerSettings de l’API sont sujettes à modification.

Le serveur MCP géré par la plateforme dans les sessions dynamiques utilise l’authentification par clé API. La clé est limitée à la portée du pool de sessions et confère l’accès à tous les outils ainsi qu'aux sessions dans le pool.

Flux d’authentification par clé API

Les étapes suivantes décrivent le fonctionnement de l’authentification par clé API pour les sessions dynamiques.

  1. Le client envoie une requête JSON-RPC avec l’en-tête x-ms-apikey .
  2. Le proxy du pool de sessions valide la clé par rapport au plan de contrôle Azure.
  3. Si la clé est valide, la requête est transférée à la session. Si ce n’est pas le cas, une erreur d’authentification est retournée.

Récupérer la clé API

Utilisez la commande suivante pour récupérer la clé API de votre pool de sessions.

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)

Faire pivoter et mettre en cache la clé API

Vous pouvez régénérer la clé API à tout moment. La plateforme met en cache les résultats de validation pendant jusqu’à cinq minutes. Les clés valides précédemment peuvent continuer à fonctionner après la régénération jusqu’à l’expiration du cache.

Pour faire pivoter la clé API, appelez l’action regenerateCredentials sur le pool de sessions :

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

Après la régénération, récupérez la nouvelle clé en utilisant fetchMCPServerCredentials comme indiqué précédemment.

Recommandations de sécurité pour les sessions dynamiques

Appliquez les meilleures pratiques suivantes pour sécuriser votre déploiement MCP de sessions dynamiques.

  • Étendue de la clé API : la clé API accorde l’accès à l’ensemble du pool de sessions. Tout client avec la clé peut créer des environnements et exécuter du code. Ne partagez pas la clé avec des parties non approuvées.
  • Isolation de l’environnement : chaque session s’exécute dans un conteneur isolé Hyper-V. L’exécution du code dans une session ne peut pas accéder aux données d’une autre session.
  • Trafic sortant du réseau : contrôler si les sessions peuvent accéder à Internet à l’aide de sessionNetworkConfiguration.status. Défini sur la valeur EgressDisabled si les sessions n’ont pas besoin d’un accès réseau externe.
  • Durée de vie de la session : configurez coolDownPeriodInSeconds pour détruire automatiquement les sessions inactives. Ce paramètre limite la fenêtre d’exposition si une session est compromise.
  • Stockage secret : stockez la clé API dans Azure Key Vault ou les secrets des Container Apps plutôt que dans le code ou les fichiers de configuration.

Incompatibilités d’authentification courantes

Une erreur courante consiste à utiliser l’en-tête de la clé API (x-ms-apikey) avec une application conteneur autonome, ou en utilisant un jeton d'authentification avec le point de terminaison MCP pour les sessions. Le tableau suivant montre ce qui se passe lorsque vous les mélangez.

Mismatch Résultat
x-ms-apikey élément d'en-tête envoyé à une application autonome L’en-tête est ignoré ; demande atteint l’authentification intégrée et retourne 401 si l’authentification est activée
Authorization: Bearer envoyé aux sessions MCP Échec de validation de la clé et retour 401

Vérifiez que la configuration de votre client MCP correspond au modèle d’hébergement que vous avez déployé.