saagpatel/cross-provider-egress-guard
GitHub: saagpatel/cross-provider-egress-guard
该工具在 Claude Code 和 Codex 的工具分发层实施基于目标感知的默认拒绝出口流量控制,防止 AI 编码 agent 因恶意指令将数据外泄到未授权主机。
Stars: 0 | Forks: 0
# cross-provider-egress-guard
**面向 AI 编码 agent 的目标感知、默认拒绝的出口流量控制,在 agent 自身的工具分发边界处执行,同时兼容 Claude Code 和 Codex。**
[](https://github.com/saagpatel/cross-provider-egress-guard/actions/workflows/ci.yml)
[](LICENSE)

*针对示例策略的六个代表性工具调用。可以通过 `bash demo/demo.sh` 在离线状态下复现。*
## 威胁
AI 编码 agent 拥有广泛的权限:它读取你的文件、调用工具,并通过 MCP connector 和 shell 访问网络。一条恶意指令(无论是模型自身出现偏差,还是 **prompt 注入 payload 隐藏在工具输出中**)都可能转化为一次将数据发送到攻击者控制主机的工具调用。大多数 agent 设置对该调用**没有目标控制**:只要 agent 能指定一个 URL,它就能访问到它。
本防护机制正是为了解决这一问题:**默认情况下,network/send 类的工具调用和 shell 网络命令将被拒绝,除非其目标位于你控制的 allow-list(允许列表)中。**
## 这是什么
这是一小套 **PreToolUse hook**(用于 Claude Code)以及等效的 **hook patch**(用于 Codex),它们会对每次工具调用进行分类,并根据一个共享的 JSON allow-list 策略对包含网络特征的调用进行拦截。它在 *agent 自身的分发周期内* 运行(无需网络重新配置,无需架设代理,也无需修改特定应用的 SDK),并通过单一事实来源在**两个 agent 之间强制执行相同的策略**。
- 针对网络/send 类工具的**默认拒绝**;其他所有操作不受影响。
- 基于**每个目标**的主机 allow-list 设定和基于**每个 connector** 的范围界定(包括资源所有者范围界定,例如仅限你的 GitHub org)。
- **Fail-closed(关闭失败)**:策略缺失、无法读取或无效时均会拒绝;绝不放开权限。
- **跨提供商**:Claude Code(`mcp-guard.sh` + `bash-egress-guard.sh`)和 Codex(`codex-egress.patch`)读取*相同*的 `mcp-gate-policy.json`,从而确保两个 agent 不会偏离到不同的影响范围。
## 它所处的位置(客观定位)
Agent 的出口流量可以在两个层面上进行控制,它们是**互补的**:
- **网络代理层**:位于 agent 外部的正向代理 / 防火墙 / DLP(例如 [Pipelock](https://github.com/luckyPipewrench/pipelock)、Promptfoo 的 MCP 代理、MCP 网关)。独立于 agent;功能强大,但需要网络底层配置,且脱离了 agent 的语义环境。
- **Agent hook 层**:*即本项目*。在**分发之前**对每次工具调用进行拦截,具备基于工具/connector/所有者的语义控制,且无需进行网络重新配置。
截至 2026 年中,尚无公开项目能够在 **hook 层面实现跨 Claude Code *和* Codex 的默认拒绝、基于目标的出口流量控制**,并基于统一的共享策略运行。这正是本项目填补的空白。要实现真正的深度防御,请**同时**运行两个层面的控制;关于为什么进程内 hook 不能替代网络阻塞点,请参阅 [LIMITATIONS.md](LIMITATIONS.md)。
## 工作原理
工具调用会被严格归类为以下一种模式(按顺序检查):
1. **URL-host**:携带显式 URL 的工具(如浏览器导航、fetch)。仅当提取出的所有主机 ∈ `allow_hosts` 时才允许。欺骗性主机(伪造 userinfo、末尾加点、punycode、IP 字面量)会先被规范化为其真实主机;无法提取出主机 ⇒ 拒绝。
2. **Connector-class**:payload 中没有 URL 的固定后端 connector。仅当完整工具名称匹配 `allow_connectors` glob 模式时才允许;未知/重命名的 connector ⇒ 拒绝。可选的 `connector_owner_scope` 会进一步限制 connector 仅能访问 allow-list 中的资源所有者。
3. **通用网络兜底策略**:任何*名称*表明其具有网络/send 行为,但不符合上述两种模式的工具 ⇒ **fail-closed 拒绝**,除非其 server 是本地的(`non_egress_servers`)。
4. **携带 `scheme://host` payload 的未知工具** ⇒ fail-closed 拒绝。
Shell hook(`bash-egress-guard.sh`,以及 Codex 端)将相同的 allow-list 应用于 `curl`/`wget`/`ssh`,并针对所有者/主机范围对 `git push` / `gh` 的**写操作**进行限制(读操作绝不拦截)。完整模型:[docs/THREAT-MODEL.md](docs/THREAT-MODEL.md) 和 [docs/DESIGN.md](docs/DESIGN.md)。映射至 [OWASP Top 10 for LLM Applications (2025)](docs/OWASP-LLM-MAPPING.md)。
## 快速开始:查看其运行效果(无需安装,离线运行)
```
git clone https://github.com/saagpatel/cross-provider-egress-guard
cd cross-provider-egress-guard
bash tests/run-all.sh # runs the full deterministic suite against the in-repo hooks
```
你将看到各种模式下触发的出口流量拒绝(导航至非 allow-list 主机、未知 connector、欺骗性的 GitHub 主机、超大 novel-host payload),以及合法的 allow-list 调用顺利通过。仅需 `bash` 和 `jq`(macOS/Linux 上已预装)。
这同一套测试套件(涵盖了两个 agent 执行逻辑中的 200 多个断言,外加证明它们读取同一共享策略的跨提供商一致性检查)也是 CI 的验证门槛。
## 安装
请参阅 [docs/INSTALL.md](docs/INSTALL.md) 部署 Claude Code hook 并应用 Codex patch,并参考 [policy/mcp-gate-policy.example.json](policy/mcp-gate-policy.example.json) 获取带有注释的启动策略模板,以便复制并根据你的环境进行修改。
## 它*不*做什么
它只是**一个防护层,而非银弹**。它不跟踪输出侧的数据流、不解码编码后的 payload、也不检测隐藏在工具输出中的注入,且进程内 hook 与 agent 共享同一个信任域。在依赖它之前,请阅读 [LIMITATIONS.md](LIMITATIONS.md),并将其与网络层控制结合使用。
## 安全
发现了绕过漏洞?请私下报告;请参阅 [SECURITY.md](SECURITY.md)。绕过漏洞即被视为漏洞;请勿为此公开 issue。
## 贡献
欢迎提交贡献;请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。简短版本:出口流量控制逻辑是累加的(绝不削弱现有的拒绝策略),两个 agent 在共享策略上保持一致,且每一次行为变更都会附带测试。
## License
[Apache-2.0](LICENSE)。
标签:AI编程助手, Homebrew安装, MCP, Streamlit, 出站流量控制, 应用安全, 访问控制, 钩子机制, 默认拒绝