dsh plugin hoạt động thế nào và cách kiểm tra
Cài dsh plugin là chạy code của người khác với quyền agent. Xem plugin có thể truy cập gì và checklist kiểm tra trước khi cài, tránh cấp quyền quá rộng.
dsh plugin là gì và có thể làm được gì?
dsh plugin là các Node package mà DeepSeek Harness tải vào process riêng của nó. Khi cài một plugin, bạn chạy code của người khác với quyền của agent, trên máy mà agent đã có thể truy cập. Không có lớp ngăn cách nào giữa plugin đã được tải và phần còn lại của harness. Vì vậy, trước khi cài một plugin, bạn cần hỏi code đó có thể chạm tới những gì và bạn sẽ giới hạn phạm vi đó như thế nào.
dsh (DeepSeek Harness) là agent harness mã nguồn mở của DeepSeek AI, được xây dựng trên một plugin framework có tên Cordis. Từ “plugin” ở đây rất quan trọng, vì agent harness là chương trình bao quanh model, quản lý vòng lặp, các tool và quyền hạn; plugin được gắn vào đúng lớp đó. README của dự án nêu rõ mọi thứ đều là plugin. Adapter của model là một plugin. Giao diện web mà bạn nhập lệnh vào cũng là một plugin. Bất kỳ thứ gì bạn cài từ bên ngoài dự án đều nằm trong cùng cây thành phần và có cùng mức độ tin cậy với các phần được phát hành kèm theo. Nếu bạn chưa triển khai dsh, hãy bắt đầu với DeepSeek Harness trên một VPS, rồi quay lại trước khi thêm bất kỳ thứ gì vào đó.
Các extension point mà plugin có thể truy cập được liệt kê trong AGENTS.md của repository. Tính đến tháng 8 năm 2026, chúng bao gồm:
- LLM (large language model): provider mà API key của bạn thanh toán
- Shell: khả năng bash, với các provider local và pwsh
- Filesystem: quyền truy cập file được kiểm soát bằng policy
- Web: các provider search và fetch
- Subprocess: provider quản lý cây process
- Workflow: các worker thread
- Subagent: ủy quyền cho các agent khác
- Settings và credentials: cấu hình đã lưu cùng các biến môi trường
Plugin cũng đăng ký các tool trên ctx.tools, và tài liệu nêu rõ schema của tool đã đăng ký sẽ được đưa vào quá trình lắp ráp prompt. Đây là phần mà nhiều người bỏ qua. Plugin có thể thay đổi quyết định của agent mà không cần code của chính nó làm điều gì bất thường, vì phần mô tả mà plugin cung cấp trở thành văn bản để model đọc. Đây là cùng dạng vấn đề với prompt injection nhằm vào coding agent, nhưng có một điểm khác: văn bản này xuất hiện khi bạn cài plugin và vẫn tồn tại cho đến khi bạn gỡ plugin.
dsh tìm và tải plugin như thế nào?
Không có thư mục plugin toàn cục. Một dsh đang chạy là một cây plugin được tạo khi boot từ các layer theo thứ tự. Đơn vị lưu các lựa chọn của bạn là profile. $DSH_HOME mặc định là ~/.dsh, và mỗi profile nằm trong $DSH_HOME/profiles/<name>. Các profile web và headless tự tạo trong lần đầu sử dụng từ các template được cung cấp.
Thư mục profile chứa 2 file quyết định toàn bộ cấu hình:
package.json, chứa các dependency của plugin ngoài cây chính cùng manifestdsh.profilelưu danh sáchbundlestheo thứ tựcordis.patch.yml, layer patch riêng của bạn áp dụng lên các bundle đó
ls ~/.dsh
ls ~/.dsh/profiles/webKhi boot, các layer được áp dụng theo thứ tự sau. Layer đứng sau sẽ ghi đè layer đứng trước:
- một root rỗng
- các bundle của profile, theo thứ tự trong manifest
cordis.patch.ymlcủa profile$DSH_HOME/cordis.patch.yml- mọi overlay
--patch <path>được truyền trên command line
Hai flag sau in ra kết quả composition mà không khởi động gì:
dsh --profile web --dump-default-config
dsh --profile web --dump-config--dump-default-config chỉ in riêng cây đã compose. --dump-config bổ sung các layer patch của profile và home. Đây là cách gần nhất để xem chính xác inventory của những gì lần boot tiếp theo sẽ tải. Hãy đọc nó trước khi tin cậy một máy chủ bạn được bàn giao.
Lưu ý về các file patch đó. Config ở đây không phải dữ liệu thụ động, vì format cho phép các giá trị được gắn tag !!js bên trong block config của plugin. Một đoạn cordis.patch.yml được copy từ bài đăng trên forum là code. Hãy xử lý nó như một shell script lấy từ cùng nguồn.
Thực tế dsh plugin add chạy gì?
dsh plugin --profile <name> <args> chuyển tiếp các đối số của nó cho pnpm bên trong thư mục của profile đó, vì vậy pnpm phải có trong PATH. Các verb là verb của 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 updateMô hình bảo mật khi cài đặt một dsh plugin vì thế là mô hình bảo mật của việc cài đặt bất kỳ dependency kiểu npm nào, cộng thêm một bước: kết quả được nạp vào agent của bạn. Package mang theo cây dependency riêng, và mọi package trong cây đó đều chạy trong cùng một process. Mọi nội dung trong cách các cuộc tấn công chuỗi cung ứng npm tiếp cận server đều áp dụng nguyên vẹn ở đây.
pnpm 10 trở lên không chạy build script của dependency theo mặc định. Việc phê duyệt được thực hiện theo từng package thông qua onlyBuiltDependencies hoặc pnpm approve-builds. Kiểm tra phiên bản pnpm đang dùng:
pnpm --versionMặc định này hữu ích, nhưng cũng là tính năng an toàn thường bị đánh giá quá cao trong hệ sinh thái này. Các build script bị chặn sẽ ngăn code chạy trong lúc cài đặt. Chúng không bảo vệ plugin, vì mục đích của plugin là để harness import nó và gọi nó trong lần boot tiếp theo. Plugin không cần hook postinstall. Bạn đã chủ động cho phép nó chạy.
Đọc gì trước khi cài plugin dsh
Hãy tải tarball đã được công bố và đọc nội dung của nó. Việc giải nén archive không thực thi gì cả.
npm pack '<package-name>@<version>'
tar -tzf '<package-name>-<version>.tgz'
tar -xzf '<package-name>-<version>.tgz'
less package/package.jsonBốn trường trong package.json cho bạn biết gần như mọi thông tin cần thiết. Đọc scripts để xem các mục preinstall, install và postinstall. Đọc dependencies để kiểm tra những tên bạn không nhận ra hoặc những tên chỉ khác tên quen thuộc một ký tự. Đọc bin để tìm mọi thứ mà package muốn có trong PATH của bạn. Đọc main hoặc exports để tìm file entry, sau đó mở file đó và lần theo nội dung.
Tiếp theo, hãy đọc code thực sự được load. Một plugin quảng bá công cụ notification không có lý do gì để đọc ~/.ssh, gọi đến một host bạn chưa từng nghe tới hoặc spawn shell. Nếu package chỉ cung cấp JavaScript đã được bundle hoặc minify mà không có source tương ứng trong một repository public, đó là câu trả lời của bạn. Ưu tiên các plugin có source mà bạn có thể đọc, và ưu tiên plugin nhỏ.
Bạn cũng có thể kiểm tra registry mà không cần cài đặt gì:
pnpm view '<package-name>' dependencies
pnpm view '<package-name>' versionsMột package được publish vào tuần trước, chỉ có một version, không có trường repository và có tên trùng hoặc gần giống một thứ phổ biến là thủ thuật cũ nhất trong mọi registry. Xác minh file tải xuống bằng checksum là thói quen cần có tiếp theo: phải biết chính xác bạn đã tải gì trước khi cho phép nó chạy.
Ghim phiên bản và giữ lockfile
Một khoảng phiên bản thả nổi có nghĩa là code bên trong tiến trình agent có thể thay đổi ở bất kỳ lần cài đặt hoặc cập nhật nào mà bạn không cần quyết định. Hãy ghim phiên bản.
dsh plugin --profile web add --save-exact '<package-name>@<version>'Vị trí của flag khác nhau giữa các phiên bản pnpm, vì vậy hãy kiểm tra kết quả thay vì tin hoàn toàn vào câu lệnh. Mở package.json của profile ngay sau đó và xác nhận dependency được ghi dưới dạng phiên bản thuần, không có ^ hoặc ~ ở trước. File đó quyết định những gì được cài đặt.
Sau đó giữ lockfile. File này ghim toàn bộ cây dependency bắc cầu, không chỉ tên dependency ở cấp cao nhất:
find ~/.dsh -maxdepth 3 -name 'pnpm-lock.yaml'Sao chép file này vào nơi bạn backup, cùng với package.json của profile. Hai file đó có thể dựng lại cùng một cây dependency trên máy mới. Chạy dsh plugin --profile web update khi bạn đã quyết định đổi phiên bản, không chạy như một bước dọn dẹp định kỳ, rồi đọc diff của lockfile.
Với plugin được cài từ git thay vì registry, hãy ghim commit thay vì branch. Spec có dạng github:owner/repo#<full commit sha> sẽ cho bạn một cây dependency cố định. Tên branch sẽ cung cấp bất kỳ nội dung nào branch đó có vào lần tiếp theo pnpm resolve, tức là bạn đã giao quyết định này cho người khác. Harness cũng cần tuân thủ nguyên tắc tương tự, vì mỗi bản build dsh được publish đều là một release candidate và một lần cài đặt không ghim phiên bản có thể resolve sang bản khác vào bất kỳ ngày nào. Đây là nguyên nhân của phần lớn lỗi cài đặt và phiên bản dsh.
Chợ plugin và giá trị thực sự của việc “curated”
dsh có một marketplace và được cài đặt dưới dạng plugin. Điều này cho thấy phần nào về kiến trúc của nó:
dsh plugin --profile web add dshmarketSau khi restart, plugin xuất hiện trong Settings, rồi đến Plugin Market. README của plugin nêu rõ các giới hạn. Việc cài đặt chỉ được phép từ những source có trong registry được curated; mọi source khác đều bị từ chối. Build script bị chặn theo mặc định. Muốn bật một build script, bạn phải phê duyệt riêng cho từng package. Plugin terminal sẽ bị đánh dấu trước khi được đưa vào web profile. Câu quan trọng nhất là việc được liệt kê không đồng nghĩa với được chứng thực, vì các plugin là code của bên thứ ba.
Danh sách được curated giúp nâng mức an toàn tối thiểu. Nhưng nó không đọc code thay bạn và cũng không thể cho biết phiên bản tiếp theo của một plugin sẽ làm gì sau khi tài khoản của maintainer đổi chủ. Hãy đối xử với việc cài đặt bằng một cú nhấp chuột giống như cách bạn đối xử với curl | bash từ cùng tác giả. Có một dòng khác trong README cũng đáng được nhắc lại: backup được export có thể chứa credential từ profile config của bạn. Vì vậy, không bao giờ đính kèm backup đó vào public issue hoặc paste site. Nếu bạn muốn có một danh sách khởi đầu thay vì một phương pháp, các plugin dsh đáng cài đặt là bài viết đi kèm với bài này.
Chạy dsh bằng user riêng, không chạy bằng root
Vetting làm giảm tần suất mối nguy xâm nhập. Least privilege quyết định mối nguy đó có thể chạm tới đâu khi đã lọt vào. Trên VPS, phần thứ hai này rất dễ thiết lập.
Tạo một tài khoản Unix riêng cho harness, có home riêng, và không bao giờ chạy harness bằng root:
sudo adduser --disabled-password --gecos "" dshrun
sudo -iu dshrunTrong session đó, khởi động harness để nó ghi dữ liệu vào home của tài khoản này:
npx @deepseek-ai/dsh webWeb UI mặc định chạy tại http://127.0.0.1:3080. Hãy giữ nguyên cấu hình này. Nếu bạn từng click vào link được in ra từ một máy khác nhưng không nhận được phản hồi, dsh muốn nói gì khi in ra địa chỉ đó sẽ giải thích nguyên nhân. Bất kỳ thứ gì truy cập được cổng đó đều có thể điều khiển một agent có shell. Vì vậy, public cổng 3080 tương đương với public một remote shell không có quyền root nhưng có giao diện dễ dùng. Hãy truy cập từ laptop qua SSH tunnel:
ssh -L 3080:127.0.0.1:3080 you@your-vpsSau đó xác nhận không có tiến trình nào listening trên địa chỉ public:
ss -lnt | grep 3080Địa chỉ local phải là 127.0.0.1:3080. Nếu là 0.0.0.0:3080, firewall là lớp duy nhất ngăn người lạ truy cập agent của bạn. Các nguyên tắc trong chạy Claude Code an toàn trên VPS cũng áp dụng nguyên vẹn cho dsh. Chỉ cấp cho agent một thư mục workspace mà nó được phép phá hỏng, và giữ mọi thứ bạn không thể rebuild ở ngoài máy đó. Tốt hơn nữa, hãy coi máy này là một VM dùng một lần cho coding agent, vì rebuild một VPS chỉ mất một giờ, còn audit một VPS có thể mất cả tuần.
Nơi lưu các key và lý do quyền file chỉ giúp được một phần
dsh lưu API key trong $DSH_HOME/.credentials.yaml và các giá trị môi trường trong $DSH_HOME/.env, còn thiết lập model nằm trong $DSH_HOME/settings.yaml và lịch sử session nằm dưới $DSH_HOME/storages. Key nào thuộc file nào trong số đó, và ở từng mode thực tế dữ liệu nào rời khỏi máy, được trình bày trong cấu hình API key, model và endpoint cho dsh. Bạn nên xác định rõ việc này trước khi thêm plugin, vì mỗi key bạn cấu hình là thêm một dữ liệu mà plugin có thể đọc. Hãy siết quyền cho 2 file nhạy cảm:
chmod 600 ~/.dsh/.credentials.yaml ~/.dsh/.env
ls -l ~/.dshMode 600 cho owner quyền đọc và ghi, còn mọi tài khoản khác không có quyền nào. Điều này hữu ích khi bạn cần hiểu cả 2 cách ghi quyền (chmod mode dạng số và dạng ký hiệu). Nhưng cần hiểu đúng giới hạn của nó. File mode bảo vệ các file đó khỏi những account khác trên máy. Chúng không ngăn được plugin, vì plugin chạy dưới user sở hữu các file này, bên trong process đọc chúng. Vì vậy, giữ secret ngoài tầm truy cập của AI agent có nghĩa là không đặt chúng trên máy ngay từ đầu. Một máy chạy dsh chỉ nên giữ model key cần thiết. Cloud credential và signing key của bạn nên được lưu ở nơi khác.
Vì sao plugin đọc web làm thay đổi mô hình mối đe dọa
Web seam cung cấp cho plugin các provider để tìm kiếm và fetch dữ liệu. Plugin đưa một trang vào session của bạn cũng đang đưa vào đó phần văn bản mà attacker có thể ghi. Prompt của model không tách instruction khỏi data, vì vậy một trang được fetch có thể chứa một dòng nhắm trực tiếp đến agent của bạn; khi harness có capability chạy shell, chỉ cần agent tuân theo một bước là lệnh sẽ được thực thi.
Cơ chế kiểm soát đã có sẵn trong harness. dsh-base, bundle đầu tiên trong mọi profile, cung cấp sandbox và approval policy. Hãy sử dụng nó. Session có thể fetch các trang không đáng tin cậy nên yêu cầu approval cho mọi thao tác ghi hoặc thực thi, để instruction lấy từ trang không thể tự biến thành action. Đặt action của agent sau bước approval giải thích cách xác định ranh giới này. Mối quan hệ này cũng có chiều ngược lại: server của bạn là một trang mà agent của người khác sẽ fetch. Đây là lý do cần chặn AI crawler trên server của bạn.
Làm thế nào để kiểm tra plugin đã thay đổi gì?
Tạo snapshot trước khi cài, cài đặt, tạo snapshot sau đó, rồi xem phần khác biệt.
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.txtDiff cho biết các entry nào của plugin được thêm vào composed tree trong quá trình cài đặt. Nếu một plugin được cài chỉ để dùng một tính năng nhỏ nhưng lại thêm nhiều entry mà bạn không giải thích được, hãy dừng lại và đọc source trước khi boot plugin đó. dsh plugin --profile web why <package-name> trả lời câu hỏi còn lại: dependency trực tiếp nào của bạn đã kéo một package cụ thể vào.
Các package đã cài nằm trong $DSH_HOME/profiles/node_modules, vì vậy bạn cũng có thể xem tree trên disk:
ls ~/.dsh/profiles/node_modulesHãy giữ một profile thứ hai và không dùng profile đó để thử nghiệm. Khi một lần cài đặt làm harness bị hỏng, boot dsh --profile <clean-name> sẽ cho bạn biết trong vài giây liệu plugin có gây ra lỗi hay không.
Cách gỡ một 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.txtGỡ dependency không phải lúc nào cũng xóa cấu hình. Các entry được ghi vào cordis.patch.yml của profile vẫn còn nguyên, vì đó là file của bạn và harness sẽ không tự viết lại. Mở file này rồi xóa mọi block có tên package bạn đã gỡ.
less ~/.dsh/profiles/web/cordis.patch.ymlTiếp theo, xử lý phần mà không lệnh uninstall nào có thể khắc phục. Nếu bạn gỡ plugin vì không còn tin cậy nó, thì bất cứ dữ liệu nào plugin có thể đọc, nó đã đọc rồi. Rotate DeepSeek API key trong provider console, đồng thời rotate mọi thông tin khác từng nằm trong $DSH_HOME. Sau đó xác định unix account mà plugin đã chạy bằng account đó có thể truy cập đến đâu trong phần còn lại của network.
Tóm tắt
- Đọc tarball đã phát hành trước khi cài đặt, bắt đầu từ
scriptsvà file entry - Pin chính xác version, hoặc commit chính xác đối với git spec, và giữ lại lockfile
- Cài đặt vào một profile, đồng thời giữ một profile sạch để có thể boot khi có lỗi
- Diff
--dump-configtrước và sau mỗi lần cài đặt - Chạy harness bằng một unix user riêng, trên loopback và truy cập qua SSH
- Chỉ giữ một API key trên máy, rồi rotate key vào ngày bạn gỡ plugin không còn tin cậy
Không điều nào trong số này có nghĩa là nên tránh plugin. Mô hình plugin là lý do dsh hữu ích, và một harness không thể mở rộng sẽ bị thay thế. Đây là lý do để biết bạn đã cài gì, từ ai, ở version nào, đồng thời chạy toàn bộ hệ thống ở nơi bạn có thể rebuild.
FAQ
dsh có sandbox các plugin với nhau không?
Không. Cordis tải plugin vào tiến trình harness, và plugin có thể truy cập các capability seam được tài liệu hóa, gồm shell, filesystem, web, subprocess, subagent và credentials. dsh-base, bundle đầu tiên trong mọi profile, cung cấp sandbox và chính sách phê duyệt quy định những gì các tool của agent được phép thực hiện. Đây là cơ chế bảo vệ bạn. Không có ranh giới quyền riêng cho từng plugin. Vì vậy, mô hình an toàn trung thực là: cài một plugin đồng nghĩa với việc bạn mở rộng mức độ tin cậy sang tác giả plugin và mọi package trong dependency tree của nó.
Có thể cài plugin dsh mà không chạy install script của nó không?
pnpm 10 trở lên mặc định chặn dependency build script, và dsh plugin ... add chuyển tiếp đến pnpm. Vì vậy, trên phiên bản pnpm hiện tại, quá trình cài đặt không chạy package script trừ khi bạn phê duyệt package đó. Xác nhận phiên bản bằng pnpm --version. Điều này không làm cho plugin chưa được đọc trở nên an toàn. Code riêng của plugin sẽ chạy ở lần boot tiếp theo vì harness chủ động tải plugin. Không có hạn chế nào trong thời điểm cài đặt ngăn được việc này.
Plugin dsh và config của chúng thực sự nằm ở đâu?
$DSH_HOME mặc định là ~/.dsh. Profile nằm trong $DSH_HOME/profiles/<name>. Mỗi profile chứa một package.json với các plugin dependency của nó, cùng manifest dsh.profile chứa các bundle theo thứ tự và một lớp patch cordis.patch.yml. Package đã cài nằm dưới $DSH_HOME/profiles/node_modules. Key nằm trong $DSH_HOME/.credentials.yaml, giá trị môi trường nằm trong $DSH_HOME/.env, và $DSH_HOME/cordis.patch.yml ở cấp home được áp dụng cho mọi profile. Chạy dsh --profile web --dump-config để xem kết quả đã ghép mà không cần boot.
Cài đặt từ market plugin dsh có an toàn không?
Market chỉ cho phép cài đặt từ các source trong registry được tuyển chọn và chặn build script trừ khi bạn phê duyệt từng package. Đây là cải thiện thực tế so với việc dán tên package từ một cửa sổ chat. Tuy nhiên, README của chính market vẫn nêu rõ rằng việc được liệt kê không đồng nghĩa với việc được chứng thực, vì plugin là code bên thứ ba do người khác viết. Hãy đọc source và pin phiên bản. Chạy harness bằng một user account, và tốt nhất là trên một máy mà bạn có thể chấp nhận bị mất.