Community程式設計與開發github.com

skill-vet — 代理技能

在安裝代理技能套件前進行審查,確保不包含竊取、監控或隱藏發送等惡意行為。靜態、唯讀、純 Python 實作。

skill-vet — 代理技能 是什麼?

skill-vet 是一款專為 AI 代理(如 Claude Code、Coder、Codex 等)設計的技能審查工具。在安裝來自信任圈外的技能套件(例如從市集下載、他人提供的儲存庫或客戶傳送的套件)之前,透過單一命令即可進行安全檢查。 該工具採用嚴格的靜態分析,純粹讀取套件中的檔案文字,絕不執行、匯入、編譯或 shell 調用任何內容,因此即使面對高度可疑的套件也安全無虞。其危險模型只針對三種行為:竊取憑證、未揭露的監控以及隱藏發送。每個危險判定都需要在同一檔案中同時具備兩種證據(例如讀取秘密+發送),並會明確指出檔案和行號。 支援的主要平台為任何可執行 Python 的環境(透過 pipx 或 pip 安裝)。JSON 輸出結構化、錯誤處理一致(無 traceback),適合整合到 CI/CD 管線或代理工作流程中。審查結果分為 BLOCKED(危險)、REVIEW(需人工檢視)和 CLEAN(乾淨),其中 REVIEW 預設不中斷流程,但有 --strict 選項可變更行為。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jasveerai88/skill-vet/tree/HEAD

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

skill-vet — 代理技能 是做什麼的?

在安裝代理技能套件前進行審查,只需一個命令。 當任務涉及來自此機器外部的技能——例如從市集下載、某人分享的儲存庫、客戶傳送的套件——在該套件被安裝到任何代理會載入的位置之前,請使用此工具。

單一命令

skill-vet vet <技能套件資料夾> [--json] [--strict]

(透過 pipx install skill-vet 或 pip install skill-vet 安裝。從原始碼目錄執行時,相同命令為 python3 src/skill_vet.py vet <技能套件資料夾> …。)

  • 參數是套件的根資料夾(包含 SKILL.md 的那個)。每次執行僅處理一個套件。
  • 退出碼:0 表示判定 CLEAN 或 REVIEW,1 表示判定 BLOCKED(或在 --strict 模式下為 REVIEW),2 表示輸入錯誤(資料夾不存在、不是資料夾、錯誤參數)。在 --json 模式下,每個錯誤(包括參數錯誤)都是一個帶有 error 鍵的 JSON 物件。絕不會出現 traceback。
  • 唯讀,且不執行任何內容。 Vet 以靜態文字讀取套件:永遠不會匯入、執行、shell 調用或求值套件中的任何內容。其原始碼不匯入任何網路或子程序模組。可以安全地指向一個你積極不信任的套件。

危險模型(完整產品)

一個套件僅當其執行以下三種行為之一時才被視為危險——擁有者的既定規則(2026-10-30),嚴格套用:

  1. 竊取(STEALS) —— 讀取憑證儲存、瀏覽器設定檔、SSH 金鑰或環境秘密,並將結果發送或複製出去。
  2. 監控(SPIES) —— 捕捉螢幕、鍵盤、麥克風、攝影機或瀏覽器歷史記錄,並持續儲存或發送捕捉內容,而文件未揭露該捕捉行為。
  3. 隱藏發送(SENDS IN SECRET) —— 網路呼叫,其負載或目的地被隱藏:編碼後的負載發送到未揭露的端點、本地檔案內容發送到未揭露的端點、結合了套件外寫入操作的發送,或者任何來自聲稱可離線運作之套件的發送。

單一模式命中本身並不構成危險判定。 每個測試都需要在同一檔案中有其組合的證據,且發現結果會引用兩部分的檔案和行號。任何未達組合標準的情況都會以警告形式呈現,並陳述證據。組合如下:

同一檔案中的證據判定
秘密讀取 + 發送,或秘密讀取 + 複製/移動到外部路徑DANGER_STEALING (BLOCKED)
捕捉 +(發送或持續儲存),捕捉類型未在 SKILL.md / README.md 中揭露DANGER_SPYING (BLOCKED)
發送 + 編碼負載,端點未揭露或非字面值DANGER_HIDDEN_SENDING (BLOCKED)
發送 + 讀取套件外檔案,端點未揭露DANGER_HIDDEN_SENDING (BLOCKED)
發送 + 寫入套件外,端點未揭露DANGER_HIDDEN_SENDING (BLOCKED)
發送 + 文件聲稱離線/僅本地DANGER_HIDDEN_SENDING (BLOCKED)
秘密讀取,檔案中無出口行為SECRET_ACCESS (WARN)
發送到文件中從未提及的端點,無隱藏組合UNDISCLOSED_NETWORK (WARN)
發送,無可檢查的字面 URLDYNAMIC_ENDPOINT (WARN)
編碼負載發送到已揭露的端點ENCODED_PAYLOAD (WARN)
捕捉 + 持續儲存/發送,捕捉已在文件中揭露DISCLOSED_CAPTURE (WARN)
捕捉,無持續儲存或發送CAPTURE_CAPABILITY (WARN)

明確說明的判斷要點:

  • 竊取無需隱藏:將憑證發送到已記錄的端點仍然是竊取——文件承認它並不會使之安全。揭露僅能區分監控和隱藏發送與其誠實的對應行為。
  • 在同一檔案中已被判定為 STEALING 出口部分的發送行為,不會再被重複計算為隱藏發送。
  • 捕捉的「揭露」會針對 SKILL.md / README.md 中的明文詞彙(如螢幕截圖、按鍵記錄、麥克風、網路攝影機、瀏覽器歷史記錄等)進行逐類檢查。捕捉並說明此行為的套件,是需知情接受的能力,而非監控。
  • 出口行為的組成要素會跨檔案的所有行(包括註解)收集(保守原則:即使能力證據位於註解附近,也不會被忽略)。衛生檢查(shell=True, eval, download-exec)會跳過全行註解——提及某模式只是文件說明,而非程式碼。

規則表

規則嚴重程度依據
MISSING_SKILL_MDERROR套件根目錄缺少 SKILL.md(名稱大小寫不同時會觸發 SKILL_MD_CASE,WARN,但仍會使用該檔案)。
FRONTMATTER_MISSINGERRORSKILL.md 沒有 --- 區塊。
FRONTMATTER_PARSEERROR前言的某行超出了支援的子集(見下文);會引用該行。
REQUIRED_FIELDERRORname 或 description 遺失或為空。
NAME_DIR_MISMATCHWARN標準化後的前言名稱 ≠ 資料夾名稱。
NAME_FORMATWARN名稱不是以小寫 kebab-case 格式的 slug。
BROAD_TOOL_GRANTWARNallowed-tools 項目包含 *、Tool(*) 萬用字元或裸 Bash。範圍限定的形式如 Bash(npm run *) 不會被標記。
BROKEN_REFERENCEERRORSKILL.md(markdown 連結或反引號路徑)或指令稿(路徑字面值)中引用的本地檔案不存在。解析時會先嘗試引用檔案所在的資料夾,再嘗試套件根目錄。
REFERENCE_OUTSIDE_PACKWARN引用解析到套件資料夾之外。
LARGE_FILEWARN檔案大小超過 1 MiB(1,048,576 位元組)。
BUNDLED_BINARYWARN二進位檔案(已知二進位副檔名,或前 8 KiB 包含 NUL 字節)。二進位檔案無法進行靜態審查。
SYMLINK_OUTINFO符號連結的目標指向套件外部;該目標不會被掃描。
DANGER_STEALINGERROR, 危險上述組合表。
DANGER_SPYINGERROR, 危險上述組合表。捕捉類型:螢幕、鍵盤、音訊、攝影機、歷史記錄(同一檔案中同時讀取歷史記錄儲存和資料庫)。
DANGER_HIDDEN_SENDINGERROR, 危險上述組合表。
SECRET_ACCESSWARN讀取憑證儲存/環境秘密,但同一檔案中無出口行為。秘密來源:.ssh / 金鑰檔案、.aws、.gnupg、.netrc、儲存的憑證檔案、瀏覽器儲存和設定檔資料夾、.env 檔案、命名秘密(TOKEN / SECRET / PASSWORD / API_KEY / …)的環境存取、整個環境的讀取。
UNDISCLOSED_NETWORKWARN網路呼叫的端點主機未出現在 SKILL.md 或 README.md 中。當主機(或其父網域)以 URL 形式出現在文件時,視為已揭露。
DYNAMIC_ENDPOINTWARN網路呼叫在檔案中沒有任何字面 URL。
ENCODED_PAYLOADWARN編碼器的輸出到達已揭露端點的發送。「到達」的判斷依據為:編碼器呼叫位於發送的呼叫段內,或來自編碼器、用於該段的變數賦值。
DISCLOSED_CAPTUREWARN捕捉 + 持續儲存/發送,已按類型揭露。
CAPTURE_CAPABILITYWARN捕捉 API,但檔案中無持續儲存或發送。
HYGIENE_SHELL_TRUEWARN程式碼行中存在 shell=True / shell: true。
HYGIENE_DYNAMIC_EXECWARN程式碼行中存在 eval( / exec( / os.system( / os.popen( / __import__(。
HYGIENE_DOWNLOAD_EXECWARN下載後 pipe 到 shell(`curl …
HYGIENE_OBFUSCATIONWARN文字檔案中存在 base64 區塊(120+ 字元,混合大小寫並包含數字或 +/)、十六進位區塊(120+ 字元)或連續 8+ 個 \xNN 跳脫序列。每種混淆方式每檔案一個發現。
CONCEALED_UNICODEWARN文字檔案中存在不可見字元(零寬度、單詞連接符、軟連字符、雙向控制字元、Unicode 標籤字元);會引用計數、首行和字元名稱。開頭的 BOM 是簽名而非隱藏,會被忽略。
CONCEALED_BLANK_RUNWARNmarkdown 檔案中出現 50+ 個連續空白行,且其後有內容。
HIDDEN_COMMENTWARNmarkdown 檔案中存在 120+ 字元的 HTML 註解。
WRITES_OUTSIDE_PACKWARN指令稿寫入絕對路徑、家目錄或系統路徑(/tmp、/etc、~/、$HOME 等)。
INSTALL_HOOKWARN安裝時會執行的檔案:setup.py、install.* / setup.sh、.pth 檔案,或包含 preinstall/install/postinstall hook 的 package.json。

判定:BLOCKED = 至少一個危險發現 → exit 1。REVIEW = 無危險,但至少一個 ERROR 或 WARN → exit 0(使用 --strict 時為 1)。CLEAN = 無 ERROR 或 WARN(INFO 可保留)→ exit 0。REVIEW 特意設為 exit 0,因為 REVIEW 意味著「應由人類閱讀」,而用於控制安裝的指令稿應在遇到危險時失敗,而非警告——--strict 則為不同意此觀點的人提供選項。

前言子集

解析器讀取技能套件實際使用的前言格式:key: value 純量(去除引號)、key: [a, b] 內聯列表、key: 後接 - item 區塊列表,以及縮排的續行會摺疊到前一個純量中。它刻意不是完整的 YAML 解析器。超出子集的行會產生帶有該行引用的 FRONTMATTER_PARSE 錯誤——vet 會報告它無法讀取的內容,而不是猜測。

掃描範圍

  • 套件中的每個檔案都會被列出大小。.git 和 __pycache__ 目錄會被跳過。
  • 文字掃描涵蓋指令稿(依副檔名或 shebang)、markdown 和其他文字檔案,每個檔案上限 2 MiB。二進位檔案和指向套件外部的符號連結目標只會列出,不會掃描。
  • 引用從 SKILL.md 和指令稿檔案中收集。其他 markdown 檔案內的引用(例如 references/*.md 連結到其他檔案)在 v1.0.0 中不會被追蹤。
  • 揭露僅針對套件根目錄的 SKILL.md 和 README.md 判斷——這是安裝該套件的人預期應已閱讀的兩個文件。

JSON schema (--json)

一個物件:

  • tool、version、command
  • pack:dir(傳入的路徑)、dirname、name(前言名稱或 null)、skill_file
  • files[]:path、bytes、kind(script|markdown|text|binary|other)、binary、scanned、symlink_out
  • findings[]:rule、severity(ERROR|WARN|INFO)、danger(布林值)、file(或 null)、line(或 null)、message、fix
  • summary:findings、errors、warnings、info、danger——這些計數應與 findings 完全一致
  • verdict(CLEAN|REVIEW|BLOCKED)、verdict_rule、limits

發現結果按確定性排序:先危險、再嚴重程度、檔案、行號、規則——相同的套件總是產生相同的報告。

刻意不達成的目標(誠實說明)

  • 永遠不執行任何內容。 不會執行、匯入、編譯或解析 shell 指令稿;不會解碼負載(編碼區塊會被報告,但不會被打開)。
  • 靜態模式是證據,而非證明。 一個在執行時從無害片段組合其行為、將組合分散到兩個檔案(vet 僅在單一檔案內判斷組合)、或以誠實的明文句子撰寫社交工程的套件,可以通過檢查。CLEAN 判定意味著沒有模式被觸發——README 如此說明,每個報告也是。
  • 二進位檔案超出範圍。 綑綁的二進位檔案會被標記,正是因為 vet 對它無從判斷。
  • 無遙測、無網路、無寫入。 僅使用標準庫;原始碼中完全沒有網路或子程序程式碼(測試會解析其匯入並證明)。
  • 模式表為快照。 新的捕捉函式庫、新的憑證儲存和新的客戶端 API 不斷出現;原始碼中的表格以版本發佈日期為準,而非視為完整。

相關技能