AgentGate - AI Agent 数据采集与安全分析中间层服务
Project description
AgentGate
AI Agent 行为采集与安全分析网关
AgentGate 位于 AI Agent 与 AgentMoss 之间:拦截 Agent 的工具调用行为,采集上下文,提交安全分析,回传 Allow/Deny 决策。
┌──────────────┐ API 请求(改base_url) ┌──────────────────┐ HTTP ┌─────────────┐
│ AI Agent │ ── /v1/chat/... ────▶│ AgentGate │ ──────────▶│ AgentMoss │
│ (claude-code │ │ API Gateway 模式 │ │ (安全分析) │
│ opendesk │◀── 原始响应 ─────────│ · 拦截tool_calls │◀──────────│ │
│ cursor...) │ │ · 隐私脱敏 │ └─────────────┘
└──────────────┘ │ · 触发规则引擎 │
│ · Dashboard │
└──────────────────┘
1. 安装
Python(PyPI)
pip install agent-gate-sec
Python(源码)
git clone git@gitcode.com:kenhkl/AgentGate.git
cd AgentGate
python3 -m venv venv
source venv/bin/activate
pip install -e ".[proxy,dev]"
TypeScript(npm)
npm install -g @kenhkl/agent-gate
TypeScript(源码)
git clone git@gitcode.com:kenhkl/AgentGate.git
cd AgentGate/ts
npm install
npm run build
2. 快速开始
2.1 API Gateway 模式(推荐)
零侵入、零配置、跨平台。Agent 无需任何环境变量,只需改一个 api_base_url。
Python
方式 1: 前台运行(测试)
# 1. 启动网关(指定上游 LLM API 地址)
agent-gate gateway --upstream https://token-plan-cn.xiaomimimo.com
# 2. 自动配置已安装的 Agent(首次执行即可)
agent-gate install
# 3. 正常使用 Agent,无需任何额外操作
ccr code -p "echo hello"
方式 2: 后台运行(日常使用)
# nohup 后台运行
nohup agent-gate gateway --upstream https://token-plan-cn.xiaomimimo.com > logs/gateway.log 2>&1 &
# 或使用 screen/tmux(推荐)
screen -S agentgate
agent-gate gateway --upstream https://token-plan-cn.xiaomimimo.com
# Ctrl+A+D 分离
方式 3: systemd 服务(生产环境)
# 一键安装 systemd 服务
bash scripts/install-systemd-py.sh
# 服务管理
sudo systemctl start agentgate # 启动
sudo systemctl stop agentgate # 停止
sudo systemctl status agentgate # 状态
# 开机自启动
sudo systemctl enable agentgate
# 查看日志
tail -f logs/gateway.log
# 卸载服务
bash scripts/uninstall-systemd-py.sh
TypeScript
# 1. 启动网关
agent-gate gateway --port 19300 --upstream https://token-plan-cn.xiaomimimo.com
# 2. 自动配置 Agent
agent-gate install --gateway-url http://127.0.0.1:19300
# 3. 正常使用
ccr code -p "echo hello"
工作原理
Agent (ccr/claude-code/opendesk)
↓ 原本: api_base_url = "https://token-plan-cn.xiaomimimo.com/v1/chat/completions"
↓ 改为: api_base_url = "http://127.0.0.1:9110/v1/chat/completions"
AgentGate API Gateway (localhost:9110)
↓ 解析 tool_calls → 触发规则 → 上报 AgentMoss
↓ 转发到真实 LLM API
token-plan-cn.xiaomimimo.com
自动配置的 Agent
agent-gate install 会自动检测并配置以下 Agent:
| Agent | 配置文件 | 修改内容 |
|---|---|---|
| ccr (claude-code-router) | ~/.claude-code-router/config.json |
api_base_url |
| claude-code | ~/.claude/settings.json |
ANTHROPIC_BASE_URL |
| opencode | ~/.config/opencode/config.json |
api_base_url |
配置前自动备份,agent-gate uninstall 一键恢复。
2.2 MITM Proxy 模式(备用)
适用于无法修改 Agent 配置的场景。需要设置环境变量。
# Python
agent-gate proxy --port 9110
# TypeScript
cd ts/
npx tsx src/cli.ts proxy --port 19300
# 另一个终端
export HTTPS_PROXY=http://127.0.0.1:9110
export HTTP_PROXY=http://127.0.0.1:9110
claude-code
2.3 v1 Server 模式
Agent 主动调用 AgentGate API(需要 Agent 集成 SDK)。
agent-gate server --port 9100
2.4 Dashboard
API Gateway 模式
Dashboard 内置在网关中,访问 http://127.0.0.1:9110 即可。
独立 Dashboard
agent-gate dashboard --port 9120
Dashboard 支持中英文切换,当前活跃/历史会话标签页,以及事件详情弹窗。
Dashboard API
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/ |
Dashboard 页面 |
GET |
/api/stats |
统计数据(事件数、会话数、触发数) |
GET |
/api/events?limit=50&page=1 |
事件列表(支持分页) |
GET |
/api/sessions |
当前活跃会话列表 |
GET |
/api/history |
历史会话列表(最近 5 分钟无事件) |
GET |
/api/session-events?id=<session_id>&limit=200 |
指定会话的事件详情 |
2.5 L3 eBPF Daemon(Linux 内核层监控)
L3 通过 eBPF 在内核层采集系统调用,提供最底层的行为监控。
# 启动 L3 daemon(需要 root 权限)
agent-gate start --level l3 --upstream https://token-plan-cn.xiaomimimo.com
# 启用拦截模式(AgentMoss Deny 时阻断 syscall)
agent-gate start --level l3 --upstream https://token-plan-cn.xiaomimimo.com --deny-action block
依赖
# Ubuntu/Debian
sudo apt install python3-bpfcc linux-headers-$(uname -r)
# CentOS/RHEL
sudo yum install python3-bcc kernel-devel
WSL2 特殊配置
WSL2 的 Microsoft 自定义内核默认未启用 CONFIG_BPF_KPROBE_OVERRIDE,需要重编译内核:
# 一键编译(自动安装依赖、配置、编译、安装)
cd ~/gitcode/AgentGate
bash scripts/build_wsl2_kernel.sh
# 重启 WSL2 生效(PowerShell 中执行)
wsl --shutdown
wsl
# 验证 eBPF enforcement 是否可用
bash scripts/verify_ebpf_enforcement.sh
编译脚本会自动:
- 克隆 WSL2 内核源码
- 安装编译依赖(
build-essential,cpio,dwarves等) - 启用
CONFIG_BPF_KPROBE_OVERRIDE=y - 编译内核并复制到 Windows 侧
- 配置
.wslconfig使用新内核
如果没有重编译内核,L3 daemon 会自动降级为 userspace 拦截(通过 kill_tree 终止进程),功能正常但不是内核级阻断。
启动参数
| 参数 | 默认值 | 说明 |
|---|---|---|
--level |
l1 |
启用的层:l1, l2, l3,可组合如 l1+l3 |
--upstream |
- | 上游 LLM API 地址 |
--deny-action |
inform |
inform=仅告警不拦截, block=AgentMoss Deny 时阻断 |
--mode |
production |
production, dev, dry-run |
3. 版本对比
| 特性 | Python | TypeScript |
|---|---|---|
| L1 API Gateway | ✅ 完整 | ✅ 完整 |
| L1 MITM Proxy | ✅ 完整 | ✅ 完整 |
| L2 PTY 拦截 | ✅ 完整 | ✅ 完整 |
| L3 eBPF Daemon | ✅ 实现 | ❌ 未实现 |
| PhaseCoordinator | ✅ L1+L2+L3 | ✅ L1+L2(L3 API 已预留) |
| 白名单 + 快速阻断 | ✅ | ✅ |
| AgentMoss 全量转发 | ✅ | ✅ |
| Session prompt 追踪 | ✅ | ✅ |
| Dashboard | ✅ | ✅(内嵌) |
| CLI | agent-gate |
agent-gate |
4. 配置
4.1 配置文件
# config/agent_gate.yaml
gateway:
host: "127.0.0.1"
port: 9110
# upstream 通过 --upstream 参数指定
privacy:
mode: "auto" # auto | cloud_only | local_only
redact_api_keys: true
redact_passwords: true
truncate_system_prompt: 200
truncate_user_prompt: 500
4.2 触发规则与 AgentMoss 联动
AgentGate 采用 白名单跳过 → 快速阻断兜底 → 默认全量送 AgentMoss 的架构。
Agent 调用 LLM API
│ L1 Proxy 拦截
▼
┌── [白名单检查] ───────────────────────────┐
│ ls, pwd, echo, which, whoami... │ → Allow(跳过 AgentMoss)
│ ask_user_question, glob, list_dir... │
└──────────────────────────────────────────┘
▼(非白名单)
┌── [本地快速阻断] ─────────────────────────┐
│ rm -rf /, chmod 777, curl|bash... │ → Deny(不等 AgentMoss)
│ dd if=/dev/zero, mkfs, 反弹 Shell... │
└──────────────────────────────────────────┘
▼(以上都不匹配)
┌── [AgentMoss 三层分析] ──────────────────┐
│ 层1.1: 启发式检测(关键命令正则+注入) │
│ 层1.2: 逻辑规则(read_before_write等) │
│ 层1.3: LLM 语义分析(最终判断) │
└──────────────────────────────────────────┘
▼
Allow → 转发响应给 Agent | Deny → 返回 403
白名单规则(action: allow, _skip_agentmoss: true):
- 完全安全的只读命令(
ls,pwd,echo,which等) - 安全工具(
ask_user_question,glob,list_dir等) - 安全但可访问敏感路径的命令(
cat,head,grep等) - 内联脚本命令(
python -c,perl -e— 避免字符串字面量误报)
快速阻断规则(action: block):
rm -rf根目录 / 系统目录chmod 777curl | bash远程下载执行dd if=/dev/zero磁盘清零mkfs格式化- 反弹 Shell(
nc -e,/dev/tcp) - Docker socket 访问
触发分析规则(action: trigger_analysis):
- 为 AgentMoss 提供精确的
severity/risk_type - 敏感文件访问(
/etc/shadow, SSH 私钥, 凭据文件) - 危险命令(
sudo,git push --force, 密码修改) - Prompt 注入(指令覆盖、角色劫持、越狱)
- 权限提升、横向移动、持久化后门、数据外传
# config/trigger_rules.yaml 示例
rules:
# 白名单 — 跳过 AgentMoss
- name: "whitelist_bash_safe_readonly"
action: allow
severity: low
_skip_agentmoss: true
pattern:
source_collector: "llm_api_proxy"
tool_name_matches: ["bash", "executeBash", "Bash"]
arguments_regex: "^(ls|pwd|echo|which|whoami)\\b"
# 快速阻断 — 不等 AgentMoss
- name: "quick_deny_rm_rf_root"
action: block
severity: critical
pattern:
source_collector: "llm_api_proxy"
arguments_regex: "\\brm\\s+-(?=[^\\s]*r)(?=[^\\s]*f)[a-zA-Z]*\\s+/"
# 触发分析 — 送 AgentMoss
- name: "sensitive_file_shadow"
action: trigger_analysis
severity: critical
pattern:
source_collector: "llm_api_proxy"
arguments_regex: "/etc/shadow"
4.3 隐私模式
6. 架构
┌─────────────────────────────────────────────────────────┐
│ AgentGate v3.0 │
├─────────────────────────────────────────────────────────┤
│ L1: API Gateway / MITM Proxy (HTTP 层) │
│ · 拦截 LLM API 请求,解析 tool_calls 和 prompts │
│ · 提取: tool_name, arguments, user_prompt, model │
├─────────────────────────────────────────────────────────┤
│ L2: PTY 终端拦截 (进程层) │
│ · 拦截 agent 子进程执行,提取命令和输出 │
│ · 提取: command, argv, pid, output │
├─────────────────────────────────────────────────────────┤
│ L3: eBPF 系统监控 (内核层,仅 Linux) │
│ · 系统调用采集(trace-all + 进程树过滤) │
│ · 提取: syscall_type, argv, pathname, fd, addr │
├─────────────────────────────────────────────────────────┤
│ PhaseCoordinator(统一判断层) │
│ · SessionAggregator(prompt + action 历史追踪) │
│ · WhitelistEngine(安全命令跳过 AgentMoss) │
│ · TriggerEngine(快速阻断 + 触发分析) │
│ · PrivacyFilter(auto/cloud_only/local_only) │
├─────────────────────────────────────────────────────────┤
│ AgentMoss 联动 │
│ · 全部非白名单事件 → 全量送 AgentMoss 三层分析 │
│ · 发送: prompt_history + action_history + a_next │
│ · 接收: Allow/Deny 决策 │
│ · Deny → 返回 403 阻断 │
└─────────────────────────────────────────────────────────┘
6.1 各层数据格式
L1 事件(API Gateway / MITM Proxy)
L1 从 LLM API 请求/响应中提取结构化数据:
{
"session_id": "api-session-hash",
"source_collector": "llm_api_proxy",
"source_layers": ["l1"],
"agent_type": "opencode",
"action": {
"tool_name": "read_file",
"tool_call_id": "call_abc123",
"arguments_raw": "{\"path\": \"/etc/passwd\"}",
"action_type": "read_file"
},
"target": {
"command": "",
"file_path": "/etc/passwd",
"arguments": {"path": "/etc/passwd"}
},
"payload": {
"user_prompt": "读取 /etc/passwd 文件内容",
"system_prompt": "你是一个AI助手...",
"request_model": "gpt-4o",
"tool_response_content": "root:x:0:0:..."
},
"timestamp": {"iso": "2025-06-15T10:30:00"}
}
L2 事件(PTY 终端拦截)
L2 从终端字节流中解析出命令执行:
{
"session_id": "pty-session-uuid",
"source_collector": "pty",
"source_layers": ["l2"],
"agent_type": "opencode",
"action": {
"tool_name": "bash",
"tool_call_id": "",
"arguments_raw": "",
"action_type": "bash"
},
"target": {
"command": "cat /etc/passwd",
"file_path": "",
"argv": ["cat", "/etc/passwd"],
"output": "root:x:0:0:root:/root:/bin/bash\n..."
},
"process": {
"pid": 12345,
"ppid": 12300,
"comm": "cat",
"agent_type": "opencode"
},
"timestamp": {"iso": "2025-06-15T10:30:01"}
}
L3 事件(eBPF 系统监控)
L3 从内核 syscall 中提取执行细节,支持内核级阻断(需 CONFIG_BPF_KPROBE_OVERRIDE):
{
"session_id": "ebpf-session-uuid",
"source_collector": "ebpf",
"source_layers": ["l3"],
"agent_type": "opencode",
"event_type": "process_exec",
"action": {
"action_type": "process_exec",
"flags": ""
},
"target": {
"argv": "cat /etc/passwd",
"pathname": "/usr/bin/cat",
"pid": 12345,
"ppid": 12300
},
"process": {
"pid": 12345,
"comm": "cat",
"agent_type": "opencode"
},
"timestamp": {"iso": "2025-06-15T10:30:01"}
}
组合事件(L1 + L2 融合)
当 PhaseCoordinator level=2 时,L1 事件和 L2 事件被合并:
{
"session_id": "matched-session-uuid",
"source_collector": "llm_api_proxy",
"source_layers": ["l1", "l2"],
"agent_type": "opencode",
"action": {
"tool_name": "read_file",
"tool_call_id": "call_abc123",
"arguments_raw": "{\"path\": \"/etc/passwd\"}",
"action_type": "read_file"
},
"target": {
"command": "cat /etc/passwd",
"file_path": "/etc/passwd",
"executed_command": "cat /etc/passwd",
"executed_args": ["cat", "/etc/passwd"],
"output": "root:x:0:0:root:/root:/bin/bash\n..."
},
"payload": {
"user_prompt": "读取 /etc/passwd 文件内容",
"system_prompt": "你是一个AI助手...",
"request_model": "gpt-4o"
},
"process": {
"pid": 12345,
"comm": "cat",
"agent_type": "opencode"
},
"agent_type": "opencode",
"timestamp": {"iso": "2025-06-15T10:30:00"}
}
6.2 AgentMoss 上报数据格式
当触发条件满足时,PhaseCoordinator 构建完整报告发送给 AgentMoss:
{
"session_id": "uuid",
"prompt_session": "读取 /etc/passwd 文件内容",
"prompt_history": [
"第一次 prompt",
"第二次 prompt",
"当前 prompt"
],
"action_history": [
{"action_type": "Read", "action_detail": "/var/log/syslog"},
{"action_type": "Bash", "action_detail": "sudo apt update"}
],
"a_next": {
"action_type": "Read",
"action_detail": "/etc/passwd"
},
"reason": "用户要求读取passwd文件",
"source_layers": ["l1", "l2"],
"os_type": "linux",
"cwd": "/home/user/project"
}
| 字段 | 来源 | 说明 |
|---|---|---|
prompt_session |
L1 payload.user_prompt | 当前最新用户 prompt |
prompt_history |
Session.prompts | 全 session 所有 prompt(有序) |
action_history |
Session.events | 全 session 所有历史动作 |
a_next |
当前事件 | 本次要执行的 tool_call |
source_layers |
事件标记 | 哪些层参与了采集 |
6.3 触发 AgentMoss 的时机
| 场景 | 触发条件 | 发给 AgentMoss 的数据 | 能否阻断 |
|---|---|---|---|
| L1 单独 | 每收到 tool_call(纯文本回复仅记录为上下文) | prompt_history + action_history + a_next + current_prompt |
✅ 同步 403 |
| L2 单独 | 每解析出命令 | command + action_history(历史命令序列) |
✅ 同步 |
| L1+L2 | L1 收到 tool_call(立即决策),L2 匹配后补充执行细节 | 同上 + 补充 L2 执行的命令和输出 | ✅ 同步 |
| L3 单独 | 每收到 syscall | event_type + argv/path(异步记录) |
✅ eBPF 阻断(需内核支持) |
| 全组合 | L1 驱动,L2/L3 融合补充 | 最完整的上下文 | ✅ |
白名单判断:匹配白名单规则(action: allow, _skip_agentmoss: true)→ 跳过 AgentMoss,直接 Allow。
快速阻断判断:匹配快速阻断规则(action: block, local_block: true)→ 跳过 AgentMoss,直接 Deny 并返回 403。
默认:以上都不匹配 → 全量送 AgentMoss 做完整三层分析。
6.4 Python 与 TypeScript 实现对照
| 组件 | Python | TypeScript |
|---|---|---|
| PhaseCoordinator | agent_gate/v3/coordinator.py |
ts/src/v3/coordinator.ts |
| Session Aggregator | agent_gate/v3/session/aggregator.py |
ts/src/v3/proxy/session.ts |
| Whitelist Engine | 无单独文件(PhaseCoordinator 集成) | ts/src/v3/proxy/whitelist.ts |
| Trigger Engine | agent_gate/v3/trigger/engine.py |
ts/src/v3/proxy/trigger.ts |
| L1 Normalizer | agent_gate/v3/proxy/normalizer.py |
ts/src/v3/proxy/normalizer.ts |
| L2 PTY | agent_gate/v3/pty/ |
ts/src/v3/pty/ |
| L3 eBPF | agent_gate/v3/l3/ |
❌ 未实现 |
| L3 Phase 集成 | coordinator.on_l3_event() |
❌ 未集成(API 已预留) |
| Moss Report 格式 | _build_moss_report() |
buildMossReport() |
| L2 Standalone | _build_l2_standalone_event() |
_buildL2StandaloneReport() |
| L3 Report | _build_l3_report() |
_buildL3Report() |
一句话:L1 知道 LLM 建议 Agent 做什么,L2 知道 Agent 实际做了什么,L3 知道内核真实发生了什么。
7. 项目结构
AgentGate/
├── agent_gate/ # Python 包
│ ├── cli.py # CLI: gateway / install / proxy / server / dashboard
│ ├── config.py # YAML 配置
│ ├── coordinator.py # PhaseCoordinator (whitelist→quick-deny→AgentMoss)
│ ├── gateway/ # API Gateway 模块
│ │ ├── server.py # OpenAI 兼容 HTTP 网关
│ │ ├── server_legacy.py # v1 HTTP 服务
│ │ └── installer.py # 自动配置 Agent
│ ├── collector/ # 数据采集
│ │ ├── base.py # BehaviorCollector 统一接口
│ │ └── ebpf/ # eBPF 采集 (experimental)
│ ├── proxy/ # MITM Proxy 模块(备用)
│ │ ├── parsers/ # LLM API 格式解析器
│ │ ├── normalizer.py # 统一事件 Schema
│ │ ├── interceptor.py # mitmproxy addon
│ │ ├── server.py # Proxy 服务器
│ │ └── privacy.py # 隐私脱敏过滤
│ ├── pty/ # PTY 终端拦截(L2)
│ ├── server/ # v1 FastAPI 服务
│ ├── session/ # 会话聚合 (prompt_history + action_history)
│ ├── trigger/ # 触发规则引擎
│ ├── storage/ # SQLite 存储
│ ├── moss/ # AgentMoss 客户端
│ └── l3/ # eBPF Daemon (L3, experimental)
├── ts/ # TypeScript 版本
│ └── src/
│ ├── cli.ts # CLI: server / proxy / gateway / run
│ ├── coordinator.ts # PhaseCoordinator (L1+L2, L3 API 预留)
│ ├── gateway/ # API Gateway
│ ├── proxy/ # MITM Proxy
│ │ ├── server.ts # Proxy 服务器
│ │ ├── interceptor.ts # LLM 拦截器
│ │ ├── normalizer.ts # 事件归一化
│ │ ├── session.ts # 会话聚合 (prompts + actions)
│ │ ├── trigger.ts # 触发规则引擎
│ │ ├── whitelist.ts # 白名单引擎
│ │ ├── privacy.ts # 隐私脱敏
│ │ ├── storage.ts # SQLite 存储
│ │ └── parsers/ # LLM API 格式解析器
│ ├── pty/ # PTY 终端拦截 (L2)
│ └── storage/ # 数据库
├── config/
│ ├── agent_gate.yaml # 主配置
│ └── trigger_rules.yaml # 触发规则(13 条)
├── deploy/
│ └── agentgate.service # systemd 服务文件
├── tests/
│ ├── test_v3_proxy.py # v3 单元测试
│ ├── test_v3_privacy.py # 隐私过滤测试
│ └── test_v2_*.py # v2 eBPF 测试
├── pyproject.toml # PyPI: agent-gate-sec
└── ts/package.json # npm: @kenhkl/agent-gate
8. 测试
# Python v3 测试
python3 tests/test_v3_proxy.py
python3 tests/test_v3_privacy.py
# TypeScript v3 测试
cd ts/
npx tsx tests/test_v3_proxy.ts
# v2 eBPF 测试(需要 sudo + Linux)
sudo python3 tests/test_v2_e2e.py
9. 发布
PyPI
pip install build twine
python -m build
twine check dist/*
twine upload dist/*
npm
cd ts/
npm run build
npm publish --access public
许可证
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_gate_sec-0.5.6.tar.gz.
File metadata
- Download URL: agent_gate_sec-0.5.6.tar.gz
- Upload date:
- Size: 337.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16abd19d3995f8556753a763a8c4a03158a0ebbcfbef8d9f1b0a8cc30a7784d4
|
|
| MD5 |
3f71e76257e8617fb40a958c9e1a27e5
|
|
| BLAKE2b-256 |
3d25478a9fa4c0619ab5d5a0de308de7d55859b120a9f563bbba13b3de225ed3
|
File details
Details for the file agent_gate_sec-0.5.6-py3-none-any.whl.
File metadata
- Download URL: agent_gate_sec-0.5.6-py3-none-any.whl
- Upload date:
- Size: 257.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34f0d00782a17b4bcebf2463d934ffb6db8b52f26056f0bd38f0a5e96c2c6018
|
|
| MD5 |
2d6200847f9b4e801ad2765a1fce3277
|
|
| BLAKE2b-256 |
5d8e902e2e275fae3ded994f096d6afead0b2ca4e2ebee133a6cc7ae27f6c919
|