8 min de lecture

Revue d'un outil MCP personnalisé : une checklist de sécurité pratique

Utilisez cette checklist de revue d'un outil MCP personnalisé pour examiner les entrées, les requêtes sortantes, l'identité des processus, les journaux, les approbations et la suppression des accès avant de l'utiliser avec un agent.

Revue d'un outil MCP personnalisé : une checklist de sécurité pratique

Les outils MCP personnalisés méritent le même examen qu'une petite intégration de production ayant accès à votre poste de travail, à votre réseau et à vos identifiants. Le fait qu'un agent appelle l'outil via MCP ne réduit pas ses pouvoirs. Cela facilite souvent l'exercice répété de droits trop larges.

J'ai souvent vu le même échec : un développeur lit la description d'un outil, voit un nom utile comme deploy_preview ou search_docs, puis lui accorde des accès parce qu'il semble local. Plus tard, l'implémentation transforme une chaîne fournie par le modèle en URL, en argument shell ou en lecture récursive de fichiers. L'outil utile n'a jamais constitué la limite de sécurité. Cette limite se trouvait dans l'implémentation et dans le chemin suivi par les identifiants.

La spécification du Model Context Protocol décrit les outils comme des fonctions exposées par un serveur, qu'un client peut découvrir et appeler. Elle rend aussi explicite un fait inconfortable : l'exécution des outils est contrôlée par le modèle. Un client peut placer un humain dans la boucle d'approbation, mais l'auteur de l'outil doit tout de même partir du principe que les arguments peuvent être surprenants, excessifs ou viser la mauvaise cible. Examinez l'outil avant de laisser un agent faire preuve d'inventivité.

Commencez par la cartographie des pouvoirs, pas par le README

Un outil MCP personnalisé n'est acceptable que si vous pouvez tracer un chemin court et concret entre la demande de l'agent et l'effet produit. Commencez par noter ce que l'outil peut lire, où il peut envoyer des données, ce qu'il peut modifier et quel identifiant ou quelle identité du système d'exploitation rend ces actions possibles.

Faites-le avant de lire les détails de l'implémentation. Vous disposez ainsi d'un critère pour évaluer le code, au lieu de laisser une description séduisante fixer la norme. Un outil appelé get_build_status peut lire un fichier de configuration local, appeler une API hébergée, écrire un cache et lancer un utilitaire en ligne de commande. Chaque action présente un mode d'échec différent.

Utilisez une petite cartographie des pouvoirs comme celle-ci :

ÉlémentÀ consignerPourquoi c'est important
Entrée de l'agentChamps exacts de l'outil et tailles maximalesMontre ce que le modèle peut influencer
Lectures localesChemins, variables d'environnement, fichiers de configurationRévèle une collecte accidentelle de données
Écritures localesCache, espace de travail, état git, fichiers temporairesRepère les effets persistants
RéseauNoms d'hôte, ports, méthodes, redirectionsDéfinit les risques d'exfiltration et de requête
ProcessusChemin de l'exécutable, arguments, processus enfantsRepère l'injection shell et les accès hérités
IdentifiantsNom, portée, stockage, responsable de la révocationRend la suppression possible
RésultatsDonnées renvoyées à l'agentEmpêche le retour de secrets par l'outil

N'écrivez pas « Internet » dans la ligne réseau ni « identifiants du développeur » dans la ligne des identifiants. Ces mentions montrent que l'examen n'a pas commencé. Indiquez l'hôte, la famille de routes API, le compte ou le jeton, ainsi que la personne ou le système qui peut le révoquer.

Cet exercice sépare aussi deux éléments que les équipes confondent souvent : la fonction annoncée d'un outil et ses pouvoirs réels. create_issue semble limité. Une fonction qui accepte une URL de base arbitraire, des en-têtes arbitraires et un corps de requête arbitraire possède les pouvoirs d'un client HTTP générique. Examinez cette réalité, pas l'étiquette.

Le schéma d'entrée doit réduire les choix

Un schéma d'entrée MCP doit limiter l'agent à l'opération que vous voulez autoriser. Il ne doit pas servir de définition de type décorative autour d'un canal de commandes en texte libre.

La spécification MCP utilise JSON Schema pour les schémas d'entrée des outils. Cela aide les clients à présenter les arguments et les implémentations à les valider, mais JSON Schema ne constitue pas une contrainte tant que le serveur ne rejette pas les valeurs invalides avant d'effectuer le travail. Considérez le schéma comme le premier filtre et la validation côté serveur comme le second.

Voici un schéma vérifiable pour un outil qui récupère l'état d'une compilation connue :

{
  "name": "get_build_status",
  "description": "Return the status for one build in the approved CI project.",
  "inputSchema": {
    "type": "object",
    "additionalProperties": false,
    "required": ["build_id"],
    "properties": {
      "build_id": {
        "type": "string",
        "pattern": "^[A-Z]{2,8}-[0-9]{1,10}$",
        "maxLength": 20
      },
      "include_logs": {
        "type": "boolean",
        "default": false
      }
    }
  }
}

Il impose plusieurs choix à l'agent. Celui-ci ne peut pas sélectionner un hôte, ajouter des en-têtes ni transmettre une commande shell. Il ne peut pas envoyer de champs non déclarés, car additionalProperties vaut false. L'identifiant de compilation a un format borné, ce qui rend son utilisation en aval moins dangereuse et facilite sa journalisation.

Comparez maintenant avec la structure qui pose problème :

{
  "name": "request",
  "inputSchema": {
    "type": "object",
    "properties": {
      "url": {"type": "string"},
      "method": {"type": "string"},
      "headers": {"type": "object"},
      "body": {}
    }
  }
}

C'est un client HTTP avec un nom convivial. S'il possède un jeton bearer, il peut envoyer ce jeton ou des données provenant d'un prompt contrôlé par l'agent vers n'importe quel point de terminaison. Les équipes conservent cette conception parce qu'elle fait gagner du temps au stade du prototype. Elle reste une mauvaise limite de production, même si le nom de l'outil semble précis.

Testez la gestion des entrées avec des valeurs qui modifient l'analyse syntaxique, et pas seulement avec des valeurs qui semblent incorrectes. Essayez un champ d'identifiant dupliqué, un champ inattendu, une chaîne très longue, des caractères Unicode ressemblants, un saut de ligne et une valeur syntaxiquement valide mais située en dehors du domaine métier prévu. Si une entrée devient un chemin, exigez un identifiant relatif et résolvez-le dans un répertoire fixe. Si elle devient un filtre API, utilisez des paramètres structurés plutôt que de concaténer des chaînes de requête.

Ne transmettez jamais un argument à un shell sous prétexte que le schéma a été validé. Utilisez un tableau d'arguments avec un chemin d'exécutable fixe. Cette version est plus sûre :

subprocess.run(
    ["/usr/local/bin/buildctl", "status", "--id", build_id],
    check=True,
    text=True,
    capture_output=True,
    env={"PATH": "/usr/bin:/bin"}
)

Voici un échec de revue :

subprocess.run(f"buildctl status --id {build_id}", shell=True)

La première forme nécessite toujours une validation, une gestion des erreurs et un exécutable fiable. Elle ne demande pas à un shell de réinterpréter une ponctuation contrôlée par le modèle.

Chaque requête sortante doit avoir une destination fixe

Un outil MCP personnalisé doit posséder un petit ensemble de destinations, et son code doit refuser toute autre destination avant d'ouvrir une connexion. Il ne sert à rien d'autoriser un nom d'hôte dans la documentation si le code accepte une URL arbitraire.

Examinez le trafic sortant à deux niveaux. Commencez par rechercher dans le code les bibliothèques HTTP, clients WebSocket, résolutions DNS, installateurs de paquets, SDK de télémétrie, bibliothèques de webhooks et processus auxiliaires capables de se connecter ailleurs. Observez ensuite une exécution réelle. L'inspection statique révèle les chemins prévus. L'observation à l'exécution détecte une dépendance qui communique avec l'extérieur ou une configuration qui a changé la cible.

Un client sûr construit une URL à partir d'éléments fixes et n'encode que l'identifiant :

from urllib.parse import quote

BASE = "https://ci.example.internal/api/builds/"
url = BASE + quote(build_id, safe="")
response = client.get(url, timeout=10, follow_redirects=False)

Le contrôle important n'est pas quote, mais l'origine fixe. Si votre client suit les redirections, une origine fiable peut renvoyer vers un hôte non fiable. Désactivez les redirections, sauf si l'outil vérifie chaque destination de redirection avec la même liste d'autorisation.

Cela concerne aussi les services internes. Un outil qui accepte http://host/path peut être manipulé pour atteindre des services d'administration locaux ou des points de terminaison de métadonnées auxquels un agent ne peut pas accéder directement. Bloquer les hôtes publics ne suffit pas. Il faut une liste positive d'origines approuvées et une règle qui refuse les adresses IP littérales ou les destinations privées, sauf si l'outil en a explicitement besoin.

Capturez le trafic dans un environnement de test jetable. Sur macOS, lsof donne un premier aperçu rapide des sockets réseau actifs :

lsof -nP -iTCP -sTCP:ESTABLISHED -c python

La structure de la sortie identifie un processus, son utilisateur, son descripteur de fichier et son point de terminaison distant :

COMMAND   PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
python   8421  alex   12u  IPv4 0x...             0t0  TCP 10.0.0.8:51244->203.0.113.20:443 (ESTABLISHED)

Remplacez python par le nom réel du processus, puis recommencez pendant que vous appelez une opération de l'outil. Cette commande ne constitue pas un audit complet du trafic. Les connexions brèves peuvent disparaître avant l'inspection. Elle reste utile pour révéler une connexion inattendue qui dure ou un auxiliaire dont vous ignoriez l'existence.

Examinez les charges utiles des requêtes avec la même attention. Un outil peut appeler correctement une seule API approuvée tout en copiant un diff complet du dépôt, une variable d'environnement ou la transcription de l'agent dans un paramètre de requête. Limitez les champs sortants dans le code. Construisez la charge utile à partir de valeurs nommées nécessaires à l'opération, plutôt que de sérialiser un objet complet reçu de l'agent.

L'identité du processus fait partie de l'autorisation

Vous ne pouvez pas approuver correctement l'utilisation d'un outil si vous ne savez pas quel exécutable l'a demandée. Le nom du processus seul est un indice faible, car n'importe quel processus peut choisir un nom familier.

Consignez la commande de lancement complète, le chemin de l'exécutable, sa version, son répertoire de travail, son processus parent et le compte utilisateur. Si la signature du code macOS s'applique, examinez également l'autorité de signature. codesign peut afficher l'identité reconnue par macOS :

codesign -dv --verbose=4 /absolute/path/to/mcp-server 2>&1 | grep -E 'Identifier|TeamIdentifier|Authority'

La sortie contient généralement des champs comme :

Identifier=com.example.mcpserver
Authority=Developer ID Application: Example Developer
TeamIdentifier=ABCDE12345

Ces champs sont des éléments de preuve, pas une décision d'autorisation à eux seuls. Un binaire signé peut tout de même être le mauvais binaire pour cette tâche, et un script interne non signé n'est pas automatiquement malveillant. Il faut vérifier que le chemin, le propriétaire, la source et l'identité correspondent à l'outil que vous pensiez lancer.

Inspectez ensuite l'arbre des processus pendant un appel :

ps -axo pid,ppid,user,command | grep -E 'mcp-server|sp-ssh|node|python'

Vous voulez obtenir une réponse sans surprise : le client de l'agent lance le serveur MCP, et le serveur ne démarre que les processus auxiliaires prévus. Soyez méfiant lorsque le serveur lance un shell, un gestionnaire de paquets, un interpréteur depuis un répertoire de projet modifiable ou un processus d'arrière-plan qui survit à la session.

Un échec courant semble inoffensif dans un fichier de configuration :

{
  "command": "npx",
  "args": ["-y", "some-mcp-package"]
}

Selon l'état du cache local et la résolution des paquets, cela peut récupérer ou modifier du code au lancement. La revue du code source d'hier devient alors moins pertinente que les équipes ne le pensent. Épinglez l'exécutable ou la version du paquet, installez-le par un processus contrôlé et lancez un chemin local connu. Si l'outil doit être mis à jour, faites de la mise à jour un événement de revue explicite, plutôt qu'un effet invisible du démarrage d'un agent.

L'identité du processus comprend aussi l'environnement hérité. Un serveur lancé depuis le shell d'un développeur peut hériter de jetons cloud, de jetons de gestion du code source, de paramètres proxy et d'un PATH très large. Affichez un inventaire nettoyé lors des tests ou lancez le serveur avec un environnement minimal. Ne journalisez pas les valeurs secrètes. Journalisez les noms des variables qui influencent le comportement et vérifiez que l'outil n'utilise pas des identifiants ambiants dont il n'était pas censé disposer.

Les journaux doivent reconstituer les actions sans répéter les secrets

Interrompez une exécution suspecte
Révoquez instantanément une exécution d'agent depuis le journal Sessions lorsqu'un outil personnalisé se comporte de façon inattendue.

Un enregistrement d'audit utile indique qui a exécuté l'outil, avec quel processus, quels arguments nettoyés ont été fournis, vers quelle destination, et avec quel résultat. Une ligne indiquant tool call succeeded ne répond à aucune des questions que vous vous poserez lorsqu'un agent enverra des données vers un endroit inattendu.

Séparez les journaux opérationnels des sorties de débogage contenant des secrets. Les opérateurs ont besoin de suffisamment de détails pour enquêter. Ils n'ont pas besoin de jetons bearer, d'en-têtes d'autorisation, de clés privées, de transcriptions brutes de l'agent ou de corps de réponse complets copiés dans un fichier texte.

Pour chaque appel, consignez des champs similaires à ceux-ci :

{
  "time": "2025-03-08T14:22:11Z",
  "session_id": "run_7c2f",
  "process": "/opt/tools/build-mcp",
  "tool": "get_build_status",
  "argument_summary": {"build_id": "CI-4812", "include_logs": false},
  "destination": "ci.example.internal",
  "decision": "approved",
  "result": "success",
  "request_id": "c4e8..."
}

L'exemple utilise volontairement un résumé des arguments. Celui-ci doit conserver les identifiants et les champs bornés utiles à l'enquête, tout en masquant ou en hachant les valeurs sensibles. Si une opération envoie légitimement un document, consignez sa taille en octets et un condensat du contenu lorsque cela facilite la corrélation. Ne placez pas le document lui-même dans le journal uniquement pour simplifier le débogage.

Le modèle de journalisation OpenTelemetry est utile ici, même si vous n'adoptez pas OpenTelemetry. Il distingue le corps de l'événement des attributs et met l'accent sur les champs structurés pour le filtrage et la corrélation. Appliquez cette idée localement : rendez la destination, l'opération, le résultat et l'identité du processus lisibles par une machine. Un tas de lignes de texte devient inutile dès que vous devez déterminer si l'agent a envoyé dix fois la même requête.

Examinez aussi les chemins d'erreur. De nombreux outils masquent les requêtes réussies, mais affichent un objet de requête complet lorsqu'une API renvoie une erreur. Forcez une réponse 401, un délai d'attente, un JSON malformé et un échec de résolution DNS. Lisez chaque ligne produite. Les identifiants s'échappent souvent par la sortie de débogage.

Sallyport conserve un journal Sessions pour les exécutions d'agents et un journal Activity pour les appels individuels, tous deux dérivés d'un journal d'audit chiffré, chaîné par hachage et insensible à l'écriture. Cette conception est utile lorsqu'il vous faut une trace locale qui ne dépende pas des seuls journaux de l'auteur de l'outil, mais elle ne rend pas un outil trop large sûr. L'outil a toujours besoin d'entrées limitées et de destinations connues.

Les demandes d'approbation ne peuvent pas corriger des pouvoirs trop larges

L'approbation humaine n'est un frein utile que si l'objet approuvé possède une portée compréhensible. Une carte indiquant qu'un processus inconnu veut utiliser un identifiant vous apprend quelque chose d'important. Elle ne vous dit pas si un outil de requête générique enverra dans cinq secondes un fichier du dépôt vers un hôte choisi par un modèle.

Faites coïncider autant que possible l'unité d'approbation et l'unité de pouvoir. Un jeton en lecture seule permettant de consulter un état et un jeton de déploiement en production ne doivent pas dépendre d'une même approbation, car leurs conséquences sont différentes. Un outil qui lit un enregistrement de mise en production ne doit pas acquérir discrètement la capacité d'en créer un sous prétexte que les deux opérations utilisent la même API.

La spécification du Model Context Protocol recommande que les clients obtiennent le consentement de l'utilisateur avant d'appeler les outils. C'est une bonne recommandation, mais le consentement présente un risque : les utilisateurs approuvent des demandes répétitives et mal décrites jusqu'à ce que la demande ne fournisse plus aucune information. Ne résolvez pas la lassitude face aux prompts en approuvant pour toujours toute une catégorie d'actions. Corrigez la limite de l'outil qui produit des demandes vagues ou excessives.

L'échelle de décision de Sallyport place un coffre verrouillé avant toute action, demande par défaut une autorisation par session et peut exiger une décision à chaque utilisation d'un identifiant donné. Utilisez l'approbation à chaque appel pour les identifiants dont vous voudriez examiner chaque utilisation, comme un identifiant de déploiement ou une clé API autorisant l'écriture. Ne vous en servez pas pour justifier l'attribution de cet identifiant à un outil HTTP générique.

Un bon test d'approbation doit pouvoir se résumer ainsi : « Ce processus signé, lancé depuis ce chemin, peut utiliser cet identifiant pour lire l'état de ce service pendant cette exécution. » Si vous ne pouvez pas le dire honnêtement, refusez la demande et revenez à la cartographie des pouvoirs.

Testez les échecs avant de faire confiance aux succès

Sachez quel processus fait la demande
Approuvez un nouveau processus d'agent une fois par session, après avoir affiché son autorité de signature du code.

Un outil qui fonctionne dans le scénario idéal n'a pas réussi une revue de sécurité. Vous devez observer son comportement lorsque les entrées sont incorrectes, que son identifiant est absent, que le réseau pointe vers un endroit inattendu ou que son processus auxiliaire échoue.

Exécutez l'outil dans un compte de test ou un projet isolé, avec un identifiant dont la portée est aussi réduite que possible. Utilisez des données de test suffisamment proches des données réelles pour exercer la sérialisation et les limites de taille, mais ne transmettez jamais de secrets de production à un outil non vérifié simplement pour voir ce qui se passe.

Suivez cette séquence en cinq étapes :

  1. Appelez l'outil avec une requête valide et capturez son arbre de processus, sa destination sortante et son enregistrement d'audit.
  2. Envoyez un champ non déclaré, une valeur de longueur maximale, une valeur contenant des retours à la ligne et un identifiant plausible situé en dehors du projet autorisé. Le serveur doit tous les rejeter avant d'effectuer une requête.
  3. Forcez un hôte non approuvé par toutes les entrées et tous les chemins de configuration disponibles. Incluez les redirections si l'outil utilise HTTP. L'outil doit le refuser et enregistrer ce refus sans exposer l'entrée sensible.
  4. Supprimez ou révoquez l'identifiant pendant que le serveur reste actif, puis répétez la requête valide. Vérifiez que l'action suivante échoue au lieu de réussir grâce à un cache caché ou à un environnement hérité.
  5. Tuez le processus parent de l'agent et recherchez les processus du serveur ou des auxiliaires qui auraient survécu. Un processus d'arrière-plan qui conserve ses accès après la fin de l'agent doit avoir une raison claire et faire l'objet d'une revue distincte.

Conservez les preuves avec la version de l'outil : manifeste, révision du code source ou condensat du paquet, commandes utilisées, points de terminaison observés, exemple d'enregistrement d'audit nettoyé et nom de la personne ayant accepté les risques restants. Ce n'est pas de la paperasse gratuite. Sans preuves versionnées, une mise à jour ultérieure du paquet modifie l'outil et chacun suppose que l'ancienne revue reste valable.

Un échec mérite une attention particulière. Supposons qu'un outil de recherche documentaire accepte repository_path et appelle un auxiliaire au moyen d'une chaîne shell. Les requêtes normales fonctionnent. Plus tard, un agent reçoit dans un ticket une instruction lui demandant de rechercher un chemin contenant de la ponctuation shell. L'auxiliaire exécute une seconde commande sous le compte du développeur, lit un fichier d'identifiants, puis l'outil envoie le résultat vers son point de terminaison de recherche pourtant approuvé. Chaque composant a fait ce que son auteur attendait. La composition a échoué parce que le schéma autorisait un chemin, que le shell l'a réinterprété et que la charge sortante acceptait toute sortie de l'auxiliaire. Testez les chaînes d'actions, pas seulement les fonctions isolées.

Retirer les accès demande plus que supprimer une entrée de configuration

Inspectez chaque utilisation d'une clé sensible
Marquez une clé API sensible pour demander une approbation à chaque utilisation, plutôt que de faire confiance à une session d'outil trop large.

Retirer un serveur MCP de la configuration d'un agent empêche son lancement habituel. Cela ne révoque pas un jeton copié dans un cache, n'arrête pas un serveur toujours actif, ne retire pas une clé SSH d'un processus d'agent et n'invalide pas l'accès au service distant.

Planifiez la suppression au moment où vous accordez l'accès. Le responsable de l'identifiant doit savoir où le révoquer, l'outil doit utiliser un identifiant distinct lorsque c'est possible et l'opérateur doit savoir quels processus et fichiers locaux supprimer. Les jetons de développeur partagés transforment une suppression simple en incident, car il devient impossible de distinguer les utilisations de l'outil.

Pour un outil qui utilise HTTP, révoquez ou désactivez d'abord le jeton distant. Arrêtez ensuite le serveur MCP et tous ses auxiliaires, supprimez la référence locale à l'identifiant et effacez la configuration de lancement. Réexécutez enfin la même requête et conservez le résultat refusé. Pour SSH, retirez la clé publique concernée du compte ou du dépôt distant, terminez les processus auxiliaires locaux et vérifiez la configuration de l'agent à la recherche d'autres identités.

Ne confondez pas le verrouillage d'un coffre local avec la révocation distante. Le verrouillage empêche toute utilisation future par ce coffre tant qu'il reste verrouillé. Il ne peut pas retirer des données déjà envoyées, invalider un jeton stocké ailleurs ni arrêter un processus indépendant qui a hérité auparavant d'un identifiant.

Rendez la suppression vérifiable avant qu'un incident ne survienne. Ajoutez à la procédure une courte entrée indiquant où effectuer la révocation distante, quelle réponse de refus attendre, quelle commande arrêter, où se trouve la configuration et quels champs de journal confirmeront l'échec de la tentative. Si le responsable de l'outil ne peut pas fournir cette entrée, l'intégration n'est pas terminée.

Un outil limité mérite une confiance renouvelable

Les outils qui résistent aux revues sont généralement ennuyeux, dans le meilleur sens du terme. Ils acceptent quelques champs typés, se connectent à un service connu, lancent un exécutable connu lorsqu'ils en ont besoin, ne renvoient à l'agent que le résultat nécessaire et laissent une trace que quelqu'un peut consulter plus tard.

Les outils très larges semblent flexibles parce qu'ils reportent les décisions de conception sur l'agent au moment de l'exécution. Ils transforment aussi une seule approbation en autorisation sur des destinations, des données et des commandes que personne n'a examinées. Gardez la flexibilité dans le code que vous contrôlez et exposez une opération limitée à l'agent.

Avant d'approuver un outil personnalisé, essayez de supprimer une entrée, une destination, une partie de la portée d'un identifiant ou un processus enfant. Si personne ne peut expliquer pourquoi cet élément doit rester, supprimez-le. La revue devient plus simple, tout comme la réponse à un incident éventuel.

FAQ

Que dois-je vérifier avant de connecter un outil MCP à un agent ?

Traitez un outil MCP personnalisé comme du code qui reçoit des instructions choisies par un modèle, et non comme une extension inoffensive. Examinez son schéma, toutes ses destinations réseau, chacun de ses processus enfants, son identité, ses journaux et la façon dont vous retirez ses accès. Un README bien rédigé ne prouve rien de tout cela.

MCP rend-il un outil sûr par défaut ?

Non. MCP décrit la façon dont les clients et les serveurs communiquent, mais ne certifie ni l'implémentation d'un outil ni ses destinations. Un outil peut respecter MCP tout en envoyant des prompts, des fichiers ou des identifiants vers un endroit que vous n'avez pas approuvé.

Les schémas JSON suffisent-ils à sécuriser les entrées des outils MCP ?

Le schéma d'un outil peut limiter les entrées qu'un modèle peut fournir, mais il ne garantit pas que l'outil les utilisera correctement. Refusez les champs génériques fourre-tout comme query, options ou le JSON arbitraire lorsque l'opération ne devrait accepter qu'un nombre limité de paramètres. Validez aussi les données dans l'implémentation, car les schémas n'empêchent pas un client compromis d'envoyer des requêtes malformées.

Un serveur MCP local peut-il tout de même exfiltrer des données ?

Un serveur MCP local utilisant stdio peut tout de même effectuer des appels HTTP sortants, lancer des gestionnaires de paquets, lire votre répertoire personnel ou démarrer des processus enfants. Le mode local ne change que le transport entre le client et le serveur, pas les droits dont le serveur hérite. Examinez la commande de lancement et les chemins de code auxquels elle donne accès.

Comment vérifier l'identité du processus d'un serveur MCP ?

Cherchez quel exécutable possède réellement la connexion réseau et quel compte utilisateur le lance. Le nom d'un paquet signé apporte moins de garanties qu'un chemin connu, une version enregistrée, un condensat quand il est disponible et un arbre des processus que vous pouvez reproduire. N'approuvez pas une identité que vous ne pourriez pas expliquer à un autre ingénieur.

Que doivent contenir les journaux d'audit d'un outil MCP ?

Les journaux d'audit doivent fournir assez de contexte pour reconstituer une action : identité de la session ou du processus, heure, nom de l'outil, arguments nettoyés, destination, catégorie du résultat et décision d'approbation. Des journaux qui indiquent seulement qu'un outil a été appelé ne permettent pas de savoir où les données sont parties. Gardez les secrets et les charges utiles sensibles complètes hors des journaux ordinaires.

Comment révoquer correctement les accès d'un outil MCP ?

Utilisez un identifiant ou une autorisation distincts pour chaque outil lorsque le service distant le permet. Retirer l'outil d'une configuration ne fait qu'empêcher son lancement habituel ; cela ne révoque ni un jeton copié ni un processus déjà actif. Révoquez l'identifiant distant, arrêtez le processus, retirez l'autorisation locale et vérifiez le résultat avec un test qui doit être refusé.

Quand est-il raisonnable d'autoriser un agent à utiliser un outil MCP personnalisé ?

Cela peut être raisonnable pour des opérations limitées et en lecture seule, dirigées vers une destination connue, avec un schéma borné et des journaux utiles. C'est un mauvais choix pour l'exécution générale de commandes shell, les URL arbitraires, la lecture récursive de fichiers ou les outils qui regroupent plusieurs pouvoirs sans rapport sous un même nom. La commodité ne justifie pas de donner à un modèle des droits implicites.

Les demandes d'approbation rendent-elles sûr un outil MCP risqué ?

Cela aide souvent, mais ne remplace pas l'examen de l'outil. Le premier appel vous indique quel processus demande l'accès, tandis que l'approbation à chaque appel limite les utilisations individuelles d'un identifiant sensible. Un outil capable d'envoyer des données arbitraires vers des hôtes arbitraires doit tout de même être conçu de manière plus restrictive avant que l'approbation soit utile.

Comment tester un outil MCP sans lui faire confiance au préalable ?

Exécutez l'outil avec des entrées représentatives et volontairement difficiles, puis capturez le trafic sortant et l'activité des processus enfants. Vérifiez que les URL invalides, les champs inattendus, les métacaractères shell, les valeurs trop longues et les paramètres manquants entraînent un échec fermé. Recommencez ensuite après avoir révoqué l'identifiant pour confirmer que sa suppression fonctionne.

Sallyport

Sallyport exécute les appels d'API et les commandes SSH à la place de votre agent IA. Les clés restent dans un coffre-fort local sur votre Mac ; vous approuvez chaque exécution et chaque action est consignée dans un journal scellé.

© 2026 Sallyport · Open source sous Apache-2.0 · Oleg Sotnikov