限、安全與供應(yīng)鏈治理)
1. 從一次真實(shí)的 Plugin 事故說(shuō)起Claude Code 的 Marketplace 機(jī)制讓第三方 Plugin 可以注入 Skills、Commands、Agents、Hooks、MCP Servers、LSP Servers 和 Scripts。能力能被加載不代表能力應(yīng)該被無(wú)條件信任。一個(gè) Plugin 可能只是提供代碼規(guī)范和文檔也可能攜帶可執(zhí)行 Shell 腳本、自動(dòng)觸發(fā)的 Hook、遠(yuǎn)程 MCP Server、本地 MCP 進(jìn)程、具有工具權(quán)限的 Skill、擁有獨(dú)立執(zhí)行循環(huán)的 Agent。我見(jiàn)過(guò)一個(gè)團(tuán)隊(duì)在內(nèi)部倉(cāng)庫(kù)里提交了.claude/settings.json里面聲明了enabledPlugins和extraKnownMarketplaces。新成員 Clone 倉(cāng)庫(kù)后Claude Code 提示安裝 Plugin成員點(diǎn)了確認(rèn)Plugin 里的 PostToolUse Hook 就開(kāi)始在每次 Write/Edit 后自動(dòng)執(zhí)行一個(gè)上傳腳本。沒(méi)有人顯式調(diào)用過(guò)這個(gè) Hook它只是在生命周期事件里被觸發(fā)。問(wèn)題不在于這個(gè) Plugin 本身惡意而在于團(tuán)隊(duì)沒(méi)有在落地前審查權(quán)限邊界。這篇文章面向的是準(zhǔn)備在團(tuán)隊(duì)里落地 Claude Code Marketplace 的工程師和平臺(tái)負(fù)責(zé)人。我會(huì)給出一份可復(fù)制的settings.json權(quán)限骨架一份供應(yīng)鏈校驗(yàn)清單以及逐步驗(yàn)證動(dòng)作幫你確認(rèn)配置生效、風(fēng)險(xiǎn)收斂。核心檢索詞是 Claude Code 權(quán)限、安全、供應(yīng)鏈治理、Marketplace。適合誰(shuí)正在評(píng)估第三方 Plugin 引入流程的團(tuán)隊(duì)、需要給 Claude Code 建立企業(yè)級(jí)來(lái)源控制的平臺(tái)工程師、以及想搞清楚 Skill allowed-tools 和 Hook 到底能做什么的開(kāi)發(fā)者。2. 落地前的 TaoToken 前置準(zhǔn)備在開(kāi)始配置權(quán)限骨架之前你需要一個(gè)穩(wěn)定的模型接入點(diǎn)來(lái)驗(yàn)證配置是否生效。TaoToken 提供 Claude Code 兼容的 API 接入官網(wǎng)地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端點(diǎn)是 https://taotoken.net/api 。如果你只是想在本地驗(yàn)證權(quán)限配置和 Skill 行為用模型對(duì)話就夠了https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。如果你要長(zhǎng)期跑編碼任務(wù)或 Agent 循環(huán)Coding Plan 更合適https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。接入文檔在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite API Keys 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。拿到 Key 之后你可以在 Claude Code 的配置里指向這個(gè)端點(diǎn)然后用它來(lái)測(cè)試 Skill 的 allowed-tools 是否按預(yù)期生效、Hook 是否在正確的生命周期觸發(fā)、MCP Tool 的權(quán)限規(guī)則是否被正確裁決。這一步的意義是你有一個(gè)可控的模型后端可以在不引入額外變量的情況下單獨(dú)驗(yàn)證權(quán)限配置的行為。3. 可復(fù)制的 settings.json 權(quán)限骨架下面這份骨架覆蓋了來(lái)源控制、Plugin 信任、Skill 權(quán)限、Hook 限制和 MCP Tool 治理五個(gè)層面。你可以直接復(fù)制到項(xiàng)目的.claude/settings.json或用戶級(jí)的~/.claude/settings.json然后按團(tuán)隊(duì)實(shí)際情況調(diào)整。3.1 來(lái)源控制strictKnownMarketplaces 與 disableSideloadFlags企業(yè)級(jí)來(lái)源控制的核心是strictKnownMarketplaces。它有三種狀態(tài)未配置時(shí)用戶可以添加任意 Marketplace空數(shù)組[]禁止添加所有 Marketplace來(lái)源列表則只允許精確匹配的來(lái)源。{ strictKnownMarketplaces: [ { source: github, repo: acme-corp/approved-plugins, ref: v2.0 } ], disableSideloadFlags: true }這里有幾個(gè)關(guān)鍵點(diǎn)。第一ref固定到具體 Tag 或 Commit SHA避免main分支內(nèi)容變化導(dǎo)致供應(yīng)鏈漂移。第二disableSideloadFlags阻止用戶通過(guò)單次 CLI 參數(shù)直接加載 Plugin 目錄、Agent 或臨時(shí) MCP Server。第三Claude Code 會(huì)在 Marketplace 添加、Plugin 安裝、更新、刷新和自動(dòng)更新之前執(zhí)行校驗(yàn)而且 Managed Settings 不能被用戶或項(xiàng)目覆蓋。精確匹配意味著github.com/company/plugins、github.com/company/pluginsv2、github.com/company/plugins/path-a被視為不同來(lái)源。URL 尾部斜杠、.git后綴以及 SSH/HTTPS 形式也可能被視為不同來(lái)源。信任一個(gè)倉(cāng)庫(kù)不等于信任倉(cāng)庫(kù)中的所有 Branch、Tag 和子目錄。3.2 Plugin 信任extraKnownMarketplaces 與 enabledPluginsextraKnownMarketplaces用于向用戶推薦 Marketplace但它不是安全邊界。它解決的是分發(fā)便利性不是來(lái)源封鎖。{ extraKnownMarketplaces: { company-tools: { source: { source: github, repo: acme-corp/approved-plugins, ref: v2.0 } } }, enabledPlugins: { security-reviewcompany-tools: true, audit-hookscompany-tools: true } }項(xiàng)目可以在.claude/settings.json中聲明enabledPlugins但這不意味著其他團(tuán)隊(duì)成員拉取倉(cāng)庫(kù)后 Plugin 會(huì)在沒(méi)有確認(rèn)的情況下直接運(yùn)行。Claude Code 要求每條 Plugin 加載路徑都先讓用戶安裝并信任 Plugin。項(xiàng)目設(shè)置只能表達(dá)項(xiàng)目期望狀態(tài)不能替每個(gè)用戶完成信任決策。完整流程是項(xiàng)目聲明 Plugin用戶打開(kāi)倉(cāng)庫(kù)接受 Workspace TrustClaude Code 發(fā)現(xiàn)缺少 Marketplace 或 Plugin向用戶展示安裝和信任提示用戶確認(rèn)Plugin 才進(jìn)入本地 Cache 和 Runtime。這阻止了惡意倉(cāng)庫(kù)提交.claude/settings.json后受害者 Clone 倉(cāng)庫(kù)導(dǎo)致 Plugin 靜默安裝并執(zhí)行的攻擊路徑。3.3 Skill 權(quán)限allowed-tools 與 disallowed-toolsSkill 通過(guò) Frontmatter 聲明allowed-tools和disallowed-tools。allowed-tools的作用不是新增底層工具而是讓指定工具在 Skill 被調(diào)用的當(dāng)前 Turn 中無(wú)需重復(fù)請(qǐng)求用戶批準(zhǔn)。--- name: commit description: Stage and commit current changes disable-model-invocation: true allowed-tools: - Bash(git status *) - Bash(git add *) - Bash(git commit *) disallowed-tools: - Write - Edit --- Review the current changes and create a commit.關(guān)鍵特點(diǎn)只在調(diào)用 Skill 的當(dāng)前 Turn 生效下一條用戶消息后清除沒(méi)有列出的工具仍受普通 Permission Settings 管理不會(huì)刪除或隱藏其他工具。權(quán)限計(jì)算可以理解為Skill Temporary Grant ∩ Harness Permission Policy ∩ Sandbox Boundary 最終有效能力。對(duì)于需要運(yùn)行自己目錄內(nèi)腳本的 Skill使用${CLAUDE_SKILL_DIR}做精確授權(quán)allowed-tools: - Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)這比Bash(*)安全得多因?yàn)樗活A(yù)批準(zhǔn)特定腳本而不是整個(gè) Shell。3.4 Hook 限制allowManagedHooksOnly 與 HTTP Hook AllowlistHook 由生命周期事件自動(dòng)觸發(fā)包括 SessionStart、PreToolUse、PostToolUse、Stop、SubagentStart、ConfigChange。它可以執(zhí)行 Shell Command、HTTP Request、LLM Prompt、Agent、MCP Tool。因此 Hook 更接近運(yùn)行時(shí) Middleware而不是普通上下文說(shuō)明。{ allowManagedHooksOnly: true, allowedHttpHookUrls: [ https://audit.acme-corp.com/hooks/* ], httpHookAllowedEnvVars: [ AUDIT_TOKEN ] }allowManagedHooksOnly阻止用戶、項(xiàng)目和普通 Plugin Hook只保留 Managed Hook。由 Managed Settings 強(qiáng)制啟用的 Plugin其 Hook 可以作為已審查企業(yè)能力繼續(xù)運(yùn)行。allowedHttpHookUrls和httpHookAllowedEnvVars分別限制 Hook 可以訪問(wèn)哪些 URL、哪些環(huán)境變量允許插入 Header。這些 Allowlist 會(huì)作用于所有來(lái)源的 HTTP Hook包括 Managed Policy。3.5 MCP Tool 治理命名空間與權(quán)限規(guī)則Plugin MCP Tool 使用完整命名空間mcp__plugin_plugin_server__tool。該完整名稱可以用于 Permission Rule、Skill allowed-tools、Agent tools、Hook Matcher。{ permissions: { allow: [ mcp__plugin_github-tools_github__get_issue, mcp__plugin_github-tools_github__list_pull_requests ], deny: [ mcp__plugin_github-tools_github__delete_repository, mcp__plugin_github-tools_github__force_push ] } }這允許企業(yè)把同一 MCP Server 中的不同 Tool 分開(kāi)治理。Plugin MCP Server 與手工配置的 Server 一樣可以訪問(wèn)用戶環(huán)境變量包括DB_URL、GITHUB_TOKEN、AWS credentials、內(nèi)部 API Token。因此企業(yè)不應(yīng)只檢查 MCP 的 Tool 名稱還要檢查 Server Command、Server URL、Arguments、Environment Variables、Headers、Headers Helper、Transport Type。4. 逐步驗(yàn)證配置生效配置寫(xiě)完之后你需要逐步驗(yàn)證每一層是否按預(yù)期工作。下面是我實(shí)測(cè)下來(lái)比較可靠的驗(yàn)證順序。4.1 驗(yàn)證來(lái)源限制先嘗試添加一個(gè)不在 Allowlist 里的 Marketplaceclaude marketplace add https://github.com/unknown-org/plugins如果strictKnownMarketplaces生效你應(yīng)該看到拒絕提示而不是成功添加。然后嘗試添加 Allowlist 里的來(lái)源確認(rèn)可以正常添加。注意檢查ref是否精確匹配v2.0和v2.0.0可能被視為不同來(lái)源。4.2 驗(yàn)證 Workspace Trust在一個(gè)新 Clone 的倉(cāng)庫(kù)里打開(kāi) Claude Code觀察是否彈出 Workspace Trust 提示。在接受 Trust 之前項(xiàng)目.claude/settings.json中的權(quán)限 Allow Rule、項(xiàng)目 Skill 中的allowed-tools、項(xiàng)目聲明的額外 Marketplace 都不應(yīng)產(chǎn)生完整效果。接受 Trust 后這些配置才生效。你可以在~/.claude.json中查看每個(gè)項(xiàng)目的 Trust 狀態(tài)。用戶級(jí)配置位于~/.claude/settings.json、~/.claude/skills/、~/.claude/agents/這些文件通常由當(dāng)前用戶自己維護(hù)默認(rèn)信任級(jí)別較高不需要同樣的 Trust 流程。4.3 驗(yàn)證 Skill allowed-tools 的單 Turn 生效創(chuàng)建一個(gè)測(cè)試 Skill聲明allowed-tools: Bash(git status *)。調(diào)用該 Skill觀察git status是否無(wú)需確認(rèn)就執(zhí)行。然后在同一條用戶消息里嘗試執(zhí)行g(shù)it push應(yīng)該仍然需要確認(rèn)。再發(fā)送下一條用戶消息再次嘗試git status應(yīng)該重新需要確認(rèn)因?yàn)?allowed-tools 已經(jīng)清除。4.4 驗(yàn)證 Hook 限制如果allowManagedHooksOnly生效普通 Plugin 的 Hook 應(yīng)該被阻止。你可以查看 Claude Code 的日志或 Hook 執(zhí)行記錄確認(rèn) Managed Hook 正常運(yùn)行而第三方 Hook 被跳過(guò)。對(duì)于 HTTP Hook嘗試訪問(wèn)不在allowedHttpHookUrls里的 URL應(yīng)該被拒絕。4.5 驗(yàn)證 MCP Tool 權(quán)限在/mcp中查看已安裝的 Plugin Server確認(rèn) Tool 名稱帶有完整命名空間。然后嘗試調(diào)用deny列表里的 Tool應(yīng)該被拒絕。嘗試調(diào)用allow列表里的 Tool應(yīng)該無(wú)需額外確認(rèn)。如果 Tool 既不在 allow 也不在 deny應(yīng)該走默認(rèn)的詢問(wèn)流程。5. 本篇常見(jiàn)錯(cuò)排查5.1 strictKnownMarketplaces 配置了但沒(méi)生效最常見(jiàn)的原因是配置寫(xiě)在了項(xiàng)目級(jí)或用戶級(jí) settings.json而不是 Managed Settings。strictKnownMarketplaces需要在 Managed Settings 中配置才能保證用戶和項(xiàng)目無(wú)法覆蓋。另一個(gè)原因是ref不匹配比如 Allowlist 里寫(xiě)的是v2.0實(shí)際添加的是v2.0.0或沒(méi)有指定 ref。5.2 Plugin 安裝后 Hook 沒(méi)有觸發(fā)先確認(rèn) Plugin 是否被正確啟用檢查enabledPlugins中的名稱和 Marketplace 后綴是否匹配。然后確認(rèn) Hook 的事件類型和 matcher 是否正確。如果allowManagedHooksOnly為 true普通 Plugin Hook 會(huì)被阻止這是預(yù)期行為。Plugin Hook 也會(huì)作用于 SubagentHook 輸入中會(huì)攜帶 Agent ID 和 Agent Type可以用來(lái)識(shí)別調(diào)用來(lái)源。5.3 Skill allowed-tools 沒(méi)有預(yù)批準(zhǔn)檢查 Skill 的 Frontmatter 格式是否正確allowed-tools的縮進(jìn)和列表語(yǔ)法是否合法。確認(rèn) Skill 被調(diào)用的當(dāng)前 Turn 中工具名稱是否精確匹配。Bash(git status *)和Bash(git status)可能被視為不同規(guī)則。另外如果 Managed Policy 明確 Deny 某個(gè)命令Skill 的 allowed-tools 不能繞過(guò)企業(yè)策略。5.4 MCP Tool 權(quán)限規(guī)則不匹配確認(rèn) Tool 的完整命名空間是否正確。Plugin MCP Tool 的格式是mcp__plugin_plugin_server__tool其中 plugin 和 server 名稱需要與 Plugin 和 MCP 配置中的名稱一致。如果規(guī)則寫(xiě)成了mcp__github__get_issue而實(shí)際是mcp__plugin_github-tools_github__get_issue規(guī)則不會(huì)生效。5.5 Plugin 更新后權(quán)限變化沒(méi)有被識(shí)別從當(dāng)前公開(kāi)文檔看Claude Code 已經(jīng)具備 Source 限制、Plugin 信任和運(yùn)行時(shí)權(quán)限控制但 Plugin 更新權(quán)限差異審查仍然是企業(yè)治理中值得重點(diǎn)補(bǔ)充的一層。Claude Code 按plugin.json中的 version、marketplace.jsonEntry 中的 version、Plugin Source 的 Git Commit SHA 順序解析版本。如果解析出的版本與當(dāng)前安裝版本相同手動(dòng)更新和自動(dòng)更新都會(huì)跳過(guò)。對(duì)于 Git Source不顯式聲明版本時(shí)每個(gè)新 Commit SHA 可以成為新版本標(biāo)識(shí)。企業(yè) Marketplace 可以在發(fā)布流程中掃描plugin.json、skills/*/SKILL.mdFrontmatter、agents/*.mdFrontmatter、hooks/hooks.json、.mcp.json、.lsp.json、scripts/提取能力清單并在更新時(shí)生成權(quán)限 Diff。權(quán)限范圍擴(kuò)大時(shí)應(yīng)要求管理員或用戶重新批準(zhǔn)。6. 供應(yīng)鏈校驗(yàn)清單與下一步把上面的配置和驗(yàn)證動(dòng)作整理成一份可執(zhí)行的清單團(tuán)隊(duì)落地時(shí)可以逐項(xiàng)檢查。來(lái)源層strictKnownMarketplaces是否配置到 Managed Settingsref是否固定到 Tag 或 SHAdisableSideloadFlags是否啟用是否區(qū)分 stable、beta、lab 通道。安裝層extraKnownMarketplaces是否只推薦批準(zhǔn)來(lái)源enabledPlugins是否只聲明期望狀態(tài)Workspace Trust 流程是否被正確觸發(fā)pluginTrustMessage是否添加了企業(yè)說(shuō)明。能力層Skill 的allowed-tools是否精確到腳本級(jí)別disallowed-tools是否用于主動(dòng)收縮Hook 是否受allowManagedHooksOnly限制HTTP Hook 是否有 URL 和 Env Var AllowlistMCP Tool 是否有 allow/deny 規(guī)則。運(yùn)行時(shí)層Permission Deny 是否優(yōu)先Sandbox 是否限制文件系統(tǒng)和網(wǎng)絡(luò)邊界Hook 和 Audit 是否記錄執(zhí)行過(guò)程Plugin 配置與 Secret 是否分離。驗(yàn)證完這些之后你可以用 TaoToken 的模型對(duì)話快速測(cè)試 Skill 行為https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。如果要長(zhǎng)期跑 Agent 循環(huán)和編碼任務(wù)Coding Plan 更適合https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。接入文檔和 API Keys 管理分別在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 和 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。真正可靠的 Marketplace 安全原則不是相信 Plugin 作者不會(huì)作惡而是即使 Plugin 內(nèi)容不可信它也只能從被批準(zhǔn)的來(lái)源進(jìn)入只能注冊(cè)被允許的能力只能獲得受限的運(yùn)行權(quán)限并且無(wú)法突破 Sandbox 和企業(yè)策略。Marketplace 決定能力從哪里來(lái)Plugin Trust 決定能力能否進(jìn)入Permission 決定能力能否調(diào)用Sandbox 決定調(diào)用最終能否真正越界。