☰
Harness Marketplace 剖析系列 - 之 Claude Code:权限、安全与供应链治理
2026/9/29 8:56:48 网站建设 项目流程

1. 从一次真实的 Plugin 事故说起

Claude Code 的 Marketplace 机制让第三方 Plugin 可以注入 Skills、Commands、Agents、Hooks、MCP Servers、LSP Servers 和 Scripts。能力能被加载,不代表能力应该被无条件信任。一个 Plugin 可能只是提供代码规范和文档,也可能携带可执行 Shell 脚本、自动触发的 Hook、远程 MCP Server、本地 MCP 进程、具有工具权限的 Skill、拥有独立执行循环的 Agent。

我见过一个团队在内部仓库里提交了.claude/settings.json,里面声明了enabledPlugins和extraKnownMarketplaces。新成员 Clone 仓库后,Claude Code 提示安装 Plugin,成员点了确认,Plugin 里的 PostToolUse Hook 就开始在每次 Write/Edit 后自动执行一个上传脚本。没有人显式调用过这个 Hook,它只是在生命周期事件里被触发。问题不在于这个 Plugin 本身恶意,而在于团队没有在落地前审查权限边界。

这篇文章面向的是准备在团队里落地 Claude Code Marketplace 的工程师和平台负责人。我会给出一份可复制的settings.json权限骨架,一份供应链校验清单,以及逐步验证动作,帮你确认配置生效、风险收敛。核心检索词是 Claude Code 权限、安全、供应链治理、Marketplace。适合谁:正在评估第三方 Plugin 引入流程的团队、需要给 Claude Code 建立企业级来源控制的平台工程师、以及想搞清楚 Skill allowed-tools 和 Hook 到底能做什么的开发者。

2. 落地前的 TaoToken 前置准备

在开始配置权限骨架之前,你需要一个稳定的模型接入点来验证配置是否生效。TaoToken 提供 Claude Code 兼容的 API 接入,官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 端点是 https://taotoken.net/api 。

如果你只是想在本地验证权限配置和 Skill 行为,用模型对话就够了:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 。如果你要长期跑编码任务或 Agent 循环,Coding Plan 更合适:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,API Keys 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。

拿到 Key 之后,你可以在 Claude Code 的配置里指向这个端点,然后用它来测试 Skill 的 allowed-tools 是否按预期生效、Hook 是否在正确的生命周期触发、MCP Tool 的权限规则是否被正确裁决。这一步的意义是:你有一个可控的模型后端,可以在不引入额外变量的情况下,单独验证权限配置的行为。

3. 可复制的 settings.json 权限骨架

下面这份骨架覆盖了来源控制、Plugin 信任、Skill 权限、Hook 限制和 MCP Tool 治理五个层面。你可以直接复制到项目的.claude/settings.json或用户级的~/.claude/settings.json,然后按团队实际情况调整。

3.1 来源控制:strictKnownMarketplaces 与 disableSideloadFlags

企业级来源控制的核心是strictKnownMarketplaces。它有三种状态:未配置时用户可以添加任意 Marketplace;空数组[]禁止添加所有 Marketplace;来源列表则只允许精确匹配的来源。

{ "strictKnownMarketplaces": [ { "source": "github", "repo": "acme-corp/approved-plugins", "ref": "v2.0" } ], "disableSideloadFlags": true }

这里有几个关键点。第一,ref固定到具体 Tag 或 Commit SHA,避免main分支内容变化导致供应链漂移。第二,disableSideloadFlags阻止用户通过单次 CLI 参数直接加载 Plugin 目录、Agent 或临时 MCP Server。第三,Claude Code 会在 Marketplace 添加、Plugin 安装、更新、刷新和自动更新之前执行校验,而且 Managed Settings 不能被用户或项目覆盖。

精确匹配意味着github.com/company/plugins、github.com/company/plugins@v2、github.com/company/plugins/path-a被视为不同来源。URL 尾部斜杠、.git后缀以及 SSH/HTTPS 形式也可能被视为不同来源。信任一个仓库不等于信任仓库中的所有 Branch、Tag 和子目录。

3.2 Plugin 信任:extraKnownMarketplaces 与 enabledPlugins

extraKnownMarketplaces用于向用户推荐 Marketplace,但它不是安全边界。它解决的是分发便利性,不是来源封锁。

{ "extraKnownMarketplaces": { "company-tools": { "source": { "source": "github", "repo": "acme-corp/approved-plugins", "ref": "v2.0" } } }, "enabledPlugins": { "security-review@company-tools": true, "audit-hooks@company-tools": true } }

项目可以在.claude/settings.json中声明enabledPlugins,但这不意味着其他团队成员拉取仓库后 Plugin 会在没有确认的情况下直接运行。Claude Code 要求每条 Plugin 加载路径都先让用户安装并信任 Plugin。项目设置只能表达项目期望状态,不能替每个用户完成信任决策。

完整流程是:项目声明 Plugin,用户打开仓库,接受 Workspace Trust,Claude Code 发现缺少 Marketplace 或 Plugin,向用户展示安装和信任提示,用户确认,Plugin 才进入本地 Cache 和 Runtime。这阻止了恶意仓库提交.claude/settings.json后受害者 Clone 仓库导致 Plugin 静默安装并执行的攻击路径。

3.3 Skill 权限:allowed-tools 与 disallowed-tools

Skill 通过 Frontmatter 声明allowed-tools和disallowed-tools。allowed-tools的作用不是新增底层工具,而是让指定工具在 Skill 被调用的当前 Turn 中无需重复请求用户批准。

--- 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.

关键特点:只在调用 Skill 的当前 Turn 生效,下一条用户消息后清除;没有列出的工具仍受普通 Permission Settings 管理;不会删除或隐藏其他工具。权限计算可以理解为:Skill Temporary Grant ∩ Harness Permission Policy ∩ Sandbox Boundary = 最终有效能力。

对于需要运行自己目录内脚本的 Skill,使用${CLAUDE_SKILL_DIR}做精确授权:

allowed-tools: - Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)

这比Bash(*)安全得多,因为它只预批准特定脚本,而不是整个 Shell。

3.4 Hook 限制:allowManagedHooksOnly 与 HTTP Hook Allowlist

Hook 由生命周期事件自动触发,包括 SessionStart、PreToolUse、PostToolUse、Stop、SubagentStart、ConfigChange。它可以执行 Shell Command、HTTP Request、LLM Prompt、Agent、MCP Tool。因此 Hook 更接近运行时 Middleware,而不是普通上下文说明。

{ "allowManagedHooksOnly": true, "allowedHttpHookUrls": [ "https://audit.acme-corp.com/hooks/*" ], "httpHookAllowedEnvVars": [ "AUDIT_TOKEN" ] }

allowManagedHooksOnly阻止用户、项目和普通 Plugin Hook,只保留 Managed Hook。由 Managed Settings 强制启用的 Plugin,其 Hook 可以作为已审查企业能力继续运行。allowedHttpHookUrls和httpHookAllowedEnvVars分别限制 Hook 可以访问哪些 URL、哪些环境变量允许插入 Header。这些 Allowlist 会作用于所有来源的 HTTP Hook,包括 Managed Policy。

3.5 MCP Tool 治理:命名空间与权限规则

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" ] } }

这允许企业把同一 MCP Server 中的不同 Tool 分开治理。Plugin MCP Server 与手工配置的 Server 一样,可以访问用户环境变量,包括DB_URL、GITHUB_TOKEN、AWS credentials、内部 API Token。因此企业不应只检查 MCP 的 Tool 名称,还要检查 Server Command、Server URL、Arguments、Environment Variables、Headers、Headers Helper、Transport Type。

4. 逐步验证配置生效

配置写完之后,你需要逐步验证每一层是否按预期工作。下面是我实测下来比较可靠的验证顺序。

4.1 验证来源限制

先尝试添加一个不在 Allowlist 里的 Marketplace:

claude marketplace add https://github.com/unknown-org/plugins

如果strictKnownMarketplaces生效,你应该看到拒绝提示,而不是成功添加。然后尝试添加 Allowlist 里的来源,确认可以正常添加。注意检查ref是否精确匹配,v2.0和v2.0.0可能被视为不同来源。

4.2 验证 Workspace Trust

在一个新 Clone 的仓库里打开 Claude Code,观察是否弹出 Workspace Trust 提示。在接受 Trust 之前,项目.claude/settings.json中的权限 Allow Rule、项目 Skill 中的allowed-tools、项目声明的额外 Marketplace 都不应产生完整效果。接受 Trust 后,这些配置才生效。

你可以在~/.claude.json中查看每个项目的 Trust 状态。用户级配置位于~/.claude/settings.json、~/.claude/skills/、~/.claude/agents/,这些文件通常由当前用户自己维护,默认信任级别较高,不需要同样的 Trust 流程。

4.3 验证 Skill allowed-tools 的单 Turn 生效

创建一个测试 Skill,声明allowed-tools: Bash(git status *)。调用该 Skill,观察git status是否无需确认就执行。然后在同一条用户消息里尝试执行git push,应该仍然需要确认。再发送下一条用户消息,再次尝试git status,应该重新需要确认,因为 allowed-tools 已经清除。

4.4 验证 Hook 限制

如果allowManagedHooksOnly生效,普通 Plugin 的 Hook 应该被阻止。你可以查看 Claude Code 的日志或 Hook 执行记录,确认 Managed Hook 正常运行,而第三方 Hook 被跳过。对于 HTTP Hook,尝试访问不在allowedHttpHookUrls里的 URL,应该被拒绝。

4.5 验证 MCP Tool 权限

在/mcp中查看已安装的 Plugin Server,确认 Tool 名称带有完整命名空间。然后尝试调用deny列表里的 Tool,应该被拒绝。尝试调用allow列表里的 Tool,应该无需额外确认。如果 Tool 既不在 allow 也不在 deny,应该走默认的询问流程。

5. 本篇常见错排查

5.1 strictKnownMarketplaces 配置了但没生效

最常见的原因是配置写在了项目级或用户级 settings.json,而不是 Managed Settings。strictKnownMarketplaces需要在 Managed Settings 中配置,才能保证用户和项目无法覆盖。另一个原因是ref不匹配,比如 Allowlist 里写的是v2.0,实际添加的是v2.0.0或没有指定 ref。

5.2 Plugin 安装后 Hook 没有触发

先确认 Plugin 是否被正确启用,检查enabledPlugins中的名称和 Marketplace 后缀是否匹配。然后确认 Hook 的事件类型和 matcher 是否正确。如果allowManagedHooksOnly为 true,普通 Plugin Hook 会被阻止,这是预期行为。Plugin Hook 也会作用于 Subagent,Hook 输入中会携带 Agent ID 和 Agent Type,可以用来识别调用来源。

5.3 Skill allowed-tools 没有预批准

检查 Skill 的 Frontmatter 格式是否正确,allowed-tools的缩进和列表语法是否合法。确认 Skill 被调用的当前 Turn 中,工具名称是否精确匹配。Bash(git status *)和Bash(git status)可能被视为不同规则。另外,如果 Managed Policy 明确 Deny 某个命令,Skill 的 allowed-tools 不能绕过企业策略。

5.4 MCP Tool 权限规则不匹配

确认 Tool 的完整命名空间是否正确。Plugin MCP Tool 的格式是mcp__plugin_<plugin>_<server>__<tool>,其中 plugin 和 server 名称需要与 Plugin 和 MCP 配置中的名称一致。如果规则写成了mcp__github__get_issue而实际是mcp__plugin_github-tools_github__get_issue,规则不会生效。

5.5 Plugin 更新后权限变化没有被识别

从当前公开文档看,Claude Code 已经具备 Source 限制、Plugin 信任和运行时权限控制,但 Plugin 更新权限差异审查仍然是企业治理中值得重点补充的一层。Claude Code 按plugin.json中的 version、marketplace.jsonEntry 中的 version、Plugin Source 的 Git Commit SHA 顺序解析版本。如果解析出的版本与当前安装版本相同,手动更新和自动更新都会跳过。对于 Git Source,不显式声明版本时,每个新 Commit SHA 可以成为新版本标识。

企业 Marketplace 可以在发布流程中扫描plugin.json、skills/*/SKILL.mdFrontmatter、agents/*.mdFrontmatter、hooks/hooks.json、.mcp.json、.lsp.json、scripts/,提取能力清单并在更新时生成权限 Diff。权限范围扩大时,应要求管理员或用户重新批准。

6. 供应链校验清单与下一步

把上面的配置和验证动作整理成一份可执行的清单,团队落地时可以逐项检查。

来源层:strictKnownMarketplaces是否配置到 Managed Settings;ref是否固定到 Tag 或 SHA;disableSideloadFlags是否启用;是否区分 stable、beta、lab 通道。

安装层:extraKnownMarketplaces是否只推荐批准来源;enabledPlugins是否只声明期望状态;Workspace Trust 流程是否被正确触发;pluginTrustMessage是否添加了企业说明。

能力层:Skill 的allowed-tools是否精确到脚本级别;disallowed-tools是否用于主动收缩;Hook 是否受allowManagedHooksOnly限制;HTTP Hook 是否有 URL 和 Env Var Allowlist;MCP Tool 是否有 allow/deny 规则。

运行时层:Permission Deny 是否优先;Sandbox 是否限制文件系统和网络边界;Hook 和 Audit 是否记录执行过程;Plugin 配置与 Secret 是否分离。

验证完这些之后,你可以用 TaoToken 的模型对话快速测试 Skill 行为:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 。如果要长期跑 Agent 循环和编码任务,Coding Plan 更适合:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。接入文档和 API Keys 管理分别在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 和 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。

真正可靠的 Marketplace 安全原则不是相信 Plugin 作者不会作恶,而是即使 Plugin 内容不可信,它也只能从被批准的来源进入,只能注册被允许的能力,只能获得受限的运行权限,并且无法突破 Sandbox 和企业策略。Marketplace 决定能力从哪里来,Plugin Trust 决定能力能否进入,Permission 决定能力能否调用,Sandbox 决定调用最终能否真正越界。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询