Pourquoi l'autorisation standard MCP ne passe pas à l'échelle enterprise
Dans un scénario OAuth classique, chaque client MCP soumet l'utilisateur au flux d'autorisation propre à chaque serveur MCP : découverte, redirection, consentement, token. Ce modèle est parfaitement adapté aux applications grand public où l'utilisateur choisit explicitement quelles données partager avec quelle application.
Dans un contexte enterprise, ce même mécanisme génère une dette d'autorisation proportionnelle au nombre de serveurs MCP déployés :
- Chaque collaborateur doit autoriser individuellement chaque serveur MCP approuvé par l'organisation.
- Les popups de sélection de compte et de consentement créent une expérience incohérente, propice aux erreurs.
- Les équipes sécurité ne disposent d'aucun plan de contrôle unifié pour auditer ou révoquer les accès.
- Le départ d'un collaborateur nécessite des actions sur de multiples relations d'autorisation distinctes.
- Les identités professionnelles et personnelles peuvent se mélanger précisément là où c'est le plus risqué : dans l'outil qui agit pour le compte de l'utilisateur.
Enterprise-Managed Authorization (EMA) est l'extension MCP stable qui répond à ces problèmes en faisant de l'IdP de l'entreprise le point de décision de politique d'accès.
Référence de spécification
L'extension EMA est publiée en version stable sur le site officiel du protocole MCP : Enterprise-Managed Authorization. La spécification complète est disponible sur GitHub.
Ce que le protocole EMA change au niveau du wire
L'utilisateur s'authentifie toujours auprès de l'IdP de l'entreprise via le MCP host. La différence intervient au moment où le client doit obtenir un token d'accès pour un serveur MCP spécifique.

Le flux EMA se déroule en cinq étapes précises :
- Le client MCP échange l'assertion d'identité de l'utilisateur auprès de l'IdP enterprise contre un ID-JAG (Identity Assertion JWT Authorization Grant), en utilisant la sémantique OAuth token exchange définie par RFC 8693.
- L'IdP évalue la politique enterprise pour le client, la ressource MCP, l'utilisateur et les scopes demandés.
- Si la politique autorise l'accès, l'IdP émet un ID-JAG à courte durée de vie, lié à une audience spécifique.
- Le client présente ce JWT au serveur d'autorisation MCP via le grant JWT bearer défini par RFC 7523.
- Le serveur d'autorisation valide l'assertion et retourne le token d'accès à la ressource que le client utilise pour ses appels MCP.
L'utilisateur ne traverse jamais un second flux navigateur auprès du serveur MCP. La décision a déjà été prise par l'IdP enterprise, ce qui confère trois propriétés structurelles :
- Autorisation unique, propagation automatique. Les administrateurs activent les serveurs approuvés ; les utilisateurs reçoivent les accès en fonction de leurs groupes et rôles existants.
- Politique et révocation centralisées. L'accès conditionnel, l'état d'emploi, les exigences sur le device restent dans l'IdP.
- Frontière d'identité nette. La connexion enterprise est la seule source d'autorité, sans sélecteur de compte à chaque serveur MCP.
Ce qu'Entra ID et App Service fournissent dès aujourd'hui
Azure App Service constitue déjà une base solide pour un serveur MCP resource enterprise. La fonctionnalité App Service Authentication s'intercale devant l'application et valide les tokens d'accès Microsoft Entra avant même que la requête n'atteigne le processus applicatif.
Fonctionnalité en préversion
L'intégration MCP de App Service Authentication et la publication de protected resource metadata sont actuellement en préversion. Ne les utilisez pas dans un environnement de production sans valider la feuille de route de disponibilité générale.
Dans le modèle Entra + App Service, la plateforme assure automatiquement :
- La publication des OAuth protected resource metadata pour la découverte MCP.
- L'exigence d'authentification sur
/mcpavec retour401pour toute requête non authentifiée. - La validation de la signature, de l'issuer, de l'audience et de la durée de vie du token.
- La restriction aux
client_idapplicatifs configurés. - L'injection du principal validé dans des en-têtes de requête contrôlés par la plateforme.
- L'exposition publique des seuls endpoints
/et/health. - L'envoi de données OpenTelemetry vers Application Insights via une managed identity.
L'application Entra expose le scope user_impersonation et préautorise Visual Studio Code et Azure CLI. Les administrateurs de tenant peuvent appliquer l'accès conditionnel à l'application enterprise et consulter les journaux de connexion Entra.
OAuth gouverné ≠ protocole EMA
Ce chemin fournit un OAuth centralement gouverné. Il supprime les prompts de consentement pour les clients connus et place la validation des tokens en périphérie de plateforme. Il n'implémente pas le protocole EMA natif, car Entra n'émet pas d'ID-JAG via RFC 8693 dans ce chemin, et il n'y a pas d'échange RFC 7523 auprès d'un serveur d'autorisation MCP séparé.
Comparaison des deux chemins d'autorisation
| Capacité | Entra + App Service | EMA avec ID-JAG |
|---|---|---|
| Politique centralisée au niveau tenant | Oui | Oui |
| Protected resource metadata | Oui | Oui |
| Préautorisation des clients connus | Oui, via préautorisation Entra | Souvent requis aussi côté IdP et serveur d'autorisation |
| Flux navigateur par serveur | Évité pour les clients préautorisés | Évité par conception du protocole |
| IdP enterprise émet un ID-JAG | Non | Oui |
| Serveur d'autorisation MCP échange l'ID-JAG | Non | Oui |
| Disponibilité dans le sample | App Azure déployable | Lab d'interopérabilité local |
Cette distinction est fondamentale : « aucun prompt de consentement » décrit une expérience utilisateur, pas une preuve de conformité protocolaire.
Peut-on implémenter EMA complet sur App Service ?
Oui. App Service ne vous empêche pas de déployer le flux EMA complet. Si votre IdP enterprise sait émettre des ID-JAG, vous pouvez implémenter le serveur d'autorisation de ressources et la validation du token MCP dans le code applicatif, ou pointer le serveur MCP vers un service d'autorisation séparé. App Service reste alors la plateforme de calcul plutôt que la frontière d'autorisation.
Cette approche remplace la validation de tokens managée par Easy Auth par des responsabilités applicatives : émission de tokens, gestion des clés de signature, validation des ID-JAG, protection contre le replay, enforcement des scopes, et audit logging.
Déployer le serveur MCP gouverné par Entra
Prérequis
- Azure CLI >= 2.60 installé et connecté (
az login). - Azure Developer CLI (azd) >= 1.9 installé.
- Rôle Owner ou Contributor + User Access Administrator sur l'abonnement cible.
- Rôle Application Administrator ou Cloud Application Administrator dans Entra ID pour la création d'applications.
- Module Python >= 3.12 pour le développement local.
Le repository de référence est seligj95/app-service-ema-mcp.
Cloner le repository et préparer l'environnement
1git clone https://github.com/seligj95/app-service-ema-mcp2cd app-service-ema-mcp3python3 -m venv .venv4source .venv/bin/activate5python -m pip install -e ".[dev]"Configurer les variables d'environnement azd
1azd auth login2azd env new ema-mcp3azd env set AZURE_SUBSCRIPTION_ID <subscription-id>4azd env set AZURE_LOCATION eastusRemplacez <subscription-id> par l'identifiant de votre abonnement Azure (az account show --query id -o tsv).
Bootstrapper l'application Entra
Le script de configuration Entra doit impérativement être exécuté avant azd up. En effet, azd résout les paramètres Bicep requis avant le hook de pré-provisionnement.
1./scripts/configure-entra-app.shCe script est idempotent : il peut être réexécuté sans danger à chaque provisionnement.
Déployer l'infrastructure et l'application
1azd upLe déploiement installe : un App Service Plan Linux Basic B1, Python 3.14, App Service Authentication, protected resource metadata, Log Analytics, Application Insights et la télémétrie via managed identity.
Vérifier la frontière d'autorisation
1./scripts/verify-deployment.shCe script vérifie séquentiellement que :
- Les protected resource metadata sont accessibles anonymement.
- Une requête MCP anonyme est bien rejetée en
401. - Azure CLI obtient un token d'API délégué valide.
- La même requête MCP réussit avec ce token.
Résultat attendu de la vérification
En invoquant l'outil whoami contre l'application déployée avec le token Azure CLI, App Service retourne :
1{2 "authentication_type": "aad",3 "client_id": "04b07795-8ddb-461a-bbee-02f9e1bf7b46",4 "scopes": ["user_impersonation"]5}Le résultat complet inclut également name, subject, tenant_id et roles. La trace de télémétrie correspondante arrive dans Application Insights via la managed identity de App Service, sans authentification locale de télémétrie.
Exécuter le flux EMA localement
Le lab local fait tourner quatre composants dans un même processus : un IdP enterprise simulé, un serveur d'autorisation MCP, un serveur de ressources MCP, et un client MCP utilisant les API d'assertion d'identité du SDK Python officiel.
Composants non destinés à la production
L'IdP simulé et le store de tokens en mémoire sont délibérément des composants de laboratoire. Ils rendent le protocole visible et testable sans prétendre qu'Entra expose aujourd'hui le flux d'émission exact utilisé par le lab.
1python -m examples.ema_lab.clientLe résultat final est le contexte d'identité et d'autorisation retourné par le serveur MCP :
1{'subject': 'alice@example.com', 'client_id': 'finance-agent',2 'scopes': ['mcp:whoami'], 'resource': 'http://localhost/mcp'}Pour exécuter la suite de tests, qui couvre à la fois les échanges réussis et les cas de rejet :
1python -m ruff check .2python -m pytestLe lab valide la signature de l'ID-JAG, les claims typ, issuer, audience, client_id, ressource, scopes, expiration et l'usage unique via jti. Il teste également les rejets : mauvais issuer, mauvaise audience, mauvaise ressource, escalade de scope, expiration, et replay.
Dépendance SDK non encore publiée
Au moment de la rédaction, le package PyPI mcp version 1.28.1 ne contient pas encore les API d'assertion d'identité utilisées par l'extension stable. Le sample pointe sur un commit exact du SDK Python officiel. Remplacez ce pin dès que les API sont disponibles dans une release publiée.
Trois pièges d'intégration à connaître avant la production
1. Autoriser l'audience qu'Entra émet réellement
Le client demande api://<client-id>/user_impersonation, mais un token délégué v2 peut transporter le client_id applicatif nu dans le claim aud. Le sample autorise à la fois la forme nue et la forme api://, tout en rejetant les tokens pour toute autre ressource. Vérifiez ce comportement dans votre propre code de validation.
2. Conserver la protection anti-DNS-rebinding du SDK
Le SDK Python MCP utilise localhost par défaut quand le serveur ne déclare pas son nom d'hôte de déploiement. C'est un défaut sûr en local, mais une requête déployée échoue correctement avec 421 Invalid Host header. Le sample lit WEBSITE_HOSTNAME et autorise uniquement ce nom d'hôte App Service exact ainsi que sa forme avec port. Ne désactivez jamais cette protection.
3. Gérer le mapping de claims App Service
App Service remaps certains noms de claims JWT avant de construire X-MS-CLIENT-PRINCIPAL. Par exemple, la valeur scp déléguée peut arriver sous l'URI de claim de scope mappé. L'application doit accepter les deux représentations, tout en ne faisant confiance qu'à l'en-tête principal injecté par App Service. Un en-tête d'identité fourni par l'appelant ne constitue jamais une preuve d'authentification, car la plateforme supprime et remplace ces en-têtes en périphérie.
Checklist de mise en production
Ce sample délimite la frontière d'autorisation, pas tous les contrôles de production
Les éléments suivants sont de votre responsabilité avant d'exposer un serveur MCP en production.
- Appliquer l'accès conditionnel Entra de manière délibérée, en commençant en mode report-only.
- Ajouter des vérifications de scope ou de rôle au niveau de chaque outil MCP lorsque des outils ont des sensibilités différentes.
- Utiliser une managed identity ou un flux on-behalf-of explicite pour les API en aval ; ne jamais transférer le token de ressource MCP.
- Ajouter un réseau privé ou une API gateway si la charge de travail exige l'isolation réseau.
- Maintenir les tokens d'accès et les ID-JAG à courte durée de vie.
- Valider les signatures des ID-JAG avec le JWKS publié par l'IdP enterprise, découvert depuis ses métadonnées de serveur d'autorisation. La clé HMAC partagée du lab n'existe que pour l'autonomie du flux local.
- Appliquer la protection contre le replay des ID-JAG via
jtiau niveau du serveur d'autorisation. - Journaliser les décisions d'autorisation sans journaliser les bearer tokens ni le contenu des assertions.
- Remplacer le pin Git du SDK dès que les API d'assertion d'identité sont disponibles dans une release testée.
Ressources de référence
- Spécification EMA stable (GitHub)
- Annonce Enterprise-Managed Authorization
- Guide identity assertion — SDK Python MCP
- Configurer l'autorisation MCP sur App Service (Microsoft Learn)
- Sécuriser les appels MCP depuis Visual Studio Code (Microsoft Learn)
- RFC 8693 — OAuth 2.0 Token Exchange
- RFC 7523 — JWT Bearer Grant
- Repository du sample de référence



