SuperMarioYL/agentgate
GitHub: SuperMarioYL/agentgate
AgentGate 是一个运行时按动作拦截的安全护栏,在 AI 编码 Agent 执行安装、脚本和网络请求时逐个授权,防止供应链载荷在执行点造成危害。
Stars: 0 | Forks: 0
给编码 Agent 的运行时主机护栏——按每个动作授权它的安装、脚本与网络请求,而不是全有或全无。
English | 简体中文
**你把 Agent 放进自主模式拉依赖、跑脚本——但容器是全有或全无的,关掉它换效率后,主机就彻底裸奔了。AgentGate 在每个触碰主机的动作发生的瞬间拦下来,带着 Agent 自己的意图问你一句:放行还是拒绝。**
## 目录
- [为什么需要它](#为什么需要它)
- [快速开始](#快速开始)
- [演示](#演示)
- [policy.yaml 策略 DSL](#policyyaml-策略-dsl)
- [配置项](#配置项)
- [对比](#对比-vs-容器--静态扫描器)
- [路线图](#路线图)
- [许可证](#许可证)
## 为什么需要它
当你让一个编码 **Agent** 写代码、拉依赖、跑脚本时,你把信任交给了它,但责任还在你身上——而你和主机之间没有一个带作用域的检查点。容器能做隔离,可它是全有或全无的,开发者为了 Agent 的效率往往把它关掉;就算开着,它也无法区分「这次安装没问题」和「那个网络请求是在外传数据」。
这不是一个静态依赖扫描器。Miasma 这类供应链蠕虫专门盯着 AI 编码 Agent——它瘫痪过 72+ 个仓库(含微软的 Azure Functions Action),而它的载荷只在安装 / 执行那一刻才暴露,静态分析在安装前读包根本看不到。AgentGate 是**运行时、按动作**的护栏:在安装、脚本、egress 发生的当下逐个授权,让供应链载荷在执行点被拦下,而不是等 72 个仓库挂掉后才发现。
##

架构
编码 Agent 跑在护栏后面:它拉起的每个子进程被 **PATH shim** 截获,每个网络请求被注入的 **HTTP(S) 代理**重定向到本地。两条路径都汇到一个 **unix-socket broker / Gate Engine**,由它按 `policy.yaml` 做首条匹配即生效的裁决——必要时弹出 `[a]llow / [d]eny / [A]lways` 提示。放行的动作才 `exec` 真实二进制并继续,拒绝的从不落地;每一笔裁决都追加进 **JSONL 审计日志**,事后用 `agentgate audit` 回看。
## 快速开始
需要 Go 1.24+(Linux 或 macOS)。从冷启动到第一个授权提示,三条命令:
go install github.com/SuperMarioYL/agentgate@latest # 1. 安装单文件二进制
agentgate init # 2. 在当前目录落一份默认 policy.yaml
agentgate run -- claude --autonomous "加个图表库并接好" # 3. 把你的 Agent 跑在护栏后面
第一个触碰主机的动作就会暂停,并显示 Agent 自己的意图:
┌─ AgentGate · action paused ──────────────────
│ agent : claude-code
│ action : exec
│ target : npm install chalk
│ intent : agent wants to install npm package: chalk
└──────────────────────────────────────────────
[a]llow / [d]eny / [A]lways ?
按 `a` 放行一次、`d` 拒绝、`A` 永久放行(会把规则写回 `policy.yaml`,稳态下几乎不再打扰你)。事后用 `agentgate audit` 查看每个被门控动作的 JSONL 审计流:
agentgate audit
# ✓ 13:20:26 exec allow npm install chalk
# ✗ 13:20:26 net_egress deny telemetry.unknown-host.example
##

演示
Agent 的 `npm install` 被暂停等待批准,安装后脚本对未声明主机的 egress 被红字拦下,最后 `agentgate audit` 打出完整轨迹:

## policy.yaml 策略 DSL
策略是**有序、首条匹配即生效**的规则列表。每条规则有一个 `match`(`action` + `target_glob`)和一个 `decision`(`allow` / `deny` / `ask`);任何规则都没命中的动作落到 `default`。
default: ask # 没有规则命中时的兜底决策
rules:
# exec —— Agent 拉起的安装与脚本
- match:
action: exec
target_glob: "*install*"
decision: ask # 每次安装都浮现出来,让你看清拉了什么
# fs_write —— 把写入限制在项目目录内
- match:
action: fs_write
target_glob: "$PWD/**"
decision: allow
scope: "$PWD" # 写入必须留在项目根之内
- match:
action: fs_write
decision: deny # 项目根之外的任何写入一律拒绝
# net_egress —— 放行常用 registry,门控其余一切
- match:
action: net_egress
target_glob: "registry.npmjs.org"
decision: allow
- match:
action: net_egress
decision: deny # 未声明的主机 -> 拦截
Glob 语义:`*` 匹配单个路径 / 主机段(`filepath.Match` 语义),`**` 跨段匹配(如 `$PWD/**`)。不带通配的裸 host token 按**主机边界**匹配——命中整个 target,或 `host:port` 的 host 部分(如 `registry.npmjs.org` 命中 `registry.npmjs.org:443`),但**不会**误放 `github.com.evil.com` 或 `evilgithub.com` 这类伪造主机。以点开头的 token(如 `.github.com`)匹配整棵子域树(`api.github.com`),但不含裸顶级域 `github.com` 本身。`agentgate init` 会落一份内置的合理默认策略,可直接编辑。
### 先 dry-run 一下:`agentgate check`
写完策略,想知道「Agent 真要做某个动作时会怎样」?`agentgate check` 把一个假想动作丢给策略,打印决策(`allow` / `deny` / `ask`)与命中原因——**不跑任何子进程、不发起任何 egress、不写审计日志**。
agentgate check --action exec -- npm install left-pad
# action : exec
# target : npm install left-pad
# intent : agent wants to install npm package: left-pad
# decision: ask (matched a rule)
agentgate check --action net_egress github.com.evil.com:443
# decision: deny (no rule matched, fell through to default)
agentgate check --action fs_write /etc/passwd
# decision: deny (matched an allow rule but the path escapes its scope)
`--action` 取 `exec`(默认)/ `fs_write` / `net_egress`,`--policy` 指定要检查的策略文件。
## 配置项
`agentgate run` 的常用开关:
| 选项 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `--policy` | string | `./policy.yaml`(或 `$AGENTGATE_POLICY`) | 使用的策略文件 |
| `--audit` | string | `.agentgate/audit.jsonl`(或 `$AGENTGATE_AUDIT`) | 追加式 JSONL 审计日志路径 |
| `--agent` | string | `claude-code` | 被包裹 Agent 的标识,会带进提示与审计 |
| `--no-net` | bool | `false` | 关闭网络 egress 门控(仅门控 exec / fs) |
| `--always` | bool | `true` | 把 `[A]lways` 选择持久化写回策略文件 |
## 对比 vs 容器 / 静态扫描器
诚实的定位——容器在隔离上比我们成熟得多;AgentGate 解决的是另一个问题:**按动作、带意图、运行时**。
| 维度 | AgentGate | 容器 / 一次性 VM | 静态依赖扫描器 |
| --- | --- | --- | --- |
| 按动作逐个授权 | ✓ | ✗(全有或全无) | ✗ |
| 携带 Agent 意图 | ✓ | ✗ | ✗ |
| 运行时拦截载荷 | ✓ | 部分(边界内不区分动作) | ✗(安装前读包,错过运行时载荷) |
| 成熟的进程隔离 | 部分(spawn + egress 边界) | ✓ | — |
| 安装时不被关掉换效率 | ✓ | ✗(常因影响效率被禁用) | — |
## 路线图
- [x] **m1 —— wrap & gate exec**:包裹 Agent,拦截它拉起的每个子进程,带意图提示 allow/deny。
- [x] **m2 —— scope fs & net**:`policy.yaml` 把文件写入限制在声明路径内,按主机门控 egress,并写入 JSONL 审计。
- [x] **m3 —— DSL & 演示**:`allow`/`deny`/`ask` DSL + `--always` 持久化、`agentgate init` 默认策略、60 秒 asciinema 演示、双语 README。
- [x] **m4 —— 写策略 & 审策略**:`agentgate check` 对任意动作做 dry-run;egress 按主机边界匹配,堵住伪造主机绕过;`.host` token 把规则限定在子域树内。
- [ ] 更多 harness 的开箱适配与 README 安全章节集成(ECC / openfang)。
- [ ] 策略 cookbook:针对真实供应链行为的若干即用策略。
- [ ] 团队共享策略 / 审计仪表盘(v2+ 探索,非当前论点)。
## 许可证
AgentGate 免费、MIT 许可、单文件二进制的开源软件——没有付费墙,没有托管层。欢迎通过 [issue](https://github.com/SuperMarioYL/agentgate/issues) 反馈问题或提交 PR。
## Share this
AgentGate — a runtime per-action host gate for your Coding Agent. It pauses each
install / script / egress with the agent's own intent, instead of all-or-nothing
containers. After the Miasma worm, your agent needs a seatbelt.
https://github.com/SuperMarioYL/agentgate
MIT © 2026 SuperMarioYL
标签:AI编程助手, EVTX分析, Go, Ruby工具, 日志审计, 权限控制, 沙箱, 网络信息收集, 运行时防护