SSD Nodes Learn 🎉 VPS $5.50/月〜
ガイド Matt Connor著者 Matt Connor ・更新日 2026-08-21

dshプラグインの仕組みと安全性を確認する方法

dshプラグインはエージェントの権限でコードを実行します。Shell、Filesystem、Web、環境変数などへの到達範囲と、インストール前に確認すべき点を解説します。

dsh プラグインとは何か、何ができるのか

dsh プラグインは、DeepSeek Harness が自身のプロセスに読み込む Node パッケージです。プラグインをインストールすると、エージェントの権限を持つ別の作成者のコードが、エージェントから到達可能なマシン上で実行されます。読み込まれたプラグインと、ハーネスの他の部分との間に隔たりはありません。したがって、インストール前に確認すべきなのは、そのコードが何にアクセスできるか、そしてその範囲をどう小さく保つかです。

dsh (DeepSeek Harness) は、Cordis というプラグインフレームワーク上に構築された、DeepSeek AI のオープンソースのエージェントハーネスです。プロジェクト自身の README には、すべてがプラグインであると記載されています。モデルアダプターもプラグインです。入力に使う Web インターフェースもプラグインです。プロジェクト外からインストールしたものは、同じツリー内に、標準で組み込まれている部品と同じ信頼レベルで配置されます。まだ構築していない場合は、まず VPS 上の DeepSeek Harness を構築し、何かを追加する前にここへ戻ってください。

プラグインが利用できる拡張ポイントは、リポジトリの AGENTS.md に一覧化されています。2026 年 8 月時点では、次の範囲を対象としています。

  • LLM (大規模言語モデル): API キーで料金を支払うプロバイダー
  • Shell: bash 機能。local と pwsh のプロバイダーを使用
  • Filesystem: ポリシーで制御されるファイルアクセス
  • Web: 検索および取得のプロバイダー
  • Subprocess: プロセスツリーのプロバイダー
  • Workflow: ワーカースレッド
  • Subagent: 追加のエージェントへの委譲
  • Settings and credentials: 保存済みの設定と環境変数

プラグインは ctx.tools にツールも登録します。ドキュメントには、登録したツールのスキーマがプロンプトの組み立てに組み込まれると明記されています。見落とされやすいのは、この後半です。プラグイン自身のコードが通常と異なる動作をしなくても、プラグインが提供する説明文がモデルの読み取るテキストになるため、エージェントの判断を変えられます。これは コーディングエージェントに対するプロンプトインジェクション と同じ種類の問題です。ただし、こちらのテキストはインストール時に到着し、プラグインを削除するまで残ります。

dsh はどのようにプラグインを検出して読み込みますか?

グローバルなプラグインディレクトリはありません。実行中の dsh は、起動時に順序付けられたレイヤーから構成されるプラグインツリーです。選択内容を保持する単位がプロファイルです。$DSH_HOME のデフォルトは ~/.dsh で、各プロファイルは $DSH_HOME/profiles/<name> にあります。webheadless のプロファイルは、初回使用時に同梱テンプレートから自動的に作成されます。

プロファイルディレクトリには、すべてを決定する2つのファイルがあります。

  • package.json。ツリー外のプラグイン依存関係と、順序付けられた bundles リストを含む dsh.profile マニフェストを保持します
  • cordis.patch.yml。これらのバンドルに適用する独自のパッチレイヤーです
ls ~/.dsh
ls ~/.dsh/profiles/web

起動時にはレイヤーが次の順序で適用され、後のレイヤーが優先されます。

  1. 空のルート
  2. マニフェストに記載された順序で適用される、プロファイルのバンドル
  3. プロファイルの cordis.patch.yml
  4. $DSH_HOME/cordis.patch.yml
  5. コマンドラインで渡された --patch <path> オーバーレイ

次の2つのフラグを使うと、何も起動せずにこの構成結果を表示できます。

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

--dump-default-config は、構成済みツリーだけを表示します。--dump-config はプロファイルとホームのパッチレイヤーを追加するため、次回の起動で読み込まれる内容を最も正確に確認できます。引き継いだマシンを信頼する前に、この結果を確認してください。

これらのパッチファイルには注意が必要です。ここでは設定は単なるデータではありません。形式上、プラグインの config ブロック内に !!js タグ付きの値を記述できるためです。フォーラムの投稿からコピーした cordis.patch.yml スニペットはコードです。同じ投稿元のシェルスクリプトと同じように扱ってください。

dsh plugin addが実際に実行するもの

dsh plugin --profile <name> <args>は引数を、そのプロファイルのディレクトリ内で pnpm に転送します。そのため、pnpm が PATH に含まれている必要があります。動詞は 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

したがって、dsh プラグインをインストールする際のセキュリティモデルは、npm 形式の依存関係をインストールする場合のセキュリティモデルに加え、その結果をエージェントに読み込ませる追加の手順を含むものです。パッケージは独自の依存関係ツリーを持ち、そのツリー内のすべてのパッケージが同じプロセス内で実行されます。npm のサプライチェーン攻撃がサーバーに到達する仕組みに関する内容は、ここにもそのまま当てはまります。

pnpm 10 以降では、依存関係のビルドスクリプトはデフォルトで実行されません。実行の承認は、onlyBuiltDependenciesまたはpnpm approve-buildsでパッケージごとに行います。使用中の pnpm を確認してください。

pnpm --version

このデフォルト設定は有用ですが、エコシステム内で最も過大評価されている安全機能でもあります。ブロックされたビルドスクリプトは、インストール中のコード実行を停止します。しかし、プラグイン自体には何の対策にもなりません。プラグインの目的は、ハーネスがそれを import し、次回の起動時に呼び出すことだからです。プラグインに postinstall hook は必要ありません。プラグインは明示的に受け入れられているためです。

インストール前に dsh プラグインについて読むこと

公開されている tarball をダウンロードして読みます。アーカイブを展開しただけでは、何も実行されません。

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

その package.json にある 4 つのフィールドを確認すれば、必要な情報の大半が分かります。scriptspreinstallinstallpostinstall のエントリを確認します。見覚えのない名前や、知っている名前と 1 文字だけ異なる名前は dependencies で確認します。パッケージが PATH に追加しようとするものは bin で確認します。エントリーファイルは main または exports で確認し、そのファイルを開いて処理を追います。

次に、実際に読み込まれるコードを確認します。通知ツールを提供すると説明するプラグインが、~/.ssh を読み取ったり、聞いたことのないホストへ接続したり、シェルを起動したりする理由はありません。パッケージに同梱された、または minify された JavaScript しかなく、公開リポジトリに対応するソースがない場合は、それが判断材料になります。ソースを読めるプラグインを優先し、小規模なものを選びます。

インストールせずにレジストリを調べることもできます。

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

先週公開されたばかりで、バージョンが 1 つしかなく、repository フィールドがなく、人気のあるものと同じ名前を使っているパッケージは、どのレジストリにもある古典的な手口です。チェックサムでダウンロードを検証することも隣接する基本習慣です。実行を許可する前に、何を取得したのかを正確に把握します。

バージョンを固定し、ロックファイルを保持する

浮動するバージョン範囲では、判断しなくても、インストールや更新のたびに agent のプロセス内のコードが変わる可能性があります。バージョンを固定してください。

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

pnpm のバージョンによってフラグの位置は異なるため、コマンドを無条件に信頼せず、結果を確認してください。その後、profile の package.json を開き、依存関係が単独のバージョンとして記載され、先頭に ^~ が付いていないことを確認します。インストール内容を決めるのはこのファイルです。

次に、トップレベルの名前だけでなく、依存関係の完全なツリーを固定するロックファイルを保持します。

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

profile の package.json とともに、バックアップ先へコピーしてください。この2つのファイルがあれば、新しいマシンで同じツリーを再構築できます。バージョンを変更すると決めた場合にだけ dsh plugin --profile web update を実行し、定期的な整理のためには実行しないでください。その後、ロックファイルの差分を確認します。

レジストリではなく git からインストールする plugin では、ブランチではなくコミットを固定します。github:owner/repo#<full commit sha> 形式の指定にすると、ツリーを固定できます。ブランチ名を指定すると、次回 pnpm が解決した際に、そのブランチが保持している内容が使われます。これは別の人に判断を委ねることになります。harness 自体にも同じ管理が必要です。公開される dsh build はすべてリリース候補であり、固定していないインストールでは、日によって別のものが解決される可能性があります。これが、dsh のインストールとバージョンのエラーの大半の原因です。

プラグイン市場と「キュレーション」の価値

dsh にはマーケットプレイスがあり、プラグインとしてインストールされます。このことから、アーキテクチャの一端が分かります。

dsh plugin --profile web add dshmarket

再起動すると、Settings の Plugin Market に表示されます。README には制限事項が明記されています。インストール元はキュレーション済みレジストリに登録されたソースに限定され、それ以外は拒否されます。ビルドスクリプトはデフォルトでブロックされ、使用を有効にするにはパッケージごとの承認が必要です。ターミナルプラグインは、Web プロファイルに追加される前に警告が表示されます。最も重要なのは、プラグインがサードパーティー製コードであるため、掲載は推奨を意味しないという記述です。

キュレーション済みリストは最低限の安全水準を引き上げます。ただし、コードを代わりに確認してくれるわけではありません。また、メンテナーのアカウントが移管された後、プラグインの次のバージョンが何をするかを判断することもできません。ワンクリックインストールは、同じ作者による curl | bash と同じように扱ってください。README には、もう1つ繰り返す価値のある記述があります。エクスポートしたバックアップには、プロファイル設定の認証情報が含まれる場合があります。そのため、公開 issue や paste site に添付しないでください。手順ではなく、最初に導入するプラグインの一覧が必要なら、導入する価値のある dsh プラグイン がこの記事の補足記事です。

dsh を root ではなく専用ユーザーで実行する

審査によって、悪意のあるものが入り込む頻度を下げられます。最小権限によって、侵入された場合に到達できる範囲を制限できます。VPS では、この後半の対策を低コストで導入できます。

ハーネス専用の Unix アカウントと専用の home を用意し、root として実行しないでください。

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

そのセッション内でハーネスを起動し、そのアカウントの home にデータを書き込ませます。

npx @deepseek-ai/dsh web

Web UI はデフォルトで http://127.0.0.1:3080 で待ち受けます。その設定を維持してください。そのポートに到達できるものは、shell を持つ agent を操作できます。そのため、3080 を公開することは、使いやすいインターフェースを備えた root 権限なしのリモート shell を公開することと同じです。代わりに、SSH tunnel 経由で laptop から接続してください。

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

続いて、公開アドレスで待ち受けているものがないことを確認します。

ss -lnt | grep 3080

ローカルアドレスは 127.0.0.1:3080 になっているはずです。0.0.0.0:3080 になっている場合、見知らぬ第三者と agent の間にあるのは firewall だけです。VPS 上で Claude Code を安全に実行するための考え方は、そのまま dsh に適用できます。agent が自由に変更してよい workspace directory を 1 つだけ用意し、再構築できないものはそのマシンに置かないでください。さらに、ホストをcoding agent 用の使い捨て VMとして扱うのが望ましいです。VPS の再構築には 1 時間かかりますが、監査には 1 週間かかるためです。

鍵の保存場所と、ファイル権限だけでは不十分な理由

dsh は API key を $DSH_HOME/.credentials.yaml に、環境変数の値を $DSH_HOME/.env に保存し、モデル設定を $DSH_HOME/settings.yaml に、セッション履歴を $DSH_HOME/storages 以下に保存します。これらのファイルのどれにどの key を保存するか、また各モードで実際に何がマシンの外部へ送信されるかについては、dsh の API key、モデル、エンドポイントを設定するで説明しています。plugin を追加する前に、この点を決めておく必要があります。設定した key はそれぞれ、plugin が読み取れる情報になるためです。特に機密性の高い2つのファイルの権限を制限します。

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

モード 600 では、所有者に読み取りと書き込みを許可し、それ以外のユーザーには何も許可しません。この指定は、数値表記と記号表記の両方で理解しておくと便利です(数値形式と記号形式の chmod モード)。ただし、効果を過大評価してはいけません。ファイルモードで保護できるのは、同じマシン上の別のアカウントからです。plugin には効果がありません。plugin はファイルを所有するユーザーとして、ファイルを読み取るプロセス内で実行されるためです。そのため、AI agent の手の届かない場所に secret を保管するには、そもそもそれらをマシン上に置かないことが必要です。dsh を実行するマシンには、必要なモデルの key だけを置くべきです。cloud の credential と signing key は別の場所で管理します。

Web を読み取るプラグインが脅威モデルを変える理由

Web の接続面は、プラグインに検索プロバイダーと取得プロバイダーを提供します。ページをセッションに取り込むプラグインは、攻撃者が書き換えられるテキストを取り込むことになります。モデルのプロンプトは命令とデータを分離しないため、取得したページにエージェント宛ての行を含めることができます。shell の機能を保持するハーネスは、1 回従うだけでその命令を実行できてしまいます。

制御機能はすでにハーネスにあります。dsh-base は各プロファイルの最初のバンドルであり、sandbox と承認ポリシーを提供します。これを使用してください。信頼できないページを取得できるセッションでは、書き込みや実行を行う操作に承認を必須にします。これにより、取得した命令だけで操作が実行されることを防げます。エージェントの操作を承認で制御するでは、その境界をどこに設定するかについて説明しています。この関係は逆方向にも成り立ちます。自分のサーバーも、誰かのエージェントが取得するページだからです。これは 自分のサーバーで AI クローラーをブロックする場合にも当てはまります。

プラグインによる変更を確認するには

インストール前にスナップショットを取得し、インストール後にもう一度取得してから、差分を確認します。

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

差分には、インストールによってどのプラグインエントリが構成ツリーに追加されたかが表示されます。1 つの小さな機能のためにインストールしたプラグインが、説明できない複数のエントリを追加した場合は、起動する前にソースを確認してください。dsh plugin --profile web why <package-name> では、指定したパッケージをどの直接依存関係が取り込んだかという別の疑問に答えられます。

インストール済みパッケージは $DSH_HOME/profiles/node_modules 配下に配置されるため、ディスク上のツリーも確認できます。

ls ~/.dsh/profiles/node_modules

実験には使用しない 2 つ目のプロファイルを用意してください。インストールによってハーネスが動作しなくなった場合、dsh --profile <clean-name> を起動すれば、プラグインが原因かどうかを数秒で確認できます。

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

依存関係を削除しても、設定が常に削除されるとは限りません。プロファイルの cordis.patch.yml に書き込まれたエントリは、そのまま残ります。このファイルはユーザー自身が管理するものであり、harness が自動的に書き換えることはありません。ファイルを開き、削除したパッケージ名を含むブロックを削除してください。

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

次に、アンインストールコマンドでは解決できない点を確認します。信頼できなくなったためにプラグインを削除した場合、そのプラグインが読み取れた情報は、すでに読み取られている可能性があります。provider console で DeepSeek API key をローテーションし、$DSH_HOME に置かれていたその他の情報もローテーションしてください。そのうえで、プラグインが実行されていた unix アカウントから、ネットワーク上のどの範囲にアクセスできたかを確認します。

短くまとめると

  • インストール前に公開された tarball を確認します。scripts とエントリーファイルから読み始めます
  • 正確なバージョンを固定します。git spec の場合は正確な commit を固定し、lockfile を保持します
  • 1 つの profile にインストールします。問題が発生したときに起動できるクリーンな profile も保持します
  • インストールの前後で毎回 --dump-config を diff します
  • harness は専用の unix user として loopback 上で実行し、SSH 経由でアクセスします
  • API key はサーバー上に 1 つだけ保持します。信頼しなくなった plugin を削除した日にローテーションします

これは plugin を避ける理由にはなりません。plugin モデルが dsh を有用にしており、拡張できない harness はいずれ置き換えることになります。重要なのは、何を、誰から、どのバージョンでインストールしたかを把握し、全体を再構築できる環境で実行することです。

FAQ

dsh はプラグイン同士をサンドボックス化しますか?

いいえ。プラグインは Cordis を通じて harness プロセスに読み込まれ、shell、filesystem、web、subprocess、subagent、credentials など、文書化された機能境界にアクセスできます。dsh-base は各 profile の最初の bundle であり、agent のツールが実行できる操作を制御する sandbox と承認ポリシーを提供します。保護はこのポリシーによって実現されます。プラグインごとの権限境界はないため、プラグインをインストールすると、その作成者と依存関係ツリー内のすべてのパッケージを信頼することになります。

install script を実行せずに dsh プラグインをインストールできますか?

pnpm 10 以降では、依存パッケージの build script がデフォルトでブロックされます。dsh plugin ... add は pnpm に処理を引き渡すため、現在の pnpm では、パッケージを承認しない限り install 中に package script は実行されません。pnpm --version でバージョンを確認してください。ただし、これによって内容を確認していないプラグインが安全になるわけではありません。次回の boot では harness がプラグインを意図的に読み込むため、プラグイン自身のコードが実行されます。install 時の制限では、この実行を防げません。

dsh のプラグインと設定は実際にはどこにありますか?

$DSH_HOME のデフォルトは ~/.dsh です。profile は $DSH_HOME/profiles/<name> に配置されます。各 profile には、プラグインの依存関係を含む package.json、順序付けされた bundle の dsh.profile manifest、cordis.patch.yml の patch layer があります。インストール済みパッケージは $DSH_HOME/profiles/node_modules 配下に配置されます。key は $DSH_HOME/.credentials.yaml に、environment value は $DSH_HOME/.env にあります。また、home レベルの $DSH_HOME/cordis.patch.yml がすべての profile に適用されます。dsh --profile web --dump-config を実行すると、boot せずに統合後の結果を確認できます。

dsh plugin market からインストールしても安全ですか?

market では、厳選された registry にある source からのインストールに限定し、パッケージごとに承認しない限り build script をブロックします。これは、chat window からパッケージ名を貼り付けてインストールするよりも明らかに改善されています。ただし、market 自身の README にも、掲載は推奨を意味しないと記載されています。プラグインは第三者が作成したコードだからです。source を確認し、バージョンを固定してください。失っても問題ない user account、できれば machine 上で harness を実行してください。