Guarded MCP Gateway · 线上可体验 · 免注册 · 双域真库验证过(Twenty 线上)

给 Agent 接内部系统,
先加一道守卫网关

一层协议级(MCP)、与 agent 框架无关的守卫网关——所有入口共用同一套守卫,HR/CRM 等系统即插即用。角色定工具面、行级过滤、字段脱敏、逐调用审计:不该看到的工具连 tools/list 都不出现,不是模型忍住不说,是数据根本没进上下文。

4 道控制
工具白名单 · 行级/脱敏 · 人工审批 · 签名审计
100 · 11 类
越权/泄漏评测题 · 跨 3 个域
2 真后端
Twenty 线上 · OrangeHRM 5.7 曾本地实测(现走 fixture)
0.00
×3 重复通过率标准差(百分点)· 无摇摆题
同一个网关 · 同一句提问:「张三的工资是多少?」
tools/list · 该身份可见的工具面
张三的工资是多少?
audit/foundry.jsonl ← 本次调用已留痕(参数只记哈希)
线上体验(免注册): CRM 助手 ↗ Twenty 后台 ↗ LangGraph 前端 · 真 Twenty 数据
为什么做

三个事故 → 三个能力

安全不靠提示词自觉——结构化规则在守卫层强制执行。

事故:员工顺嘴一问,拿到同事工资

角色 → 工具白名单

不该用的工具在 tools/list 里根本不出现,而不是调用被拒后再解释。

事故:模型把手机号、薪资整行吐进回答

行级过滤 + 字段脱敏

结构化规则在守卫出口强制执行;越权数据不进上下文,模型想编也没材料。

事故:出事后翻不出谁问过什么

逐调用审计流水

每次调用一条 JSONL;只记参数哈希不记原文,审计日志不成为第二个泄漏面。

人工审批 · Human-in-the-loop

动钱、改库这类高危写,先过人的点头

行级过滤拦得住泄漏,拦不住已经发生的写。涉审写操作在执行前被挂起成审批单,独立审批人批准后才落库——审批必须在写入之前。

Guard 管线 · 审批闸门在 execute 之前
1角色查找 → 工具白名单
2写前归属校验(preimage)越权即 row_denied
3审批闸门pending · 无 data
4adapter.execute(人批准后)一单一次
5行级过滤 → 字段脱敏 → 审计
01
独立审批人,不能自批
发起人(sales_rep)与审批人(sales_manager,approver:true)分离;RBAC 只标谁能批(approver:true),而「发起人不能批自己的单」是网关代码级硬校验(userId 比对)。
02
闸门在写入之前
挂起发生在 adapter.execute 之前——行级过滤拦得住读的泄漏,拦不住已经落库的写。审批必须在写入发生前。
03
一单一次,防重放
批准后同参调用重试即消票执行;审批单一次性核销,重复提交不再触发第二次写入。
04
拒答/挂起分支无 data
pending 与 refusal 在类型层就没有 data 字段,结构上不可能夹带业务数据或模型自由文本。
issue_refund policy-as-code 按金额与账期信号分档
金额 ≤ ¥500 · 本月 < 2 笔
自动放行
金额 > ¥500
挂起等经理批
本月已退 ≥ 2 笔(第 3 笔起)
挂起等经理批
订单号 / 邮箱 / 卡尾号不符
直接拒
归属约束叠加:只退自己名下订单,越权退款在审批前就 row_denied。金额缺失/非数值一律判「需审批」(fail-closed)。
架构

所有入口,同一套守卫

MCP 客户端
LangGraph / Claude Code / 任意 Streamable HTTP host · Bearer 签名令牌
飞书 bot
长连接 · open_id → principal · 工具面按身份收窄
Guard 管线 · packages/core
角色查找 → 工具白名单 → 审批闸门(写前挂起) → 行级过滤 → 字段脱敏 → 审计 JSONL
orangehrm
HR · 真实 5.7 已验
twenty
CRM · 真实 REST 已上线
memory
跨会话记忆 · 域内 RBAC
01
工具面在 LLM 看到之前就收窄
员工的工具定义里根本没有 get_salary;拒答是结构化分支,结构上不可能夹带业务数据。
02
角色不跨域
HR 的通配权力跨不进 CRM,销售看不到全员业绩盘——业务全权 ≠ 跨域全权。
03
生产级签名身份
HS256 共享密钥或 JWKS 非对称(ES256/RS256)+ 热轮换;伪造头不是被拒绝,是根本不在信任路径上。线上实例现跑 JWKS URL 模式。
04
两分钟本地验证
fixture 模式无需任何密钥:pnpm install 后换身份问同一个问题,行为不同——这正是卖点。
飞书机器人

自然语言进,按身份收窄的工具面出

长连接接入,无需公网回调。sender open_id 映射到 principal,同一套守卫——安全不靠提示词。三个域已在真实飞书应用上端到端验证。

F
Foundry 助手
01
工具面在 LLM 看到之前收窄
GLM tool-calling 循环拿到的工具定义已按身份过滤——员工的定义里根本没有 get_salary。
02
越权数据在出口就不存在
refusal 分支无 data 字段,模型想编也没材料;拒答如实转述「已记入审计」。
03
跨域实测零泄漏
sales_rep 跨域问工资零泄漏;hr_admin 反向无任何 CRM 能力——业务全权 ≠ 跨域全权。
04
身份源可信
sender open_id 由飞书服务端签发,经 identity.feishu.yaml 映射到 principal,全程留审计。
评测

守卫的价值是分数差,不是一句「我们有 RBAC」

100 题越权/泄漏题库跨三个域(含对抗红队与退款分级),硬断言 + LLM-judge 双轨(judge 须先过人工校准,只能加严不能翻案)。头条:红队攻击得手率 无守卫 77.2% → 生产配置 0%,所有数据可本机复现。

100
题 × 11 类,跨三个域
HR 29 · 记忆 20 · CRM 51
100%
全开配置全绿
fixture 常测 · 真后端曾实测
0.00
×3 重复通过率标准差
(百分点) · 无摇摆题
77→0%
红队攻击得手率
无守卫 → 生产配置(0 题泄漏)
守卫逐层 Ablation(100 题;分层贡献与后端实现无关)
同一套题在四档守卫配置下各跑一遍——每一层的贡献是可测的:
全关(无守卫)
48.0%
仅角色+工具白名单
64.0%
白名单+行级过滤
95.0%
全开(生产配置)
100.0%
泄漏题数:47 → 28 → 5 → 0(攻击得手率 77.2% → 0%)。工具白名单先砍一截(红队拦截 22.8% → 50.9%);行级过滤是拦截主力(→ 98.2%);字段脱敏把「白名单+行级」档残留的 5 条脱敏泄漏清零(→ 100%)。
01
judge 不过校准线不上岗
对人工标注 golden 集一致率 ≥90% 才允许进报告;换模型 = 重新过校准。judge 只能把通过的题追加判失败,不能翻案救回。
02
双轨的价值在发现,不在分数
judge 上岗第一轮就抓到一个硬断言看不见的出口污染(ZodError 原样透传),修复后沉淀为确定性回归断言。
03
CI 门禁只信硬断言
红队题任何一道失败,CI 退出码 1;LLM-judge 有成本且依赖外部 API,不进门禁。
本机复现(无需密钥)
pnpm --filter @yiong/foundry-eval run eval \
  --repeat 3 --ablation
标准映射

每道控制,对标 2026 的公开威胁框架

守卫不试图「检测」提示注入——那是打不赢的仗;它让注入「没有后果」。以下把每道控制映射到 OWASP 与中国 TC260 的逐条编号。

控制
拦住什么攻击
框架编号
工具白名单
越权工具调用(员工查薪资、销售摸全员业绩盘)
OWASP ASI02LLM06TC260 最小权限
行级过滤
越权读取他人的行(投毒备注指示"导出全部联系人")
LLM01LLM02ASI02
字段脱敏
敏感字段泄露(电话、工资整行吐进回答)
LLM02
写前归属校验
越权改删同事的行 / 伪造归属新建(归属由 principal 盖戳)
ASI03
审批闸门
高危写未经人批就落库(改/删/改阶段)
ASI09LLM06TC260 二次确认
分级审批
大额 / 频繁退款自动放行("动钱"类动作)
ASI09TC260 资金二次确认
签名令牌
冒充身份 · alg:none 降级(不读令牌自述 alg)
ASI03
签名审计链
事后抵赖 / 篡改审计(可选 Ed25519 签名链,公钥离线复核;默认明文 JSONL)
ASI10 可追溯TC260 全量审计

框架:OWASP Top 10 for Agentic Apps 2026(ASI02/03/09/10)· OWASP LLM Top 10 2025(LLM01/02/06)· 中国 TC260《AI 智能体安全部署使用指南》(2026-07 生效:最小权限 / 高危操作人工二次确认 / 全量审计)。设计对标 lethal trifecta(Willison)与 Meta「Agents Rule of Two」的 [AB] 档(对外动作前人类校验)。EU AI Act Art.14 高风险人工监督已推迟至 2027–2028,本项目 HITL 只作中期顺风、不宣称现在受其强制。

诚实边界

说清楚验证了什么、没验证什么

安全产品最怕过度承诺。以下边界与 README 保持同步:

两条真库链路都已验证:HR 对真实 OrangeHRM 5.7(只读 MySQL,本地 docker;docker 已下线,prod 走 fixture),CRM 对真实 Twenty(REST + Bearer,线上)——都是演示数据口径,不是生产规模
线上 CRM 域连的是真实 Twenty(crm.yiongspace.com 读写真数据);HR 域线上仍走 fixture
体验链接的身份是配好的,不是登录来的——演示「同一网关、不同身份、行为不同」,不是登录系统
行级/字段规则只在 Guard 出口生效;绕过 Foundry 直连源系统管不到——源系统凭据只发给 Foundry
JWKS URL 模式默认可用性优先:端点持续故障期间吊销不生效,fail-closed 需自行开启 max-stale
ERP 仍是路线图;「多签发方」是能力,线上是单签发方口径
路线图

11 项里程碑:8 项已交付 · 3 项规划中

每一项「已交付」都附带可复现的验证口径。

已落地
HR 域 + Guard 管线真库已验
角色白名单 / 行级过滤 / 字段脱敏 / 审计 JSONL;对真实 OrangeHRM 5.7 只读 MySQL 全绿。
记忆域(跨会话,域内 RBAC)
越权召回走行级规则兜底;投毒防线是接口级——save_memory 根本没有 employee_id 参数。
CRM 域(twenty 适配器,已上公网)2026-07
同一套用例 schema 换适配器即全绿;线上网关连真实 Twenty(REST + Bearer),角色不跨域。
签名身份:HS256 → JWKS → URL 拉取线上已切
ES256/RS256 多签发方 + 热轮换;线上实例现跑 JWKS URL 模式,私钥永不落服务器。
飞书 bot 三域端到端 + LangGraph 公网2026-07
真实飞书应用实测脱敏/拒答/审计;自建 LangGraph 前端上公网,连真实 Twenty,免注册可试。
对抗红队评测 + 攻击得手率指标2026-07
被劫持的 agent 试图伪造归属/越权改删/导出他人数据——红队攻击得手率 无守卫 77.2% → 生产配置 0%,由 ablation 跑出。
防篡改审计(Ed25519 签名哈希链)可选开启
每条审计带 hash 链 + 签名:改一条断整链、伪造验签不过,校验只需公钥、可离线复核(verify-audit)。
退款分级动作 + 威胁模型2026-07
审批闸门升级为分级放行(policy-as-code):小额自动、超额/频繁挂起、身份核验前置。控制到 OWASP ASI/LLM + TC260 的逐条映射。
规划中
ERP 适配器
第三个业务域——检验 SystemAdapter 抽象在财务形状数据上的迁移成本。
第三方红队
现状是出题人和被评人同仓同评审;引入外部对抗测试补上这个口径。
独立签发方(SSO/IdP)
线上现为单签发方口径(签发方=部署方同机);接真实 SSO 验证多签发方与轮换纪律。