内容
# bawbel-gate
[](./LICENSE)
[](./pyproject.toml)
[-orange)](#v1.0-feature-complete-pre-release)
[](#install-development)
[](./DESIGN.md)
[](https://scorecard.dev/viewer/?uri=github.com/bawbel/gate)
[](./SECURITY.md)
[](./CODE_OF_CONDUCT.md)
[](./CONTRIBUTING.md#pull-requests)
MCP 代理运行时强制执行:能力清单、会话污染跟踪和不可配置的二元组三重奏不变性,具有哈希链审计日志。
## 状态:v1.0 功能完整(预发布)
完整的强制执行核心、完整性层、操作栈、嵌入式控制台和舰队中心均已实现。327 个测试通过。公共 API 稳定;发布包尚未在 PyPI 上发布。
## 问题
代理主机对上下文中的所有内容都授予了平等信任。工具响应、技能文件和用户消息在模型中具有相同的指令权限,因为模型处理一个令牌序列,没有权限边界。这在模型层中是无法解决的。bawbel-gate 修复了后果层:一个确定性的代理,位于代理主机和 MCP 服务器之间,强制执行每个组件的能力授予、会话污染和三重奏不变性,而不管模型决定如何。
## 工作原理
```mermaid
flowchart LR
Host["Agent Host<br/>(LLM + user)"] -->|"MCP tool calls<br/>(JSON-RPC)"| Gate
subgraph Gate["bawbel-gate"]
direction TB
Manifest["1. 能力清单<br/>匹配工具名称授予"]
Taint["2. 会话污染<br/>私有数据/不受信任的内容"]
Trifecta["3. 三重奏不变性<br/>规则二,不可配置"]
Manifest --> Taint --> Trifecta
end
Trifecta -->|allow| Server[("MCP Server")]
Trifecta -->|approve| Human[["人工审批"]]
Human -->|granted| Server
Trifecta -->|deny| Blocked["Blocked + logged"]
Gate --> Audit[("哈希链<br/>审计日志")]
Audit -.push only.-> Hub[["bawbel-hub<br/>(可选的舰队)"]]
```
来自代理主机的每个工具调用都会经过三个检查,然后才能到达真正的 MCP 服务器:是否匹配该工具的能力授予,该会话的污染状态是否超过了二元组阈值,三重奏不变性是否需要人工介入。每个决定,无论是否允许,都被写入一个仅追加的哈希链审计日志中。网关从不读取模型输出来做出这些决定——只使用结构化的 JSON-RPC。
## 已构建
| 里程碑 | 组件 | 状态 |
|---|---|---|
| M0 | 项目脚手架、模式、迁移脚本 | 完成 |
| M1 | MCP 多路复用器、学习模式、审计骨架 | 完成 |
| M2 | 策略引擎、污染跟踪器、三重奏不变性、审计链 | 完成 |
| M3 | 完整性锁定、漂移检测、`harden --ave` | 完成 |
| M4 | 审批 UX 预算、良性语料库、延迟门控 | 完成 |
| M5 | OTel 跨度、CEF/syslog 导出、姿态报告 | 完成 |
| M6 | 嵌入式控制台 + 控制台 API | 完成 |
| M7 | bawbel-hub:舰队接收、状态存储、注册 | 完成 |
### 策略引擎(M2)
每个 DESIGN.md 5.2 的六步决策管道:
1. 按工具名称(精确则通配符)匹配授予。
2. 无匹配 -> `deny: no_grant`。失败关闭。
3. 条件失败 -> `deny: condition_failed`。不回落到下一个授予。
4. 参数守卫:秘密扫描和字节上限。
5. 污染规则:`lattice_min` 仅限,影响永远不会上升。
6. 三重奏不变性:`private_touched AND untrusted_seen AND external_comms` -> 至少 `approve`。不能被任何清单字段或标志禁用。
效果格子:`allow (2) > approve (1) > deny (0)`。拒绝吸收所有。
### 三重奏不变性
防止提示注入外泄的二元组保护。当会话已触摸私有数据、看到不受信任的内容(工具响应、网页抓取、问题正文)并调用具有外部通信能力的工具时,必须有人审批。这不可配置。任何清单字段、环境变量或调试标志都无法绕过它。
### 完整性锁定(M3)
工具模式在审查时被哈希(`bawbel-gate verify`)。在每个会话启动时,网关重新哈希并比较。任何突变——中毒描述、注入工具、地毯式拉取——都被检测为漂移。服务器被暂停(`on_drift: suspend`),所有工具都被保留,直到操作员运行 `bawbel-gate verify --accept` 以审查差异。
### 审计日志(M2)
仅追加 JSONL。每个记录都带有 `hash = sha256(canonical(record) || prev)`。链按需验证(`bawbel-gate audit verify`)。参数有效载荷被哈希,不存储,默认情况下(`args_sha256`)。法医记录是本地的、防篡改的;OTel/SIEM 导出是其上的操作馈送。
### 嵌入式控制台(M6)
`bawbel-gate serve --console 127.0.0.1:7317` 启动一个环回 HTTP 服务器。启动时打印一个随机 bearer token。端点:
| 端点 | 方法 | 描述 |
|---|---|---|
| `/v1/state` | GET | 完整快照:会话、服务器、待处理审批、审计头 |
| `/v1/events` | GET | 审计记录的 SSE 流 |
| `/v1/approvals/{id}` | POST | 控制台审批通道(竞赛安全:第一个写入者获胜) |
| `/` | GET | 嵌入式 UI 包 |
控制台除审批端点外均为只读。无端点可发出工具调用、编辑清单或清除污染;这些仍保持 CLI 独占。
`/v1/state` 反映实时会话污染和每个服务器的清单状态:

### bawbel-hub(M7)
团队运行多个网关的自托管舰队管理器。仅推送:网关将审计记录推送到中心;中心从不连接。
- 接收服务(`POST /v1/gates/{gate_id}/records`):按会话验证哈希链,存储记录 ID 为 `(gate_id, session_id, seq)`,隔离并引发 `gate.chain.gap` 以示篡改证据。
- 舰队状态存储:SQLite(评估)或 Postgres(生产),可从原始记录完全重建。
- 单次注册令牌:`bawbel-gate hub token new`,然后 `bawbel-gate enroll --hub URL --token TOKEN`。
- 舰队姿态 API:`GET /v1/fleet/state` 返回每个网关的 allow/approve/deny 计数、三重奏跳过和漂移事件。
## 安装(开发)
```bash
git clone https://github.com/chaksaray/bawbel-gate
cd bawbel-gate
pip install -e ".[dev]" --break-system-packages
pytest # 327 tests
pre-commit run --all-files # lint gate
```
启用 OTel 导出:
```bash
pip install -e ".[dev,ops]" --break-system-packages
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
```
## 快速开始
将您的 MCP 客户端指向网关,而不是直接指向服务器:
```json
{
"mcpServers": {
"bawbel-gate": {
"command": "bawbel-gate",
"args": ["serve", "--config", "gate.yaml"]
}
}
}
```
无清单?先运行学习模式:
```bash
bawbel-gate serve --config gate.yaml --learn
bawbel-gate learn report
bawbel-gate learn synthesize --out manifests/
```
在强制执行前检查您的清单:
```bash
bawbel-gate lint manifests/ --forbid-effect allow --tools-with external_comms
```
加固清单以对抗已知攻击模式:
```bash
bawbel-gate harden --ave AVE-2026-00041 --manifest manifests/github-mcp.cap.yaml --write
```
`harden` 将 AVE 记录的缓解部分合并到您的清单中,并在写入任何内容之前打印差异(删除 `--write` 以预览)。
在审查后锁定工具模式:
```bash
bawbel-gate verify tools.json manifests/github-mcp.cap.yaml --accept
```
最小清单(参见 DESIGN.md 4.1 注释版本):
```yaml
schema: bawbel/capability-manifest/v1
subject:
kind: mcp-server
name: github-mcp
provenance_class: tool.response.github
instruction_authority: none
trifecta:
private_data: true
untrusted_content: true
external_comms: true
grants:
tools:
- name: get_issue
effect: allow
- name: create_pull_request
effect: allow
conditions:
args.base_repo: {pattern: "myorg/*"}
- name: "*"
effect: deny
```
## CLI 参考
```
bawbel-gate serve --config gate.yaml [--learn] [--console HOST:PORT]
bawbel-gate audit verify FILE | tail FILE [--follow]
bawbel-gate learn report | synthesize --out DIR
bawbel-gate lint MANIFEST_DIR [--forbid-effect EFFECT] [--tools-with FLAG]
bawbel-gate verify TOOLS_JSON MANIFEST [--accept]
bawbel-gate harden --ave AVE_ID [--manifest FILE] [--write] [--allow-unreviewed]
bawbel-gate posture [--audit-log FILE] [--json]
bawbel-gate clear --session SESSION_ID --confirm [--audit-log FILE]
bawbel-gate enroll --hub URL --token TOKEN
bawbel-gate hub serve [--db FILE] [--host HOST] [--port PORT]
bawbel-gate hub token new [--db FILE]
```
## 拒绝原因
DESIGN.md 6.2 中的封闭集。每个拒绝原因都有一个:
| 原因 | 原因 |
|---|---|
| `no_grant` | 无匹配工具名称的授予 |
| `condition_failed` | 匹配授予的条件未满足 |
| `trifecta_third_leg` | 三重奏不变性触发;需要人工审批 |
| `guard:secret_scan` | 参数包含秘密模式 |
| `guard:byte_cap` | 参数超过出站字节上限 |
| `approval_timeout` | 人工未在审批窗口内响应 |
| `approval_denied` | 人工拒绝审批请求 |
| `drift:suspended` | 服务器因工具模式漂移而暂停 |
| `parse_error` | JSON-RPC 请求格式错误 |
## 可告警事件(OTel / CEF)
六类事件作为结构化记录发出,与导出器无关:
| 事件 | 默认严重程度 | 含义 |
|---|---|---|
| `gate.drift.detected` | 高 | 审查后供应链突变 |
| `gate.trifecta.trip` | 中 | 注入前提条件达到 |
| `gate.deny.burst` | 中 | 代理在授予表面以外探测 |
| `gate.secretscan.hit` | 高 | 通过参数尝试外泄 |
| `gate.approval.timeout` | 低 | 代理未触发人工门控 |
| `gate.chain.gap` | 严重 | 审计日志篡改指示器 |
## 非目标
- 不是提示过滤器。每个强制执行决定仅读取结构化的 JSON-RPC;网关从不咨询模型说了什么。
- 无 fail-open 模式,无可配置的三重奏绕过,无“完全信任此服务器”切换。
- 任何部署中都无网关的入站连接。
- 默认情况下无参数有效载荷存储。记录携带 `args_sha256`。
## 文档
- [DESIGN.md](./DESIGN.md) - 规范性规格。
- [ARCHITECTURE.md](./ARCHITECTURE.md) - 生态系统地图。
- [IMPLEMENTATION_PLAN.md](./IMPLEMENTATION_PLAN.md) - 里程碑序列。
- [BAWBEL_GATE_MITIGATIONS_SPEC.md](./BAWBEL_GATE_MITIGATIONS_SPEC.md) - 强制执行策略详情。
- [docs/LANGUAGE.md](./docs/LANGUAGE.md) - 规范术语。
## 相关项目
- [AVE](https://ave.bawbel.io) - 行为漏洞分类标准,bawbel-gate 强制执行(`bawbel-gate harden --ave`)。
- [bawbel-scanner](https://pypi.org/project/bawbel-scanner/) - 静态检测代理代码库、MCP 配置和服务器卡。
- [PiranhaDB](https://api.piranha.bawbel.io) - 查询 AVE 语料库 API。
## 安全
参见 [SECURITY.md](./SECURITY.md) 以获取披露政策。不要为漏洞打开公共问题。
## 许可证
Apache-2.0。网关完全独立且开放。bawbel-hub(多个网关的舰队管理)是付费层级;参见 DESIGN.md 14 以获取边界。
## 贡献
参见 [CONTRIBUTING.md](./CONTRIBUTING.md)。在修改 `policy/`、`taint/`、`audit/` 或 `integrity/` 之前,请阅读 DESIGN.md;行为与规范不同需要先修改 DESIGN.md,而不是更大的差异。提交必须带有 DCO 签名(`git commit -s`);参见 [GOVERNANCE.md](./GOVERNANCE.md) 以获取决策者信息,以及 [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) 以获取我们如何对待彼此的信息。