# 插件市场 · 从哪装、怎么装才安全

> 插件从哪来？grok 有两层 marketplace：兼容 Claude 的 extraKnownMarketplaces，和原生的 xai-grok-plugin-marketplace。这一章看它怎么发现、拉取、安装插件，以及那些防坑的安全设计——SHA 钉版、路径穿越防护、快照而非软链。

- 作者：David（道雾轩）
- 专栏：Grok Build 源码解读（https://daiw.org/manual/grok-build.md）
- 最后更新：2026-09-15
- 原文：https://daiw.org/manual/grok-build/plugins-marketplace
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 插件市场 · 从哪装、怎么装才安全

上一章的插件从哪来？一部分你手写，更多的从 **marketplace** 装。grok 的 marketplace 分两层。

## 两层 marketplace

- **兼容层**(`plugins/marketplace.rs`)：直接读项目 `.claude/settings.json` 的 `extraKnownMarketplaces`(只认本地目录源)与 `enabledPlugins`，以及 `~/.claude/plugins/known_marketplaces.json` 里 Claude 已经克隆好的市场，插件就地加载。—— 又是「兼容 Claude 生态」的一环，你在 Claude 里配的市场，grok 直接认。
- **原生层**(`xai-grok-plugin-marketplace` crate)：grok 自己的市场，官方源是 `xAI Official`(`github.com/xai-org/plugin-marketplace.git`)。从 `[[marketplace.sources]]` 配置读源(本地路径或 git)，还会把 `~/.grok`、`~/.claude` 下 settings 里的 `extraKnownMarketplaces` 和 `known_marketplaces.json` 一并收成原生源。git 源克隆后缓存在 `~/.grok/marketplace-cache/`，5 分钟内不重复拉。

## 装一个插件的流程

`install_from_marketplace`(从已同步的 checkout 本地复制)或 `install_from_remote_url`(从远程 git 拉)。安装信息记在 `~/.grok/installed-plugins/registry.json`。源的解析(`parse_install_source`，在 `xai-grok-agent` 的 `git_install.rs` 里)认三种：完整 URL(HTTPS 或 SSH)、`owner/repo` GitHub 简写、本地路径，还支持 `#subdir` 和 `@ref`。会话启动时，pager 还会检查市场更新、自动升级有新版本的插件(组织可以用 `plugin_auto_update = false` 把它钉死关掉)。

一个关键设计：**安装是「复制成受管快照」，不是软链接**。源码注释给的理由是：让安装与源后续的修改、删除相隔离，卸载也只是删一个目录。对 git 安装，快照锁定的是装时的那个 commit，只有 update 才会变；对本地目录安装则有意「跟源」——`local_refresh` 在每次会话启动(以及 `/plugins reload`)时，把位于 home 下或受信的本地源重新复制一遍，好让源里新加的组件生效。

## 安全：几道防线

marketplace 装的是**别人写的、能执行代码的东西**，安全是重中之重：

1. **SHA 钉版**：`require_sha` 策略(`[marketplace] require_sha = true` 或环境变量 `GROK_MARKETPLACE_REQUIRE_SHA=1`，只能收紧、不能放松)开启时，从远程装或更新必须给**完整 commit SHA**(40 位或 64 位十六进制)，否则 `UnpinnedRemoteRefused` 拒装——防「装的时候是好的、之后源被人改了」。本地目录安装豁免(磁盘归你管，也没有东西要拉)。
2. **路径穿越防护**：`MarketplaceRelativePath::parse` 拒绝空路径、绝对路径、`..` 与 `.` 段，以及盘符、`a//b` 这类平台前缀或空段(开头的 `./` 会先剥掉再接受)；`join_under(root)` 规范化后还做 fail-closed 的符号链接逃逸检查。防插件路径指到市场目录外面。
3. **组织级白名单**：管理员可以用 `strictKnownMarketplaces` 限定允许的市场源——只要这个键存在就生效，列表为空即全部锁死；多个策略层同时存在时取最严。

最后要清楚一点：**装进来即受信**。marketplace 或 `grok plugin install` 装的插件按 User 作用域发现、自动受信——源码注释的理由是「用户显式装了它」。所以[上一章](https://daiw.org/manual/grok-build/plugins-manifest)的 `TrustStore` 管不到它们，真正的闸在安装之前：钉版、路径防护和白名单。

<Callout type="info">
  「不用扫全部插件就能列出」靠的是市场仓库里的索引文件(`.grok-plugin/marketplace.json` 优先，也认 `.claude-plugin/` 下的同名文件)，没有索引才回退到遍历 `plugins/*/`。CI 生成的 `plugin-index.json`(`catalog.rs`)则只补展示细节——让你装之前就看到每个插件带了哪些 skills、hooks、agents，加载失败也只是少了这些信息，从不影响列出。这和[工具协议那章](https://daiw.org/manual/grok-build/tool-protocol) `search_tool` 的「不把全部塞出来」是同一种「规模化」思路：索引先行，按需拉取。
</Callout>

## 和《从 LLM 到 Coding Agent》对照

对照 [Claude Code 手册 · 插件市场](https://daiw.org/manual/claude-code/plugins)——grok 的两层市场几乎是它的源码版对照：官方源、`owner/repo` 简写、SHA 钉版、`enabledPlugins`。教学最小实现里这些都不存在；它们是「让一个 agent 有生态、还安全」的产品工程。下一章转向另一类扩展：并行的 subagent。

---

上一篇：[插件 · 清单与信任](https://daiw.org/manual/grok-build/plugins-manifest) · 下一篇：[Subagents 与 personas](https://daiw.org/manual/grok-build/subagents)
