Inside the Harness : le binding de l’issuer OAuth dans MCP, et pourquoi la sécurité des protocoles tient à une comparaison de chaînes
La spécification MCP 2026-07-28 livre six SEPs pour durcir OAuth, et les plus importantes tournent autour d’une question banale : de quel serveur cette réponse vient-elle réellement ? Le modèle d’attaque mix-up, les erreurs d’issuer déjà observées qui cassent des clients MCP, et ce que les implémenteurs doivent changer.
Sur cette page
- Ce qui s’est passé
- Le modèle de vulnérabilité : un client, de nombreux issuers
- La spécification rattrape les pannes de production
- Ce que les implémenteurs doivent faire
- Ce que la spécification ne répond toujours pas
- FAQ
- Quel est le problème d’issuer binding OAuth dans MCP ?
- Est-ce une vulnérabilité de MCP lui-même ?
- Quels flows sont concernés ?
- Quand cela devient-il obligatoire ?
- En bref
- Sources
Trois chiffres, puis je les explique. Un : le champ issuer dans un document de métadonnées OAuth est une simple chaîne. Deux : cet été, Atlassian, Context7 et Home Assistant ont chacun servi des métadonnées d’autorisation MCP où cette chaîne ne correspondait pas à l’URL depuis laquelle le document avait été récupéré, et des clients stricts ont refusé de se connecter. Trois : le correctif désormais intégré dans la spécification MCP se résume à "comparer la chaîne, rejeter si elle diffère". C’est tout le mécanisme, et l’attaque qu’il ferme est l’une des plus désagréables d’OAuth : l’attaque mix-up, structurellement aggravée par la manière dont MCP est déployé.
C’est un article Inside the Harness, donc on descend dans la plomberie : quel est le problème d’issuer binding, quels flows sont touchés et qu’exige le package de spécification 2026-07-28 de quiconque construit un client ou serveur MCP ? Les changements de transport stateless de la même version ont pris les gros titres ; le durcissement auth a reçu six SEPs et presque aucune couverture. C’est l’inverse de ce qui devrait se passer, parce que si vous exploitez des serveurs MCP détenant de vraies credentials, c’est cette partie qui décide si un client confus remet un token à la mauvaise partie.
Points clés - MCP inverse la forme classique d’OAuth : un client parle à de nombreux authorization servers, découverts au runtime. Cette inversion est exactement la topologie visée par les mix-up attacks. - Le package de spécification 2026-07-28 contient six SEPs. Les deux plus importantes : SEP-2468, qui valide le paramètreissdes authorization responses selon RFC 9207, et SEP-2352, qui lie chaque client credential enregistré à l’issuer qui l’a émis. - Ce n’est pas théorique. Les endpoints MCP d’Atlassian et Context7 ont servi cet été des métadonnées avec issuer mismatch, cassant des clients stricts ; la spécification rattrape des erreurs déjà en production. - La validation deissest recommandée aujourd’hui et se dirige vers l’obligation. Implémentez-la maintenant et traitez l’absence deissd’un serveur censé le supporter comme un rejet, pas comme un détail. - Même entièrement adopté, ce package ne durcit que l’authentification client-serveur. Agent identity, authorization par request, provenance de délégation et audit restent hors du protocole, donc à votre charge.
Ce qui s’est passé
Le 21 mai 2026, les maintainers MCP ont verrouillé le release candidate de la spécification 2026-07-28, la version finale est sortie le 28 juillet et les maintainers SDK sont depuis dans une fenêtre de validation de dix semaines. La plupart des commentaires se sont concentrés sur le passage stateless. En dessous, selon l’analyse détaillée de Tigera, se trouve un package de six Spec Enhancement Proposals durcissant la couche OAuth :
|
SEP |
Ce qu’elle exige |
L’échec qu’elle évite |
|---|---|---|
|
2468 |
Valider |
Mix-up attacks entre plusieurs authorization servers |
|
2352 |
Lier les credentials enregistrées à leur issuer ; réenregistrer après migration |
Credential replay contre le mauvais authorization server |
|
837 |
Déclarer |
Clients desktop et CLI rejetés à cause de redirect URIs localhost |
|
2207 |
Flow refresh-token documenté pour serveurs de type OIDC |
Renouvellement de token divergent et improvisé |
|
2350 |
Accumulation de scopes définie dans les step-up flows |
Ambiguïté sur les scopes déjà accordés |
|
2351 |
Suffixe |
Échecs d’interop de metadata discovery |
Les trois SEPs de housekeeping, 2207, 2350 et 2351, sont des clarifications, et les clarifications dans les spécifications auth comptent : deux SDKs en désaccord sur l’emplacement d’un document de métadonnées provoquent une panne d’interop, pas une note de bas de page. Mais le duo porteur est 2468 et 2352, tous deux autour de la même question : comment un client sait-il à quel serveur il parle réellement ?
Le package de spécification MCP 2026-07-28 contient six SEPs de durcissement OAuth : validation de l’issuer (2468), credentials liées à l’issuer (2352), déclaration du type de client lors de Dynamic Client Registration (837), plus refresh tokens documentés (2207), accumulation des scopes (2350) et comportement de discovery (2351), selon l’analyse de Tigera. Le release candidate a été verrouillé le 21 mai et la spécification finale est sortie le 28 juillet 2026.
Le modèle de vulnérabilité : un client, de nombreux issuers
OAuth classique suppose de nombreux clients et un authorization server : des milliers d’apps, un identity provider, un token issuer. Les mix-up attacks, où l’on trompe un client pour qu’il attribue une authorization response au mauvais serveur, étaient un sujet de niche parce que la plupart des clients ne parlaient qu’à un seul issuer.
MCP renverse complètement la situation. Un client, l’application host, parle à de nombreux serveurs MCP, chacun potentiellement derrière un authorization server différent, découvert au runtime et souvent enregistré à la volée par Dynamic Client Registration. Les auteurs de la spécification le disent directement : le SEP d’issuer validation vise "a class of mix-up attack that is more prevalent in MCP's single-client, many-server deployment pattern", comme le cite l’article de Tigera. Quand votre client maintient des registrations auprès d’une douzaine d’authorization servers en même temps, un attaquant n’a pas besoin de casser la cryptographie. Il lui suffit de faire attribuer au client une réponse au mauvais serveur.
Voici la forme de l’attaque. Le host de votre agent est au milieu d’un flow avec le serveur honnête A quand arrive une réponse qui vient en réalité du serveur B contrôlé par l’attaquant. Sans vérification de l’issuer, le client peut terminer l’exchange contre B, faire fuiter l’authorization code, ou accepter des tokens émis par B et les présenter ensuite. RFC 9207, le correctif de 2021 pour OAuth classique, a ajouté un paramètre explicite iss aux authorization responses afin que le client puisse rejeter toute réponse venant d’un issuer inattendu, et SEP-2468 importe cette exigence dans MCP. SEP-2352 gère l’autre moitié, plus silencieuse : les credentials. Avant, un client pouvait détenir un client ID émis par issuer A et, lorsqu’une resource migrait vers issuer B, présenter la credential de A à B. Parfois cela fonctionnait, et "parfois cela fonctionne" n’est pas une propriété souhaitable dans un système auth. SEP-2352 exige donc que les registrations soient conservées par authorization server, liées à la valeur issuer, et recréées lors d’une migration.
Ce n’est pas non plus la première passe sur cette classe. La révision de spécification 2025-06-18 a rendu obligatoires les Resource Indicators de RFC 8707 pour que les tokens soient émis pour un serveur précis, et la spécification d’autorisation MCP interdit déjà d’accepter des tokens destinés à d’autres resources ou de les transmettre downstream. Le package 2026-07-28 poursuit la même trajectoire : moins de confiance par défaut, plus de binding explicite. Si vous avez lu mon article MCP versus API, c’est le coût de la flexibilité décrite là-bas : runtime discovery rend MCP composable, et fabrique aussi ces questions d’identité.
La topologie un-client-plusieurs-serveurs de MCP est exactement le deployment pattern ciblé par les mix-up attacks : l’attaquant ne casse pas la crypto, il amène le client à attribuer une response ou une credential au mauvais authorization server. SEP-2468 lie les responses aux issuers via le paramètre iss de RFC 9207 ; SEP-2352 lie les credentials enregistrées à leur serveur émetteur, selon l’analyse de Tigera et RFC 9207.La spécification rattrape les pannes de production
Si tout cela semble abstrait, ce ne l’est pas. La chaîne issuer échoue déjà dans de vrais déploiements MCP cet été, et des clients stricts s’y cassent les dents.
En juillet, des utilisateurs du client opencode ont découvert que OAuth vers le serveur MCP Rovo d’Atlassian échouait au discovery. Les protected-resource metadata annonçaient correctement un authorization server spécifique au tenant, mais le document servi à cet endroit déclarait l’issuer partagé nu https://auth.atlassian.com au lieu du chemin tenant depuis lequel il avait été récupéré. RFC 8414 section 3.3 dit que la valeur issuer doit exactement égaler l’URL utilisée pour récupérer les métadonnées, moins le suffixe .well-known. La validation stricte d’opencode a donc correctement rejeté la réponse et bloqué complètement le login : un bug de conformité côté Atlassian, confirmé sur les endpoints live. L’endpoint MCP de Context7 a rencontré un bug voisin en juin, où l’authorization server annoncé et le metadata issuer sur un sous-domaine Clerk divergeaient, et le SDK Go officiel MCP a refusé le flow. Les métadonnées Home Assistant omettaient entièrement le champ issuer, cassant les clients MCP d’une autre manière.
Aucun de ces trois cas n’était un exploit mix-up ; c’étaient des échecs d’interopérabilité. Mais c’est précisément le point. La même comparaison de chaîne qui bloque le faux serveur d’un attaquant bloque aussi un vrai serveur mal configuré, donc l’écosystème va devenir bien moins tolérant envers des métadonnées qui ont toujours été fausses et passaient auparavant. Le billet de WorkOS sur les mix-up attacks résume bien le problème opérationnel : de nombreuses librairies OAuth laissent encore la vérification RFC 9207 désactivée par défaut, et il cite CVE-2026-59208 comme cas où limiter les account lookups à l’issuer confirmé, au lieu de matcher un claim sub globalement, aurait stoppé le bug. Je traiterais cette référence CVE comme rapportée par WorkOS plutôt que vérifiée indépendamment, mais le principe défensif reste une bonne pratique standard.
Des déploiements MCP réels ont échoué à issuer validation tout l’été : le serveur MCP Rovo d’Atlassian sert des métadonnées dont l’issuer ne correspond pas à l’URL tenant depuis laquelle elles ont été récupérées (opencode issue #39332), l’endpoint Context7 annonçait un authorization server tandis que ses métadonnées en déclaraient un autre (Context7 issue #2723), et Home Assistant omettait entièrement le champ issuer. RFC 8414 section 3.3 exige que l’issuer corresponde exactement à la retrieval URL, donc les clients stricts ont correctement rejeté les trois.
Ce que les implémenteurs doivent faire
Si vous maintenez un client MCP :
Validez
isssur chaque authorization response dès maintenant. Rejetez les mismatches avec l’issuer avec lequel vous êtes en flow, et si le serveur annonce le support RFC 9207 mais omet le paramètre, rejetez aussi. La spécification indique clairement que le rejet d’unissabsent sera attendu dans une version future, donc traitez-le comme obligatoire aujourd’hui.Partitionnez l’état de registration par authorization server. Chaque client ID, secret et refresh token est stocké avec l’issuer qui l’a émis. Si les protected-resource metadata d’une resource commencent à pointer vers un nouvel authorization server, réenregistrez ; ne rejouez jamais l’ancienne credential.
Déclarez
application_typependant Dynamic Client Registration. SEP-837 corrige la classe de pannes où un client desktop ou CLI est considéréwebpar défaut et rejeté à cause de sa redirect URI localhost. Un champ, une vraie classe de bug supprimée.Limitez les account lookups à l’issuer. Un claim
subne doit matcher que des comptes dans le namespace de l’issuer réellement validé. Jamais de match global.
Si vous exploitez un serveur MCP ou un authorization server placé devant : servez des métadonnées dont issuer est exactement égal à l’URL depuis laquelle elles sont récupérées, chemin tenant inclus, implémentez les protected-resource metadata selon RFC 9728 et continuez de valider que les tokens ont été émis spécifiquement pour votre resource. Et si vous self-hostez des agents contre une liste croissante de serveurs MCP, les mathématiques de flotte comptent : N agents multiplié par M serveurs égale N fois M registrations liées à des issuers. Avec dix agents, c’est un spreadsheet ; avec cent, c’est un registry, et la spécification n’a aucune opinion sur les registries. Cette partie appartient à votre plateforme.
Les implémenteurs doivent validerisssur les authorization responses, rejeter les mismatches et, quand c’est supporté, les omissions, stocker les credentials partitionnées par issuer et se réenregistrer lors d’une migration, déclarerapplication_typependant Dynamic Client Registration, et limiter les account lookups à l’issuer validé, selon l’analyse SEP de Tigera et les recommandations mix-up de WorkOS. Les SDK Tier 1 sont censés livrer le support dans la fenêtre de validation de dix semaines de la spécification.
Ce que la spécification ne répond toujours pas
Relisez le package et remarquez ce que les six SEPs ont en commun : elles durcissent l’échange entre un client OAuth et un authorization server. Il fallait le faire. Mais comme le dit clairement l’analyse de Tigera, le token authentifie le client, pas l’agent. Deux cents agents derrière un host partagent une client identity ; issuer binding ne dit rien sur quel agent, au nom de qui, décidant sur quelle base, se trouve derrière le client. Les scopes sont une admission, pas une policy par request. Les chaînes de délégation, agent appelle agent appelle serveur, peuvent être OAuth-clean à chaque hop et sans accountability end-to-end. Et rien dans le package n’oblige quiconque à écrire tout cela, ce qui est le bon choix de scope pour un protocole et une réponse incomplète pour une entreprise.
Je ne dis pas cela pour diminuer le travail. MCP sans issuer validation était HTTP sans certificate checking, et ce trou se ferme maintenant. Mais les quatre manques, agent identity, per-request authorization, delegation provenance et audit, sont la couche de governance, et ils n’arrivent pas en attendant la spécification. Ce sont les mêmes manques que je travaille avec mes clients sur agent governance, et ils sont imposés par l’environnement autour de l’agent ou par personne.
FAQ
Quel est le problème d’issuer binding OAuth dans MCP ?
Les clients MCP parlent à de nombreux authorization servers découverts au runtime, ce qui les rend vulnérables aux mix-up attacks : une response ou credential est attribuée au mauvais serveur. La spécification 2026-07-28 corrige cela en exigeant que les clients valident le paramètre iss des authorization responses, SEP-2468 adoptant RFC 9207, et qu’ils lient chaque credential enregistrée à son issuer, SEP-2352.
Est-ce une vulnérabilité de MCP lui-même ?
C’est une classe de vulnérabilité que le deployment pattern du protocole a rendue plus fréquente, maintenant fermée au niveau de la spécification. Les pannes observées en production cet été, Atlassian, Context7 et Home Assistant servant des métadonnées avec issuer mismatch, étaient des bugs d’implémentation, mais montrent à quel point le modèle non validé était fragile. La validation stricte devient la baseline.
Quels flows sont concernés ?
Les authorization-code flows avec tout client enregistré auprès de plusieurs authorization servers, Dynamic Client Registration entre serveurs, l’utilisation de credentials après migration d’une resource entre authorization servers et la metadata discovery via des documents .well-known. Les déploiements mono-serveur n’ont jamais été le risque ; c’est la topologie multi-serveur créée par les agents.
Quand cela devient-il obligatoire ?
La spécification 2026-07-28 est finale, le support SDK arrive dans une fenêtre de validation de dix semaines depuis le lock du release candidate en mai, et la spécification dit explicitement que le rejet des responses sans iss sera attendu dans une future version. Traitez-le comme obligatoire dans tout ce que vous construisez aujourd’hui.
En bref
La sécurité OAuth est surtout une comparaison de chaînes ennuyeuse avec des conséquences, et MCP vient de faire face à ce fait. Le package 2026-07-28 importe un correctif OAuth vieux de cinq ans dans un protocole dont la forme un-client-plusieurs-serveurs le rendait urgent, au moment même où des déploiements réels commençaient à échouer à cette vérification en production. Mettez à jour vos SDKs, validez iss, liez vos registrations. Puis posez la question que la spécification a eu raison de ne pas répondre : lorsqu’un token que vous avez émis est utilisé pour un tool call que vous n’auriez jamais approuvé, présenté par un agent que vous ne pouvez pas nommer, qui le détecte et où est la trace ? Cette réponse ne vient pas d’une spécification. Elle vient du harness que vous construisez autour.
Si vous mettez au point auth et identity pour un déploiement MCP, c’est une conversation que j’ai régulièrement avec mes clients. Contactez-moi.
Sources
Tigera, "MCP's Auth Hardening: What the Six New OAuth SEPs Fix, and What They Still Don't": https://www.tigera.io/blog/mcps-auth-hardening-what-the-six-new-oauth-seps-fix-and-what-they-still-dont/ (publié 2026-07-28, consulté 2026-08-29)
WorkOS, "OAuth mix-up attacks and RFC 9207: The issuer check that never made it to token exchange": https://workos.com/blog/oauth-mix-up-attacks-rfc-9207 (publié 2026-07-20, consulté 2026-08-29)
Model Context Protocol, Authorization specification: https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization (publié 2025-11-25, consulté 2026-08-29)
RFC Editor, RFC 9207, "OAuth 2.0 Authorization Server Issuer Identification": https://www.rfc-editor.org/rfc/rfc9207.html (publié 2021-12-16, consulté 2026-08-29)
opencode repository, issue #39332, "MCP OAuth: Atlassian auth fails - RFC 8414 issuer mismatch": https://github.com/anomalyco/opencode/issues/39332 (publié 2026-07-28, consulté 2026-08-29)
Context7 repository, issue #2723, "OAuth metadata issuer mismatch for MCP OAuth endpoint": https://github.com/upstash/context7/issues/2723 (publié 2026-06-05, consulté 2026-08-29)
Home Assistant Core, issue #147059, missing issuer in OAuth metadata: https://github.com/home-assistant/core/issues/147059 (publié 2025-06-17, consulté 2026-08-29)
modelcontextprotocol/modelcontextprotocol repository: https://github.com/modelcontextprotocol/modelcontextprotocol (consulté 2026-08-29)
Continuer la lecture
Agent Field Notes
Recevez le prochain numéro.
Harnesses d’agents, environnements d’exécution, sécurité et gouvernance, expliqués pour celles et ceux qui doivent exploiter ces systèmes.
Vous faites face à une décision de ce type ?
Nous réalisons des revues d'architecture, des évaluations de gouvernance et des comparaisons de frameworks à versions figées pour les équipes confrontées à des décisions déterminantes sur les systèmes d'agents.