SSD Nodes Learn Hosting plans →
Guías Matt ConnorPor Matt Connor · Actualizado 2026-08-26

Plugins de dsh: cómo funcionan y cómo revisarlos

Instalar un plugin de dsh ejecuta código ajeno con los permisos de su agente. Aprenda qué puede alcanzar y cómo revisarlo antes de incorporarlo a Harness.

¿Qué es un plugin de dsh y qué puede hacer?

Los plugins de dsh son paquetes de Node que DeepSeek Harness carga en su propio proceso. Al instalar uno, se ejecuta código de terceros con los permisos de su agente y en una máquina a la que el agente ya puede acceder. No hay ninguna barrera entre un plugin cargado y el resto de Harness. Por eso, antes de instalar uno, debe preguntarse a qué puede acceder ese código y cómo limitar ese acceso.

dsh (DeepSeek Harness) es el harness de agentes de código abierto de DeepSeek AI, creado sobre un framework de plugins llamado Cordis. Esa palabra intermedia es importante, porque un harness de agentes es el programa que envuelve al modelo y controla el bucle de ejecución, las herramientas y los permisos; un plugin se integra exactamente en ese nivel. El README del proyecto indica que todo es un plugin. El adaptador del modelo es un plugin. La interfaz web en la que escribes es un plugin. Todo lo que instalas desde fuera del proyecto se incorpora al mismo árbol y tiene el mismo nivel de confianza que los componentes incluidos originalmente. Si todavía no has puesto uno en funcionamiento, empieza por DeepSeek Harness en un VPS y vuelve aquí antes de añadirle nada.

Los puntos de extensión a los que puede acceder un plugin aparecen en AGENTS.md del repositorio. En agosto de 2026 incluyen:

  • LLM (large language model): el proveedor al que paga con su clave de API
  • Shell: la capacidad de bash, con proveedores local y pwsh
  • Filesystem: acceso a archivos controlado por políticas
  • Web: proveedores de búsqueda y obtención de contenido
  • Subprocess: un proveedor para árboles de procesos
  • Workflow: hilos de trabajo
  • Subagent: delegación a otros agentes
  • Settings and credentials: su configuración guardada y las variables de entorno

Un plugin también registra herramientas en ctx.tools, y la documentación indica claramente que el esquema de una herramienta registrada se incorpora al ensamblado del prompt. Esta segunda parte suele pasarse por alto. Un plugin puede cambiar lo que su agente decide hacer sin que su propio código haga nada inusual, porque la descripción que aporta se convierte en texto que el modelo lee. Es el mismo tipo de problema que la inyección de prompts contra agentes de programación, con una diferencia: este texto llega al instalar el plugin y permanece hasta que lo elimina.

¿Cómo busca y carga plugins dsh?

No existe un directorio global de plugins. Un dsh en ejecución es un árbol de plugins que se compone durante el arranque a partir de capas ordenadas, y el elemento que contiene las opciones elegidas es un perfil. $DSH_HOME tiene el valor predeterminado ~/.dsh y cada perfil se encuentra en $DSH_HOME/profiles/<name>. Los perfiles web y headless se crean automáticamente durante el primer uso a partir de las plantillas incluidas.

Un directorio de perfil contiene dos archivos que determinan todo:

  • package.json, con las dependencias de plugins externos y un manifiesto dsh.profile que contiene la lista ordenada de bundles
  • cordis.patch.yml, su propia capa de cambios sobre esos paquetes
ls ~/.dsh
ls ~/.dsh/profiles/web

El arranque aplica las capas en este orden. Las capas posteriores prevalecen:

  1. una raíz vacía
  2. los paquetes del perfil, en el orden indicado por el manifiesto
  3. cordis.patch.yml del perfil
  4. $DSH_HOME/cordis.patch.yml
  5. cualquier capa --patch <path> pasada en la línea de comandos

Dos flags muestran el resultado de esta composición sin iniciar nada:

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

--dump-default-config muestra el árbol compuesto sin más. --dump-config añade las capas de cambios del perfil y del directorio personal. Por tanto, es lo más parecido a un inventario fiable de lo que cargará el próximo arranque. Léalo antes de confiar en una máquina que ha heredado.

Hay una advertencia sobre esos archivos de cambios. La configuración no es aquí un conjunto de datos inerte, porque el formato permite valores etiquetados !!js dentro del bloque config de un plugin. Un fragmento cordis.patch.yml copiado de una publicación de un foro es código. Trátelo como trataría un script de shell procedente de la misma fuente.

¿Qué ejecuta realmente dsh plugin add?

dsh plugin --profile <name> <args> reenvía sus argumentos a pnpm dentro del directorio de ese perfil, por lo que pnpm debe estar en PATH. Los verbos son los 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

Por tanto, el modelo de seguridad de instalar un complemento de dsh es el mismo que el de instalar cualquier dependencia de estilo npm, más un paso adicional en el que el resultado se carga en el agente. El paquete incluye su propio árbol de dependencias y todos los paquetes de ese árbol terminan en el mismo proceso. Todo lo explicado en cómo los ataques a la cadena de suministro de npm llegan a un servidor se aplica aquí sin cambios.

pnpm 10 y las versiones posteriores no ejecutan de forma predeterminada los scripts de compilación de una dependencia, y la aprobación se concede por paquete mediante onlyBuiltDependencies o pnpm approve-builds. Compruebe qué versión de pnpm tiene:

pnpm --version

Este valor predeterminado es útil, pero también es la función de seguridad más sobrevalorada del ecosistema. Los scripts de compilación bloqueados impiden que se ejecute código durante la instalación. No hacen nada para proteger el complemento, porque la finalidad de un complemento es que el arnés lo importe y lo ejecute en el siguiente arranque. Un complemento no necesita un enlace postinstall. Se le permitió cargarse.

Qué leer antes de instalar un plugin de dsh

Descargue el tarball publicado y léalo. No se ejecuta nada al desempaquetar un archivo.

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

Cuatro campos de ese package.json le proporcionan casi toda la información que necesita. Lea scripts para consultar las entradas preinstall, install y postinstall. Lea dependencies para revisar nombres que no reconozca o nombres que se diferencien en un solo carácter de otros conocidos. Lea bin para comprobar qué elementos quiere el paquete en su PATH. Lea main o exports para localizar el archivo de entrada. Después, abra ese archivo y sígalo.

A continuación, lea el código que se cargará realmente. Un plugin que anuncia una herramienta de notificaciones no tiene ningún motivo para leer ~/.ssh, conectarse a un host que no conoce o iniciar un shell. Si el paquete sólo incluye JavaScript agrupado o minimizado y no existe el código fuente correspondiente en un repositorio público, esa es la respuesta. Prefiera plugins cuyo código fuente pueda leer y dé prioridad a los que sean pequeños.

También puede consultar el registro sin instalar nada:

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

Un paquete publicado la semana pasada, con una sola versión, sin campo de repositorio y con un nombre que suplanta a algo popular es el truco más antiguo de cualquier registro. Verificar las descargas con sumas de comprobación es la práctica complementaria: sepa exactamente qué ha descargado antes de permitir que se ejecute.

Fije la versión y conserve el archivo de bloqueo

Un rango de versiones flotante permite que el código dentro del proceso de su agente cambie en cualquier instalación o actualización sin que usted decida nada. Fije la versión.

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

La posición de las opciones varía entre las versiones de pnpm, así que compruebe el resultado en lugar de confiar en el comando. Abra después el package.json del perfil y confirme que la dependencia aparece como una versión simple, sin ^ ni ~ delante. Ese archivo determina qué se instala.

Después conserve el archivo de bloqueo, que fija todo el árbol transitivo y no sólo el nombre de nivel superior:

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

Cópielo en una ubicación incluida en las copias de seguridad, junto con el package.json del perfil. Esos dos archivos reconstruyen el mismo árbol en un servidor nuevo. Ejecute dsh plugin --profile web update cuando haya decidido cambiar de versión, nunca como tarea rutinaria de limpieza, y revise después las diferencias del archivo de bloqueo.

Para un plugin instalado desde git en lugar de un registro, fije el commit y no la rama. Una especificación con el formato github:owner/repo#<full commit sha> proporciona un árbol fijo. Un nombre de rama proporciona lo que esa rama contenga la próxima vez que pnpm lo resuelva. Esa decisión queda entonces en manos de otra persona. El propio harness requiere la misma disciplina, porque cada compilación publicada de dsh es una candidata a versión y una instalación sin versión fijada puede resolver otra distinta cualquier día. De ahí proceden la mayoría de los errores de instalación y versión de dsh.

El mercado de plugins y el valor de que estén «seleccionados»

dsh tiene un mercado e instala sus componentes como plugins, lo que indica algo sobre su arquitectura:

dsh plugin --profile web add dshmarket

Después de reiniciar, aparece en Settings, en Plugin Market. Su README explica claramente las limitaciones. Las instalaciones están restringidas a las fuentes incluidas en un registro seleccionado, y cualquier otra fuente se rechaza. Los scripts de compilación están bloqueados de forma predeterminada, y habilitar uno requiere aprobación por paquete. Los plugins de terminal se marcan antes de incorporarse a un perfil web. La frase más importante indica que aparecer en la lista no constituye una recomendación, porque los plugins son código de terceros.

Una lista seleccionada eleva el nivel mínimo de seguridad. No analiza el código por usted y no puede decirle qué hará la siguiente versión de un plugin después de que una cuenta de mantenedor cambie de propietario. Trate una instalación con un solo clic como trataría curl | bash del mismo autor. Conviene repetir otra línea de ese README: una copia de seguridad exportada puede contener credenciales de la configuración de su perfil, por lo que nunca debe adjuntarla a un issue público ni a un sitio de pegado de texto. Si quiere una lista inicial en lugar de un método, plugins de dsh que vale la pena instalar es el artículo complementario de este.

Ejecute dsh con su propio usuario, no como root

La verificación reduce la frecuencia con la que entra algo malicioso. El principio de mínimo privilegio determina a qué puede acceder si consigue entrar. En un VPS, esta segunda parte es fácil de configurar.

Asigne al entorno su propia cuenta de Unix y su propio directorio personal. No lo ejecute nunca como root:

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

Dentro de esa sesión, inicie el entorno para que escriba su directorio personal con esa cuenta:

npx @deepseek-ai/dsh web

La interfaz web se sirve en http://127.0.0.1:3080 de forma predeterminada. Déjela ahí. Si alguna vez hizo clic desde otra máquina en el enlace mostrado y no obtuvo respuesta, en qué consiste esa dirección que dsh muestra explica el motivo. Cualquier sistema que llegue a ese puerto puede controlar un agente que tiene un shell. Por tanto, publicar 3080 equivale a publicar un shell remoto sin privilegios de root con una interfaz sencilla. Acceda desde su portátil mediante un túnel SSH:

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

Después, confirme que no hay ningún proceso escuchando en una dirección pública:

ss -lnt | grep 3080

La dirección local debe ser 127.0.0.1:3080. Si aparece 0.0.0.0:3080, el firewall es lo único que separa a un desconocido de su agente. El razonamiento de ejecutar Claude Code de forma segura en un VPS se aplica a dsh sin cambios. Asigne al agente un único directorio de trabajo que pueda modificar o eliminar, y mantenga fuera de esa máquina todo lo que no pueda reconstruir. Mejor aún, trate el sistema como una VM desechable para agentes de programación, porque reconstruir un VPS cuesta una hora, mientras que auditarlo cuesta una semana.

Dónde se almacenan las claves y por qué los permisos de archivo no bastan

dsh almacena las claves de API en $DSH_HOME/.credentials.yaml y los valores de entorno en $DSH_HOME/.env, y guarda la configuración de los modelos en $DSH_HOME/settings.yaml y el historial de sesiones en $DSH_HOME/storages. La clave que corresponde a cada archivo y lo que realmente sale del equipo en cada modo se explica en configurar las claves de API, los modelos y los endpoints de dsh. Conviene resolverlo antes de añadir un plugin, porque cada clave que se configura es otro dato que un plugin puede leer. Restrinja los permisos de los dos archivos sensibles:

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

El modo 600 permite al propietario leer y escribir, y no concede ningún permiso al resto. Esto es importante en ambas notaciones (modos numéricos y simbólicos de chmod). Hay que tener claro qué protección ofrece. Los modos de archivo protegen esos archivos frente a otras cuentas del equipo. No protegen frente a un plugin, porque el plugin se ejecuta como el usuario propietario de los archivos, dentro del proceso que los lee. Por eso, mantener los secretos fuera del alcance de un agente de IA significa no almacenarlos en el equipo. Un equipo con dsh debe contener sólo la clave del modelo que necesita. Las credenciales de la nube y las claves de firma deben almacenarse en otro lugar.

Por qué un plugin que lee la web cambia el modelo de amenazas

La interfaz Web proporciona a los plugins proveedores de búsqueda y descarga. Un plugin que carga una página en tu sesión está cargando texto que un atacante puede escribir. Un prompt de modelo no separa las instrucciones de los datos. Por tanto, una página descargada puede incluir una línea dirigida a tu agente, y un harness que tenga la capacidad de usar el shell está a un paso obediente de ejecutarla.

El control ya existe en el harness. dsh-base, el primer paquete de cada perfil, proporciona el sandbox y la política de aprobación. Úsalo. Una sesión que pueda descargar páginas no confiables debe requerir aprobación para cualquier operación que escriba o ejecute algo. Así, una instrucción descargada no puede convertirse por sí sola en una acción. Controlar las acciones del agente mediante aprobaciones explica cómo decidir dónde establecer ese límite. La relación también funciona en la otra dirección: tu propio servidor es una página que el agente de otra persona descargará. Ese es el caso de bloquear los rastreadores de IA en tu servidor.

¿Cómo compruebo qué cambió un plugin?

Cree una instantánea antes, instale el plugin, cree otra instantánea y lea las diferencias.

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

La diferencia muestra qué entradas del plugin añadió la instalación al árbol compuesto. Si instaló un plugin para una función pequeña y este añade varias entradas que no puede justificar, deténgase y lea el código fuente antes de iniciarlo. dsh plugin --profile web why <package-name> responde a la otra pregunta: cuál de sus dependencias directas incorporó un paquete determinado.

Los paquetes instalados se guardan en $DSH_HOME/profiles/node_modules, por lo que también puede consultar el árbol en el disco:

ls ~/.dsh/profiles/node_modules

Mantenga un segundo perfil en el que nunca haga pruebas. Si una instalación rompe el entorno de pruebas, iniciar dsh --profile <clean-name> le indica en segundos si el plugin fue la causa.

¿Cómo elimino un complemento de 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

Eliminar la dependencia no siempre elimina la configuración. Las entradas escritas en cordis.patch.yml del perfil permanecen porque ese archivo es suyo y el arnés no lo reescribe por usted. Ábralo y elimine cualquier bloque que indique el paquete que quitó.

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

Después, aborde la parte que ningún comando de desinstalación puede resolver. Si quitó un complemento porque dejó de confiar en él, todo lo que podía leer ya lo había leído. Rote la clave de API de DeepSeek en la consola del proveedor y rote cualquier otro dato que estuviera en $DSH_HOME. Después, determine a qué recursos del resto de la red podía acceder la cuenta de Unix con la que se ejecutaba.

La versión corta

  • Lea el tarball publicado antes de instalarlo, empezando por scripts y el archivo de entrada
  • Fije la versión exacta o el commit exacto para una especificación de git, y conserve el archivo de bloqueo
  • Instale en un solo perfil y conserve un perfil limpio que pueda iniciar cuando algo falle
  • Compare --dump-config antes y después de cada instalación
  • Ejecute el harness con su propio usuario de Unix, en loopback, y acceda a él mediante SSH
  • Mantenga una sola clave de API en el equipo y rótela el día que elimine un plugin en el que ya no confíe

Nada de esto es motivo para evitar los plugins. El modelo de plugins es la razón por la que dsh resulta útil, y un harness que no pueda ampliar será reemplazado. Es motivo para saber qué instaló, de quién procede y qué versión usa, y para ejecutar todo en un entorno que pueda reconstruir.

FAQ

¿dsh aísla entre sí los plugins?

No. Un plugin se carga en el proceso del harness mediante Cordis y puede acceder a las interfaces de capacidad documentadas, incluidos shell, filesystem, web, subprocess, subagent y credentials. dsh-base, el primer bundle de cada perfil, proporciona el sandbox y la política de aprobación que determinan lo que pueden hacer las herramientas del agente. Esa política es la que proporciona la protección. No existe un límite de permisos por plugin. Por tanto, el modelo correcto es que instalar un plugin extiende la confianza al autor y a todos los paquetes de su árbol de dependencias.

¿Puedo instalar un plugin de dsh sin ejecutar sus scripts de instalación?

pnpm 10 y las versiones posteriores bloquean de forma predeterminada los scripts de compilación de las dependencias, y dsh plugin ... add reenvía las operaciones a pnpm. Por tanto, en una versión actual de pnpm la instalación no ejecuta scripts de paquetes, salvo que apruebe ese paquete. Confirme la versión con pnpm --version. Esto no hace seguro un plugin que no haya revisado. El código propio del plugin se ejecuta en el siguiente arranque porque el harness lo carga de forma deliberada. Ninguna restricción aplicada durante la instalación afecta a ese comportamiento.

¿Dónde se encuentran realmente los plugins de dsh y su configuración?

$DSH_HOME usa ~/.dsh de forma predeterminada. Los perfiles se encuentran en $DSH_HOME/profiles/<name>. Cada uno contiene un package.json con sus dependencias de plugins, el manifiesto dsh.profile de bundles ordenados y una capa de parches cordis.patch.yml. Los paquetes instalados se guardan en $DSH_HOME/profiles/node_modules. Las claves se encuentran en $DSH_HOME/.credentials.yaml, los valores de entorno en $DSH_HOME/.env, y un $DSH_HOME/cordis.patch.yml del nivel de usuario se aplica a todos los perfiles. Ejecute dsh --profile web --dump-config para ver el resultado compuesto sin iniciar el sistema.

¿Es seguro instalar desde el mercado de plugins de dsh?

El mercado limita las instalaciones a fuentes de un registro seleccionado y bloquea los scripts de compilación salvo que los apruebe por paquete. Esto supone una mejora real frente a pegar el nombre de un paquete desde una ventana de chat. Su propio README sigue indicando que la inclusión en el listado no constituye una recomendación, porque los plugins son código de terceros creado por otras personas. Lea el código fuente y fije la versión. Mantenga el harness en una cuenta de usuario y, preferiblemente, en una máquina que pueda permitirse perder.