SSD Nodes Learn Hosting plans →
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-26

Plugins dsh : fonctionnement et vérification

Installer un plugin dsh exécute le code d’un tiers avec les droits de votre agent. Découvrez ce qu’il peut atteindre et comment l’auditer avant installation.

Qu’est-ce qu’un plugin dsh et que peut-il faire ?

Les plugins dsh sont des packages Node que DeepSeek Harness charge dans son propre processus. L’installation de l’un d’eux exécute le code d’un tiers avec les permissions de votre agent, sur la machine que votre agent peut déjà atteindre. Rien ne sépare un plugin chargé du reste du harness. Avant d’en installer un, vous devez donc déterminer ce que ce code peut toucher et comment limiter cet accès.

dsh (DeepSeek Harness) est l’agent harness open source de DeepSeek AI, construit sur un framework de plugins appelé Cordis. C’est le terme central, car un agent harness est le programme qui entoure le modèle et qui gère la boucle d’exécution, les outils et les permissions. Un plugin s’y intègre exactement à ce niveau. Le README du projet indique que tout est un plugin. L’adaptateur du modèle est un plugin. L’interface web dans laquelle vous saisissez vos requêtes est un plugin. Tout ce que vous installez depuis l’extérieur du projet rejoint la même arborescence, avec le même niveau de confiance que les composants fournis avec le projet. Si vous n’en avez pas encore déployé un, commencez par DeepSeek Harness sur un VPS, puis revenez ici avant d’y ajouter quoi que ce soit.

Les points d’extension accessibles à un plugin sont répertoriés dans le AGENTS.md du dépôt. En août 2026, ils couvrent :

  • LLM (large language model) : le fournisseur payé avec votre clé API
  • Shell : la capacité bash, avec les fournisseurs local et pwsh
  • Filesystem : l’accès aux fichiers contrôlé par des règles
  • Web : les fournisseurs de recherche et de récupération de contenu
  • Subprocess : un fournisseur pour l’arborescence des processus
  • Workflow : les worker threads
  • Subagent : la délégation à d’autres agents
  • Settings and credentials : votre configuration enregistrée et vos variables d’environnement

Un plugin enregistre également des outils dans ctx.tools, et la documentation précise que le schéma d’un outil enregistré est intégré à la construction du prompt. C’est la partie souvent oubliée. Un plugin peut modifier les décisions de votre agent sans que son propre code fasse quoi que ce soit d’inhabituel, car la description qu’il ajoute devient du texte lu par le modèle. Le problème est du même type que l’injection de prompt contre les agents de développement, à une différence près : ce texte arrive lors de l’installation et reste présent jusqu’à la suppression du plugin.

Comment dsh trouve-t-il et charge-t-il les plugins ?

Il n’existe pas de répertoire global de plugins. Un dsh en cours d’exécution est un arbre de plugins composé au démarrage à partir de couches ordonnées. Le profil contient vos choix. $DSH_HOME vaut ~/.dsh par défaut, et chaque profil se trouve dans $DSH_HOME/profiles/<name>. Les profils web et headless sont créés à la première utilisation à partir des templates fournis.

Un répertoire de profil contient deux fichiers qui déterminent toute la configuration :

  • package.json, avec les dépendances des plugins externes et un manifeste dsh.profile contenant la liste ordonnée bundles
  • cordis.patch.yml, votre propre couche de correctifs appliquée à ces bundles
ls ~/.dsh
ls ~/.dsh/profiles/web

Au démarrage, les couches sont appliquées dans cet ordre. Les couches suivantes ont priorité :

  1. une racine vide
  2. les bundles du profil, dans l’ordre indiqué par le manifeste
  3. le cordis.patch.yml du profil
  4. $DSH_HOME/cordis.patch.yml
  5. les éventuelles couches --patch <path> passées sur la ligne de commande

Deux options affichent le résultat de cette composition sans rien démarrer :

dsh --profile web --dump-default-config
dsh --profile web --dump-config

--dump-default-config affiche uniquement l’arbre composé. --dump-config ajoute les couches de correctifs du profil et du répertoire personnel. C’est donc ce qui se rapproche le plus d’un inventaire fiable de ce que votre prochain démarrage chargera. Consultez-le avant de faire confiance à une machine dont vous avez hérité.

Attention aux fichiers de correctifs. Ici, la configuration n’est pas constituée uniquement de données inertes, car le format autorise des valeurs marquées !!js dans le bloc config d’un plugin. Un extrait cordis.patch.yml copié depuis un message de forum est du code. Traitez-le comme un script shell provenant de la même source.

Que lance réellement dsh plugin add ?

dsh plugin --profile <name> <args> transmet ses arguments à pnpm dans le répertoire du profil concerné. pnpm doit donc être présent dans le PATH. Les verbes sont ceux de pnpm :

dsh plugin --profile web add '<package-or-git-spec>'
dsh plugin --profile web remove '<package-name>'
dsh plugin --profile web why '<package-name>'
dsh plugin --profile web update

Le modèle de sécurité applicable à l’installation d’un plugin dsh est donc celui de l’installation de n’importe quelle dépendance de type npm, avec une étape supplémentaire : le résultat est chargé dans votre agent. Le package fournit son propre arbre de dépendances, et chaque package de cet arbre se retrouve dans le même processus. Tout ce qui concerne la manière dont les attaques de la chaîne logistique npm atteignent un serveur s’applique ici sans modification.

pnpm 10 et les versions ultérieures n’exécutent pas les scripts de build d’une dépendance par défaut. Leur approbation se fait package par package avec onlyBuiltDependencies ou pnpm approve-builds. Vérifiez la version de pnpm installée :

pnpm --version

Ce comportement par défaut est utile, mais c’est aussi la fonctionnalité de sécurité la plus souvent mal comprise de l’écosystème. Les scripts de build bloqués empêchent l’exécution de code pendant l’installation. Ils ne protègent pas contre le plugin lui-même, car le rôle d’un plugin est précisément que le harness l’importe et l’appelle au démarrage suivant. Un plugin n’a pas besoin d’un hook postinstall. Il a été autorisé à s’exécuter.

À lire avant d’installer un plugin dsh

Téléchargez l’archive tar publiée et lisez-la. Rien ne s’exécute lorsque vous décompressez une archive.

npm pack '<package-name>@<version>'
tar -tzf '<package-name>-<version>.tgz'
tar -xzf '<package-name>-<version>.tgz'
less package/package.json

Quatre champs de cette package.json vous donnent déjà l’essentiel. Consultez scripts pour les entrées preinstall, install et postinstall. Consultez dependencies pour les noms que vous ne reconnaissez pas, ou pour ceux qui ne diffèrent que d’un caractère d’un nom connu. Consultez bin pour tout ce que le paquet veut ajouter à votre PATH. Consultez main ou exports pour le fichier d’entrée, puis ouvrez ce fichier et suivez son exécution.

Lisez ensuite le code qui sera réellement chargé. Un plugin qui annonce un outil de notification n’a aucune raison de lire ~/.ssh, d’appeler un hôte dont vous n’avez jamais entendu parler ou de lancer un shell. Si le paquet fournit uniquement du JavaScript regroupé ou minifié et qu’aucun code source correspondant n’existe dans un dépôt public, vous avez votre réponse. Privilégiez les plugins dont le code source est lisible, et privilégiez les plugins de petite taille.

Vous pouvez également interroger le registre sans rien installer :

pnpm view '<package-name>' dependencies
pnpm view '<package-name>' versions

Un paquet publié la semaine dernière, avec une seule version, sans champ de dépôt et dont le nom usurpe celui d’un élément populaire, reprend la plus vieille astuce de tous les registres. Vérifier les téléchargements avec des sommes de contrôle est le réflexe complémentaire : sachez exactement ce que vous avez téléchargé avant de l’exécuter.

Figez la version et conservez le fichier de verrouillage

Une plage de versions flottante signifie que le code exécuté dans le processus de votre agent peut changer lors de n’importe quelle installation ou mise à jour, sans que vous l’ayez décidé. Figez la version.

dsh plugin --profile web add --save-exact '<package-name>@<version>'

La position des options varie selon les versions de pnpm. Vérifiez donc le résultat au lieu de vous fier à la commande. Ouvrez ensuite le package.json du profil et vérifiez que la dépendance apparaît sous la forme d’une version seule, sans ^ ni ~ devant. C’est ce fichier qui détermine ce qui est installé.

Conservez ensuite le fichier de verrouillage. Il fige l’ensemble de l’arbre des dépendances transitives, et pas seulement le nom de la dépendance de premier niveau :

find ~/.dsh -maxdepth 3 -name 'pnpm-lock.yaml'

Copiez-le dans un emplacement inclus dans vos sauvegardes, avec le package.json du profil. Ces deux fichiers permettent de reconstruire le même arbre sur un nouveau serveur. Exécutez dsh plugin --profile web update uniquement lorsque vous avez décidé de changer de version, jamais pour effectuer un nettoyage de routine, puis lisez le diff du fichier de verrouillage.

Pour un plugin installé depuis git plutôt que depuis un registry, figez le commit au lieu de la branche. Une spécification de la forme github:owner/repo#<full commit sha> vous donne un arbre fixe. Un nom de branche fournit le contenu de cette branche lors de la prochaine résolution par pnpm. Vous confiez alors cette décision à quelqu’un d’autre. Le harness doit suivre la même discipline, car chaque build dsh publié est une release candidate et une installation sans version figée peut en résoudre une autre n’importe quel jour. C’est à l’origine de la plupart des erreurs d’installation et de version de dsh.

Le marché des plugins et la valeur réelle de la « curation »

dsh dispose d’un marketplace qui s’installe sous forme de plugin. Cela en dit long sur son architecture :

dsh plugin --profile web add dshmarket

Après un redémarrage, il apparaît dans Settings, puis Plugin Market. Son README décrit clairement les limites. Les installations sont limitées aux sources répertoriées dans un registre géré, et toute autre source est refusée. Les scripts de build sont bloqués par défaut. Leur activation nécessite une approbation pour chaque package. Les plugins de terminal sont signalés avant leur ajout à un profil web. La phrase la plus importante précise que leur présence dans le registre ne constitue pas une recommandation, car les plugins sont du code tiers.

Une liste gérée relève le niveau minimal de sécurité. Elle ne lit pas le code à votre place et ne peut pas vous dire ce que fera la prochaine version d’un plugin après un changement de propriétaire du compte du mainteneur. Traitez une installation en un clic comme vous traiteriez curl | bash provenant du même auteur. Une autre ligne de ce README mérite d’être répétée : une sauvegarde exportée peut contenir des identifiants provenant de la configuration de votre profil. Ne la joignez donc jamais à une issue publique ni à un site de paste. Si vous cherchez une liste de départ plutôt qu’une méthode, plugins dsh à installer est l’article complémentaire de celui-ci.

Exécuter dsh avec son propre compte, pas avec root

La vérification réduit la fréquence des intrusions. Le principe du moindre privilège limite ce qu’un intrus peut atteindre. Sur un VPS, cette deuxième mesure est simple à mettre en place.

Attribuez au harness son propre compte Unix et son propre répertoire personnel. Ne l’exécutez jamais avec root :

sudo adduser --disabled-password --gecos "" dshrun
sudo -iu dshrun

Dans cette session, démarrez le harness afin qu’il utilise le répertoire personnel de ce compte :

npx @deepseek-ai/dsh web

L’interface web est disponible sur http://127.0.0.1:3080 par défaut. Laissez cette configuration telle quelle. Si vous avez déjà cliqué sur ce lien depuis une autre machine sans obtenir de réponse, l’explication de l’adresse affichée par dsh indique pourquoi. Toute machine qui atteint ce port peut piloter un agent disposant d’un shell. Publier le port 3080 revient donc à publier un shell distant sans privilèges root, avec une interface conviviale. Accédez-y depuis votre ordinateur portable via un tunnel SSH :

ssh -L 3080:127.0.0.1:3080 you@your-vps

Vérifiez ensuite qu’aucun service n’écoute sur une adresse publique :

ss -lnt | grep 3080

L’adresse locale doit être 127.0.0.1:3080. Si elle est 0.0.0.0:3080, votre pare-feu est le seul obstacle entre un inconnu et votre agent. Le raisonnement présenté dans exécuter Claude Code en toute sécurité sur un VPS s’applique de la même manière à dsh. Attribuez à l’agent un seul répertoire de travail qu’il peut endommager, et conservez hors de cette machine tout ce que vous ne pouvez pas recréer. Mieux encore, considérez cette machine comme une VM jetable pour les agents de codage, car reconstruire un VPS prend une heure, tandis que l’auditer prend une semaine.

Emplacement de vos clés et limites des permissions de fichiers

dsh conserve les clés d’API dans $DSH_HOME/.credentials.yaml et les valeurs d’environnement dans $DSH_HOME/.env, les paramètres des modèles dans $DSH_HOME/settings.yaml et l’historique des sessions sous $DSH_HOME/storages. La clé à placer dans chacun de ces fichiers et les données qui quittent réellement la machine selon le mode utilisé sont expliqués dans la configuration des clés d’API, des modèles et des endpoints de dsh. Il est préférable de régler ce point avant d’ajouter un plugin, car chaque clé que vous configurez est une donnée supplémentaire qu’un plugin peut lire. Restreignez au minimum les deux fichiers sensibles :

chmod 600 ~/.dsh/.credentials.yaml ~/.dsh/.env
ls -l ~/.dsh

Le mode 600 donne à son propriétaire les droits de lecture et d’écriture, et aucun droit aux autres utilisateurs. Cette différence est utile à connaître dans les deux notations (modes chmod numériques et symboliques). Il faut toutefois bien comprendre ce que cette protection apporte. Les modes de fichiers protègent ces fichiers contre les autres comptes présents sur la machine. Ils ne protègent pas contre un plugin, car celui-ci s’exécute avec l’utilisateur qui possède ces fichiers, dans le processus qui les lit. C’est pourquoi garder les secrets hors de portée d’un agent d’IA signifie ne pas les stocker sur la machine. Une machine qui exécute dsh ne devrait contenir que la clé du modèle dont elle a besoin. Vos identifiants cloud et vos clés de signature doivent être conservés ailleurs.

Pourquoi un plugin qui lit le Web modifie le modèle de menace

L’interface Web fournit aux plugins des fournisseurs de recherche et de récupération. Un plugin qui charge une page dans votre session charge du texte qu’un attaquant peut écrire. Un prompt de modèle ne sépare pas les instructions des données. Une page récupérée peut donc contenir une ligne adressée à votre agent, et un harness qui détient la capacité d’exécuter des commandes shell n’est plus qu’à une étape obéissante de son exécution.

Le contrôle existe déjà dans le harness. dsh-base, le premier bundle de chaque profil, fournit le sandbox et la policy d’approbation. Utilisez-les. Une session capable de récupérer des pages non fiables doit demander une approbation pour toute opération qui écrit ou exécute quelque chose. Ainsi, une instruction récupérée ne peut pas devenir une action par elle-même. Soumettre les actions de l’agent à une approbation explique comment déterminer où placer cette limite. La relation fonctionne aussi dans l’autre sens : votre propre serveur est une page que l’agent de quelqu’un d’autre récupérera. C’est le cas du blocage des crawlers d’IA sur votre serveur.

Comment vérifier ce qu’un plugin a modifié ?

Créez un snapshot avant l’installation, installez le plugin, créez un snapshot après l’installation, puis consultez les différences.

dsh --profile web --dump-config > /tmp/dsh-before.txt
dsh plugin --profile web add '<package-name>@<version>'
dsh --profile web --dump-config > /tmp/dsh-after.txt
diff -u /tmp/dsh-before.txt /tmp/dsh-after.txt

Le diff indique quelles entrées du plugin l’installation a ajoutées à l’arbre composé. Si un plugin installé pour une petite fonctionnalité ajoute plusieurs entrées que vous ne pouvez pas justifier, arrêtez-vous et lisez le code source avant de le démarrer. dsh plugin --profile web why <package-name> répond à l’autre question : quelle dépendance directe a tiré un paquet donné.

Les paquets installés sont placés sous $DSH_HOME/profiles/node_modules. Vous pouvez donc aussi examiner l’arbre sur le disque :

ls ~/.dsh/profiles/node_modules

Conservez un second profil dans lequel vous ne faites jamais d’expériences. Si une installation casse le harness, démarrez dsh --profile <clean-name>. Vous saurez en quelques secondes si le plugin en est la cause.

Comment supprimer un plugin dsh ?

dsh plugin --profile web remove '<package-name>'
dsh --profile web --dump-config > /tmp/dsh-after-removal.txt
diff -u /tmp/dsh-before.txt /tmp/dsh-after-removal.txt

La suppression de la dépendance ne supprime pas toujours la configuration. Les entrées écrites dans le cordis.patch.yml du profil restent en place, car ce fichier vous appartient et le harness ne le réécrit pas à votre place. Ouvrez-le et supprimez tout bloc qui fait référence au package supprimé.

less ~/.dsh/profiles/web/cordis.patch.yml

Il faut ensuite traiter ce qu’aucune commande de désinstallation ne peut corriger. Si vous avez supprimé un plugin parce que vous ne lui faisiez plus confiance, il a déjà lu tout ce à quoi il pouvait accéder. Faites une rotation de la clé API DeepSeek dans la console du fournisseur, ainsi que de tous les autres secrets présents dans $DSH_HOME. Déterminez ensuite à quelles ressources du reste de votre réseau le compte Unix utilisé par le plugin pouvait accéder.

La version courte

  • Lisez l’archive tarball publiée avant l’installation, en commençant par scripts et le fichier d’entrée
  • Épinglez la version exacte, ou le commit exact pour une spécification git, et conservez le fichier lock
  • Installez dans un seul profil et gardez un profil propre que vous pouvez démarrer en cas de problème
  • Comparez --dump-config avant et après chaque installation
  • Exécutez le harness avec son propre utilisateur Unix, sur loopback, et accédez-y via SSH
  • Conservez une seule clé API sur la machine et faites-la tourner le jour où vous supprimez un plugin auquel vous ne faites plus confiance

Rien de tout cela ne justifie d’éviter les plugins. Le modèle des plugins explique l’utilité de dsh, et un harness que vous ne pouvez pas étendre est un harness que vous devrez remplacer. Cela signifie qu’il faut savoir ce que vous avez installé, de qui cela vient et à quelle version, puis exécuter l’ensemble dans un environnement que vous pouvez reconstruire.

FAQ

Les plugins dsh sont-ils isolés les uns des autres ?

Non. Cordis charge chaque plugin dans le processus du harness. Le plugin peut accéder aux interfaces de capacité documentées, notamment au shell, au système de fichiers, au web, aux subprocess, aux subagents et aux credentials. dsh-base, le premier bundle de chaque profile, fournit le sandbox et la policy d’approbation qui contrôlent les actions autorisées aux outils de l’agent. C’est cette policy qui vous protège. Il n’existe pas de boundary de permissions entre les plugins. Le modèle à retenir est donc qu’installer un plugin étend votre confiance à son auteur et à chaque package de son dependency tree.

Puis-je installer un plugin dsh sans exécuter ses scripts d’installation ?

pnpm 10 et les versions ultérieures bloquent par défaut les scripts de build des dépendances. dsh plugin ... add s’appuie sur pnpm. Avec une version récente de pnpm, l’installation n’exécute donc pas les scripts des packages, sauf si vous approuvez le package concerné. Vérifiez votre version avec pnpm --version. Cela ne rend pas sûr un plugin dont vous n’avez pas lu le code. Le code du plugin s’exécute au prochain boot, car le harness le charge explicitement. Aucune restriction appliquée lors de l’installation ne l’empêche.

Où se trouvent réellement les plugins dsh et leur configuration ?

$DSH_HOME utilise ~/.dsh par défaut. Les profiles se trouvent dans $DSH_HOME/profiles/<name>. Chacun contient un package.json avec ses plugin dependencies, ainsi que le manifest dsh.profile des bundles dans l’ordre et une couche de patch cordis.patch.yml. Les packages installés sont placés sous $DSH_HOME/profiles/node_modules. Les keys se trouvent dans $DSH_HOME/.credentials.yaml, les valeurs d’environnement dans $DSH_HOME/.env, et un $DSH_HOME/cordis.patch.yml au niveau du home s’applique à tous les profiles. Exécutez dsh --profile web --dump-config pour afficher le résultat composé sans démarrer le harness.

Est-il sûr d’installer un plugin depuis le marché des plugins dsh ?

Le marché limite les installations aux sources d’un registry validé et bloque les scripts de build, sauf si vous les approuvez package par package. C’est une amélioration réelle par rapport au fait de coller un nom de package copié depuis une fenêtre de chat. Son propre README précise toutefois que la présence dans le catalogue ne vaut pas recommandation, car les plugins sont du code tiers fourni par d’autres personnes. Lisez le code source et verrouillez la version. Exécutez le harness avec un compte utilisateur et, dans l’idéal, sur une machine que vous pouvez vous permettre de perdre.