Aller au contenu principal
Leçon 8 sur 14 · Apps SDK et plugins ChatGPT — serveurs MCP et interfaces

Authentification et sécurité

Leçon 8 sur 14 Mis à jour le 3 novembre 2026 Développeur
Sur cette page
  1. Qui doit s’authentifier
  2. Ce qu’exige la spécification
  3. Comment ChatGPT s’enregistre comme client
  4. Le flux, vu de l’utilisateur
  5. Déclarer quels outils exigent un compte
  6. Vérifier chaque jeton
  7. Identifier ChatGPT comme client
  8. Les principes de sécurité d’OpenAI
  9. Tester l’authentification
  10. Points clés à retenir

Leçon réécrite le 3 novembre 2026 d’après les pages Authentication et Security & Privacy de la documentation Plugins d’OpenAI. L’ancienne version proposait une authentification par clé d’API et une configuration auth dans un manifeste inexistant ; ChatGPT ne sait pas présenter de clé d’API personnalisée et suit le flux d’autorisation de la spécification MCP (OAuth 2.1). Sources : Authentication · Security & Privacy.

Qui doit s’authentifier

Beaucoup de serveurs MCP peuvent fonctionner en lecture seule, de façon anonyme. Tout ce qui expose des données propres à un client, ou qui écrit quoi que ce soit, doit en revanche authentifier l’utilisateur. Le contrat d’autorisation est celui de la spécification MCP, le même dans ChatGPT et dans Codex : un flux OAuth 2.1, avec trois acteurs.

  • Le serveur de ressources : votre serveur MCP, qui expose les outils et vérifie le jeton d’accès à chaque requête.
  • Le serveur d’autorisation : votre fournisseur d’identité, qui émet les jetons et publie ses métadonnées de découverte.
  • Le client : l’hôte OpenAI, ChatGPT ou Codex, qui agit pour le compte de l’utilisateur.

OpenAI recommande fortement de s’appuyer sur un fournisseur d’identité établi plutôt que d’écrire son authentification de zéro ; sa documentation renvoie notamment à Auth0 et à Stytch.

Ce qu’exige la spécification

Des métadonnées de ressource protégée. Votre serveur MCP publie un document, par exemple à https://votre-mcp.example.com/.well-known/oauth-protected-resource, qui donne son identifiant canonique (resource), ses serveurs d’autorisation (authorization_servers) et, facultativement, les portées proposées (scopes_supported). Quand une requête arrive sans authentification valable, le serveur répond 401 Unauthorized avec un en-tête qui pointe vers ce document :

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://votre-mcp.example.com/.well-known/oauth-protected-resource", scope="files:read"

Des métadonnées de serveur d’autorisation, à /.well-known/oauth-authorization-server ou /.well-known/openid-configuration, avec l’émetteur (issuer), les points d’autorisation et de jeton, et code_challenge_methods_supported contenant S256 — sans quoi le serveur MCP n’est pas pris en charge, PKCE étant obligatoire.

Le paramètre resource repris de bout en bout. ChatGPT ajoute resource=… aux requêtes d’autorisation et de jeton ; votre serveur d’autorisation le recopie dans le jeton (souvent la revendication aud), et votre serveur MCP rejette tout jeton qui n’a pas été émis pour lui.

Comment ChatGPT s’enregistre comme client

Trois voies coexistent. La voie préférée est CIMD (Client ID Metadata Documents) : ChatGPT utilise comme client_id l’URL d’un document de métadonnées hébergé en HTTPS, que votre serveur d’autorisation va lire ; activez-la en publiant client_id_metadata_document_supported: true. ChatGPT y accepte deux méthodes d’authentification au point de jeton : none (client public, protégé par PKCE) et private_key_jwt (assertion signée, vérifiable avec la clé publique publiée par ChatGPT). L’enregistrement dynamique (DCR) reste possible si vous publiez un registration_endpoint : ChatGPT s’enregistre une fois par connexion et réutilise ce client. Un client OAuth prédéfini est la troisième voie.

Côté redirection, copiez dans la liste blanche de votre serveur d’autorisation l’URI exacte affichée sur la page de gestion du serveur MCP dans ChatGPT : elle dépend de la prise en charge de l’identification de l’émetteur (RFC 9207, paramètre iss renvoyé dans chaque réponse d’autorisation).

Le flux, vu de l’utilisateur

  1. ChatGPT lit les métadonnées de ressource protégée de votre serveur.
  2. Il s’identifie comme client OAuth (CIMD, DCR ou client prédéfini).
  3. Au premier appel d’un outil protégé, il lance le flux authorization code + PKCE : l’utilisateur se connecte et consent aux portées demandées.
  4. ChatGPT échange le code contre un jeton et l’ajoute aux requêtes MCP suivantes (Authorization: Bearer …).
  5. Votre serveur vérifie le jeton à chaque requête avant d’exécuter l’outil.

Déclarer quels outils exigent un compte

ChatGPT n’affiche son interface de liaison de compte que si votre serveur signale qu’OAuth est disponible ou nécessaire. Il faut pour cela les deux moitiés : des métadonnées et une erreur à l’exécution.

Les métadonnées, d’abord : chaque outil déclare sa politique dans _meta.securitySchemes. noauth signifie appelable anonymement, oauth2 exige un jeton avec les portées indiquées ; déclarer les deux signale qu’on peut commencer sans compte et que la liaison débloque davantage. Déclarez-le outil par outil, même si tout le serveur suit la même politique.

server.registerTool(
  "create_doc",
  {
    title: "Créer un document",
    description: "Crée un nouveau document dans le compte de l'utilisateur.",
    inputSchema: { title: z.string().min(1) },
    _meta: { securitySchemes: [{ type: "oauth2", scopes: ["docs.write"] }] },
  },
  async ({ title }, extra) => {
    const jeton = await verifierJeton(extra); // signature, iss, aud, exp, portées
    if (!jeton) {
      return {
        isError: true,
        content: [{ type: "text", text: "Connexion requise pour créer un document." }],
        _meta: {
          "mcp/www_authenticate": [
            'Bearer resource_metadata="https://votre-mcp.example.com/.well-known/oauth-protected-resource", error="insufficient_scope", error_description="Connectez votre compte pour continuer"',
          ],
        },
      };
    }
    // … créer le document pour jeton.sub
  }
);

L’erreur à l’exécution, ensuite : quand le jeton manque ou ne convient pas, l’outil renvoie un résultat d’erreur portant _meta["mcp/www_authenticate"], avec les paramètres error et error_description. C’est ce contenu qui déclenche réellement l’interface de connexion. verifierJeton est votre fonction de vérification ; les SDK MCP en Python et en TypeScript fournissent des aides pour l’écrire.

Vérifier chaque jeton

Une fois le flux terminé, ChatGPT joint le jeton tel quel à chaque requête. Considérez-le comme non fiable et faites vous-même toutes les vérifications d’un serveur de ressources : signature avec les clés publiées par votre serveur d’autorisation (JWKS) et émetteur iss ; validité dans le temps (exp, nbf) ; audience (aud ou resource) et portées requises ; puis vos règles propres. En cas d’échec : 401 et en-tête WWW-Authenticate, ce qui relance le flux OAuth.

Identifier ChatGPT comme client

Pour vérifier qu’une requête vient bien de ChatGPT, deux moyens existent. ChatGPT présente un certificat client géré par OpenAI lors de la connexion TLS (mTLS) : vérifiez qu’il remonte à l’autorité intermédiaire publiée par OpenAI, qu’il est valable pour l’authentification client et que son nom dnsName est mtls.prod.connectors.openai.com, sans épingler l’empreinte du certificat final, qu’OpenAI peut renouveler. Vous pouvez aussi filtrer sur les plages d’adresses IP publiées. L’mTLS authentifie ChatGPT ; OAuth continue d’authentifier l’utilisateur.

ChatGPT ne prend en charge ni les autorisations de machine à machine (client credentials, comptes de service, assertions JWT bearer), ni les clés d’API personnalisées, ni les certificats mTLS fournis par le client.

Les principes de sécurité d’OpenAI

  • Moindre privilège : ne demandez que les portées, le stockage et les accès réseau nécessaires.
  • Consentement explicite : l’utilisateur doit comprendre quand il lie un compte ou accorde un droit d’écriture ; utilisez les confirmations de l’hôte pour les actions destructrices.
  • Défense en profondeur : partez du principe que des injections de prompt et des entrées malveillantes atteindront votre serveur ; validez toutes les entrées côté serveur, même fournies par le modèle, et tenez des journaux d’audit.

Côté données : n’incluez dans structuredContent que ce dont la demande a besoin, publiez une politique de conservation et respectez les demandes de suppression, masquez les données personnelles dans les journaux. Côté interface : le composant tourne dans une iframe isolée, sous une politique de contenu stricte, sans accès à window.alert, window.prompt, window.confirm ni navigator.clipboard. Côté exploitation : revue de sécurité avant le lancement, alertes sur les échecs d’authentification répétés, dépendances tenues à jour.

Tester l’authentification

Commencez avec un locataire de développement qui émet des jetons de courte durée, réservez l’accès à des testeurs de confiance avant d’ouvrir plus largement, et prévoyez révocation, rafraîchissement et changement de portées : un jeton absent ou périmé se traite comme une absence d’authentification, avec un message d’erreur utile. Les réglages Auth de MCP Inspector permettent de suivre le flux OAuth étape par étape pour voir où il casse.

Points clés à retenir

  • Données privées ou écritures : OAuth 2.1 selon la spécification MCP, avec PKCE S256
  • Le serveur publie ses métadonnées de ressource protégée et répond 401 + WWW-Authenticate
  • CIMD est la voie d’enregistrement préférée ; DCR et client prédéfini restent possibles
  • Interface de liaison : securitySchemes par outil et erreur portant _meta["mcp/www_authenticate"]
  • Chaque jeton est vérifié à chaque requête ; l’mTLS identifie ChatGPT, OAuth identifie l’utilisateur