Plugin dsh: come funzionano e come verificarli
Un plugin dsh esegue codice di terze parti con i permessi dell'agent. Scopri a quali risorse accede e come valutarlo prima dell'installazione.
Che cos'è un plugin dsh e cosa può fare?
I plugin dsh sono pacchetti Node che DeepSeek Harness carica nel proprio processo. Installarne uno esegue codice di terze parti con le autorizzazioni del tuo agent, sulla macchina che l'agent può già raggiungere. Tra un plugin caricato e il resto dell'harness non c'è alcuna separazione. Prima di installarne uno, devi quindi chiederti a quali risorse può accedere quel codice e come limitare tale accesso.
dsh (DeepSeek Harness) è l'harness open source per agent di DeepSeek AI, basato su un framework per plugin chiamato Cordis. Il README del progetto dichiara che tutto è un plugin. L'adapter per il modello è un plugin. Anche l'interfaccia web in cui digiti è un plugin. Qualsiasi componente installato dall'esterno del progetto viene inserito nello stesso albero e allo stesso livello di attendibilità delle parti incluse nel progetto. Se non hai ancora configurato un'istanza, inizia da DeepSeek Harness su un VPS e torna qui prima di aggiungervi altro.
I punti di estensione a cui un plugin può accedere sono elencati nel AGENTS.md del repository. Ad agosto 2026 comprendono:
- LLM (large language model): il provider per il quale utilizzi la tua API key
- Shell: la funzionalità bash, con i provider local e pwsh
- Filesystem: accesso ai file controllato dalle policy
- Web: provider per la ricerca e il recupero dei contenuti
- Subprocess: un provider per l'albero dei processi
- Workflow: thread di lavoro
- Subagent: delega ad altri agent
- Settings and credentials: la configurazione salvata e le variabili d'ambiente
Un plugin registra inoltre strumenti su ctx.tools e la documentazione specifica che lo schema di uno strumento registrato viene incluso nell'assemblaggio del prompt. È questo il secondo aspetto che spesso viene trascurato. Un plugin può modificare ciò che l'agent decide di fare senza che il proprio codice esegua operazioni insolite, perché la descrizione fornita diventa testo che il modello legge. Il problema ha la stessa struttura di un prompt injection contro gli agent per il coding, con una differenza: questo testo arriva quando installi il plugin e rimane disponibile finché non lo rimuovi.
Come trova e carica i plugin dsh?
Non esiste una directory globale dei plugin. Un'istanza dsh in esecuzione è un albero di plugin composto all'avvio da livelli ordinati. L'unità che contiene le scelte dell'utente è un profilo. $DSH_HOME ha come valore predefinito ~/.dsh e ogni profilo si trova in $DSH_HOME/profiles/<name>. I profili web e headless vengono creati automaticamente al primo utilizzo a partire dai template forniti.
Una directory del profilo contiene due file che determinano l'intera composizione:
package.json, con le dipendenze dei plugin esterni all'albero e un manifestdsh.profilecontenente l'elenco ordinatobundlescordis.patch.yml, il proprio livello di patch applicato a quei bundle
ls ~/.dsh
ls ~/.dsh/profiles/webAll'avvio, i livelli vengono applicati in questo ordine. I livelli successivi hanno la precedenza:
- una radice vuota
- i bundle del profilo, nell'ordine indicato dal manifest
cordis.patch.ymldel profilo$DSH_HOME/cordis.patch.yml- eventuali overlay
--patch <path>passati sulla riga di comando
Due flag mostrano il risultato di questa composizione senza avviare nulla:
dsh --profile web --dump-default-config
dsh --profile web --dump-config--dump-default-config stampa da solo l'albero composto. --dump-config aggiunge i livelli di patch del profilo e della home directory. È quindi il comando più vicino a un inventario completo di ciò che verrà caricato al prossimo avvio. Consultalo prima di affidarti a una macchina ereditata.
È necessaria una precisazione sui file di patch. In questo caso la configurazione non è costituita soltanto da dati inerti, perché il formato consente valori con tag !!js nel blocco config di un plugin. Un frammento cordis.patch.yml copiato da un post del forum è codice. Trattalo quindi come tratteresti uno script shell proveniente dalla stessa fonte.
Che cosa esegue realmente dsh plugin add?
dsh plugin --profile <name> <args> inoltra i relativi argomenti a pnpm nella directory del profilo, quindi pnpm deve essere disponibile in PATH. I verbi sono quelli di 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 updateIl modello di sicurezza dell'installazione di un plugin dsh è quindi quello dell'installazione di qualsiasi dipendenza in stile npm, con un passaggio aggiuntivo: il risultato viene caricato nell'agent. Il pacchetto include il proprio albero delle dipendenze e ogni pacchetto dell'albero viene eseguito nello stesso processo. Tutto ciò che vale per come gli attacchi alla supply chain di npm raggiungono un server si applica anche in questo caso, senza modifiche.
pnpm 10 e versioni successive non eseguono per impostazione predefinita gli script di build delle dipendenze. L'approvazione è specifica per pacchetto e si gestisce tramite onlyBuiltDependencies o pnpm approve-builds. Verifica quale versione di pnpm è installata:
pnpm --versionQuesta impostazione predefinita è utile, ma è anche la funzionalità di sicurezza più spesso interpretata erroneamente nell'ecosistema. Gli script di build bloccati impediscono l'esecuzione di codice durante l'installazione. Non fanno nulla per il plugin in sé, perché lo scopo di un plugin è che l'harness lo importi e lo richiami al boot successivo. Un plugin non ha bisogno di un hook postinstall. È stato autorizzato a entrare.
Cosa leggere prima di installare un plugin dsh
Scarica il tarball pubblicato e leggilo. Quando decomprimi un archivio non viene eseguito nulla.
npm pack '<package-name>@<version>'
tar -tzf '<package-name>-<version>.tgz'
tar -xzf '<package-name>-<version>.tgz'
less package/package.jsonI quattro campi in package.json forniscono quasi tutte le informazioni necessarie. Leggi scripts per individuare le voci preinstall, install e postinstall. Leggi dependencies per i nomi che non riconosci o che differiscono di un carattere da nomi noti. Leggi bin per verificare cosa il pacchetto vuole trovare nel tuo PATH. Leggi main o exports per individuare il file di ingresso, quindi apri quel file e segui il flusso di esecuzione.
Poi leggi il codice che verrà effettivamente caricato. Un plugin che dichiara di fornire uno strumento per le notifiche non ha motivo di leggere ~/.ssh, contattare un host che non hai mai sentito nominare o avviare una shell. Se il pacchetto contiene soltanto JavaScript incluso o minificato e non esiste il relativo codice sorgente in un repository pubblico, hai già la risposta. Preferisci i plugin con codice sorgente leggibile e, possibilmente, di dimensioni ridotte.
Puoi anche interrogare il registry senza installare nulla:
pnpm view '<package-name>' dependencies
pnpm view '<package-name>' versionsUn pacchetto pubblicato la settimana scorsa, con una sola versione, senza un campo repository e con un nome che imita qualcosa di popolare è il trucco più vecchio di qualunque registry. Verificare i download con gli checksum è la pratica complementare: devi sapere esattamente cosa hai scaricato prima di consentirne l'esecuzione.
Blocca la versione e conserva il lockfile
Un intervallo di versioni mobile significa che il codice eseguito dal processo del tuo agent può cambiare durante qualsiasi installazione o aggiornamento, senza che tu abbia deciso di farlo. Blocca la versione.
dsh plugin --profile web add --save-exact '<package-name>@<version>'La posizione dei flag varia tra le versioni di pnpm. Controlla quindi il risultato invece di fidarti del comando. Apri il file package.json del profilo e verifica che la dipendenza sia indicata come versione semplice, senza ^ o ~ davanti. È quel file a determinare cosa viene installato.
Conserva poi il lockfile, che blocca l'intero albero delle dipendenze transitive e non soltanto il nome di primo livello:
find ~/.dsh -maxdepth 3 -name 'pnpm-lock.yaml'Copialo in una posizione inclusa nei backup, insieme al file package.json del profilo. Questi due file ricostruiscono lo stesso albero su un nuovo server. Esegui dsh plugin --profile web update solo quando hai deciso di cambiare versione, mai come operazione ordinaria di riordino, quindi esamina il diff del lockfile.
Per un plugin installato da git anziché da un registry, blocca il commit invece del branch. Una specifica nella forma github:owner/repo#<full commit sha> fornisce un albero fisso. Un nome di branch utilizza il contenuto disponibile in quel branch alla successiva risoluzione da parte di pnpm. In questo modo la decisione viene delegata a un soggetto esterno. Anche l'harness richiede la stessa disciplina, perché ogni build pubblicata di dsh è una release candidate e un'installazione senza versione bloccata può risolvere una build diversa in qualsiasi giorno. È questa la causa della maggior parte degli errori di installazione e versione di dsh.
Il mercato dei plugin e il valore della «curatela»
dsh dispone di un marketplace e viene installato come plugin. Questo fornisce un'indicazione sull'architettura:
dsh plugin --profile web add dshmarketDopo un riavvio, compare in Settings, quindi in Plugin Market. Il relativo README descrive chiaramente i limiti. Le installazioni sono consentite soltanto per le sorgenti elencate in un registro curato; tutto il resto viene rifiutato. Gli script di compilazione sono bloccati per impostazione predefinita e per abilitarli è necessaria un'approvazione per ogni pacchetto. I plugin per il terminale vengono segnalati prima di essere inseriti in un profilo web. La frase più importante specifica che la presenza nel registro non costituisce un'approvazione, perché i plugin sono codice di terze parti.
Un elenco curato innalza il livello minimo di sicurezza. Non analizza il codice al posto tuo e non può dirti che cosa farà la versione successiva di un plugin dopo un cambio di titolarità dell'account del maintainer. Considera un'installazione con un clic come considereresti curl | bash dello stesso autore. Vale la pena ripetere un'altra riga di quel README: un backup esportato può contenere credenziali provenienti dalla configurazione del tuo profilo; non allegarlo quindi a una issue pubblica o a un sito di paste. Se vuoi un elenco iniziale anziché un metodo, plugin dsh che vale la pena installare è l'articolo complementare a questo.
Esegui dsh con un utente dedicato, non come root
La verifica riduce la frequenza con cui entra qualcosa di dannoso. Il principio del privilegio minimo stabilisce invece cosa può raggiungere quando accade. Su un VPS, applicare questa seconda misura richiede poco lavoro.
Assegna all’harness un account Unix dedicato con una home propria e non eseguirlo mai come root:
sudo adduser --disabled-password --gecos "" dshrun
sudo -iu dshrunAll’interno di quella sessione, avvia l’harness in modo che utilizzi la home di quell’account:
npx @deepseek-ai/dsh webPer impostazione predefinita, l’interfaccia web è disponibile su http://127.0.0.1:3080. Lasciala su quell’indirizzo. Chiunque raggiunga quella porta può controllare un agent dotato di shell; pubblicare la porta 3080 equivale quindi a pubblicare una shell remota senza privilegi root, con un’interfaccia semplice da usare. Raggiungila dal laptop tramite un tunnel SSH:
ssh -L 3080:127.0.0.1:3080 you@your-vpsVerifica quindi che non ci siano processi in ascolto su un indirizzo pubblico:
ss -lnt | grep 3080L’indirizzo locale dovrebbe essere 127.0.0.1:3080. Se viene visualizzato 0.0.0.0:3080, il firewall è l’unica barriera tra un estraneo e il tuo agent. Il ragionamento alla base di eseguire Claude Code in sicurezza su un VPS si applica senza modifiche a dsh. Assegna all’agent una sola directory di lavoro che possa modificare o eliminare e mantieni fuori da quel computer tutto ciò che non puoi ricreare. Meglio ancora, tratta il sistema come una VM usa e getta per gli agent di coding, perché ricreare un VPS richiede un’ora, mentre controllarlo dopo un incidente può richiedere una settimana.
Dove vengono memorizzate le chiavi e perché i permessi dei file non bastano
dsh conserva le chiavi API in $DSH_HOME/.credentials.yaml e i valori dell'ambiente in $DSH_HOME/.env, mentre le impostazioni dei modelli si trovano in $DSH_HOME/settings.yaml e la cronologia delle sessioni in $DSH_HOME/storages. Quale chiave debba essere inserita in ciascuno di questi file e quali dati vengano effettivamente inviati all'esterno in ogni modalità è spiegato in configurare le chiavi API, i modelli e gli endpoint di dsh. È opportuno chiarire questo aspetto prima di aggiungere un plugin, perché ogni chiave configurata è un'ulteriore informazione che un plugin può leggere. Proteggi in modo rigoroso i due file sensibili:
chmod 600 ~/.dsh/.credentials.yaml ~/.dsh/.env
ls -l ~/.dshLa modalità 600 concede al proprietario i permessi di lettura e scrittura e nega qualsiasi permesso agli altri. È utile conoscere questa impostazione in entrambe le notazioni (modalità chmod numeriche e simboliche). Occorre però considerare con precisione cosa protegge. I permessi dei file impediscono agli altri account del server di accedere a quei file. Non proteggono da un plugin, perché il plugin viene eseguito dall'utente proprietario dei file, all'interno del processo che li legge. Per questo tenere i secret fuori dalla portata di un agente AI significa non conservarli affatto sulla macchina. Un server dsh dovrebbe contenere soltanto la chiave del modello necessaria. Le credenziali cloud e le chiavi di firma devono essere conservate altrove.
Perché un plugin che legge il Web modifica il modello delle minacce
L’interfaccia Web fornisce ai plugin provider per la ricerca e il recupero dei contenuti. Un plugin che importa una pagina nella sessione importa testo che può essere scritto da un attaccante. Il prompt del modello non separa le istruzioni dai dati. Una pagina recuperata può quindi contenere una riga indirizzata al tuo agente, mentre un harness con accesso alla shell è a un solo passaggio dall’esecuzione di quel comando.
Il controllo esiste già nell’harness. dsh-base, il primo bundle di ogni profilo, fornisce il sandbox e i criteri di approvazione. Usalo. Una sessione che può recuperare pagine non attendibili dovrebbe richiedere l’approvazione per qualsiasi operazione di scrittura o esecuzione. In questo modo, un’istruzione recuperata non può trasformarsi autonomamente in un’azione. Gestire le azioni dell’agente tramite approvazioni spiega come stabilire il punto in cui applicare questo limite. La relazione vale anche nella direzione opposta: il tuo server è una pagina che l’agente di qualcun altro recupererà. Questo è il caso di bloccare i crawler AI sul tuo server.
Come verifico che cosa ha modificato un plugin?
Create uno snapshot prima dell’installazione, installate il plugin, create un secondo snapshot e quindi confrontate le differenze.
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.txtIl diff mostra quali voci del plugin sono state aggiunte all’albero composto. Se avete installato un plugin per una singola funzionalità e questo aggiunge diverse voci che non riuscite a giustificare, fermatevi e leggete il codice sorgente prima di avviarlo. dsh plugin --profile web why <package-name> risponde all’altra domanda: quale dipendenza diretta ha introdotto un determinato pacchetto.
I pacchetti installati vengono salvati in $DSH_HOME/profiles/node_modules, quindi potete esaminare anche l’albero sul disco:
ls ~/.dsh/profiles/node_modulesMantenete un secondo profilo in cui non eseguite mai esperimenti. Se un’installazione danneggia l’harness, avviare dsh --profile <clean-name> indica in pochi secondi se la causa è il plugin.
Come rimuovo 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.txtLa rimozione della dipendenza non elimina sempre la configurazione. Le voci scritte nel file cordis.patch.yml del profilo restano al loro posto, perché quel file è di tua proprietà e l'harness non lo riscrive automaticamente. Apri il file ed elimina ogni blocco che indica il pacchetto rimosso.
less ~/.dsh/profiles/web/cordis.patch.ymlPoi devi gestire l'aspetto che nessun comando di disinstallazione può correggere. Se hai rimosso un plugin perché non ti fidavi più di esso, tutto ciò che poteva leggere è già stato letto. Ruota la chiave API di DeepSeek nella console del provider e ruota anche qualsiasi altro secret presente in $DSH_HOME. Verifica quindi a quali risorse del resto della rete poteva accedere l'account Unix con cui il plugin veniva eseguito.
La versione breve
- Leggere il tarball pubblicato prima dell'installazione, iniziando da
scriptse dal file di ingresso - Fissare la versione esatta oppure il commit esatto per una specifica git e conservare il lockfile
- Installare in un unico profilo e mantenere un profilo pulito, che sia possibile avviare quando qualcosa si rompe
- Confrontare
--dump-configprima e dopo ogni installazione - Eseguire l'harness con un utente Unix dedicato, sull'interfaccia di loopback, e raggiungerlo tramite SSH
- Conservare una sola chiave API sul server e ruotarla il giorno in cui si rimuove un plugin di cui non ci si fida più
Niente di tutto questo è un motivo per evitare i plugin. Il modello a plugin è il motivo per cui dsh è utile, e un harness che non è possibile estendere è un harness che prima o poi dovrete sostituire. È un motivo per sapere che cosa è stato installato, da chi e in quale versione, e per eseguire l'intero sistema in un ambiente che sia possibile ricostruire.
FAQ
I plugin di dsh sono isolati tra loro?
No. Un plugin viene caricato nel processo harness tramite Cordis e può raggiungere le interfacce di capacità documentate, tra cui shell, filesystem, web, subprocess, subagent e credentials. dsh-base, il primo bundle di ogni profilo, fornisce la sandbox e la policy di approvazione che stabilisce cosa possono fare gli strumenti dell'agente; è questa policy a fornire la protezione. Non esiste un limite di autorizzazioni specifico per plugin. Il modello corretto è quindi considerare l'installazione di un plugin come un'estensione della fiducia all'autore e a ogni pacchetto incluso nel relativo albero delle dipendenze.
Posso installare un plugin dsh senza eseguire gli script di installazione?
pnpm 10 e versioni successive bloccano per impostazione predefinita gli script di build delle dipendenze e dsh plugin ... add inoltra le richieste a pnpm. Con una versione aggiornata di pnpm, quindi, l'installazione non esegue gli script dei pacchetti finché non autorizzi il pacchetto interessato. Verifica la versione con pnpm --version. Questo non rende sicuro un plugin non esaminato. Il codice del plugin viene eseguito al boot successivo perché l'harness lo carica deliberatamente; nessuna restrizione applicata durante l'installazione può impedirlo.
Dove si trovano realmente i plugin dsh e la relativa configurazione?
Per impostazione predefinita, $DSH_HOME usa ~/.dsh. I profili si trovano in $DSH_HOME/profiles/<name>. Ogni profilo contiene un package.json con le dipendenze dei plugin, il manifest dsh.profile dei bundle ordinati e un livello di patch cordis.patch.yml. I pacchetti installati vengono salvati in $DSH_HOME/profiles/node_modules. Le chiavi si trovano in $DSH_HOME/.credentials.yaml, i valori dell'ambiente in $DSH_HOME/.env e un $DSH_HOME/cordis.patch.yml a livello home viene applicato a ogni profilo. Esegui dsh --profile web --dump-config per visualizzare il risultato composto senza eseguire il boot.
È sicuro installare plugin dal mercato di dsh?
Il mercato limita le installazioni alle sorgenti presenti in un registry selezionato e blocca gli script di build finché non li autorizzi per il singolo pacchetto. È un miglioramento concreto rispetto all'incollare il nome di un pacchetto copiato da una chat. Il README del mercato specifica comunque che la pubblicazione non costituisce un'approvazione, perché i plugin sono codice di terze parti sviluppato da altri autori. Esamina il codice sorgente e blocca la versione. Esegui l'harness con un account utente e, idealmente, su una macchina che puoi permetterti di perdere.