ARTICLE · 1114907
我们给所有 AI 调用加了一层网关:脱敏、拦截、审计
我是老张,干了十年运维,正在学 AI。这里只写我亲手做过、翻过车的东西。
上一篇我写完 AI 安全风险清单之后,有同行在后台问我一个很实在的问题:
"道理我都认,但我们发了通知、贴了规范、开会讲了三遍——两周之后大家该怎么用还怎么用。 怎么办?"
这个问题问到了根子上。因为它们全都是"依赖自觉"的措施,而自觉在真实的故障现场是最先被牺牲的东西。
我们自己也走过这段。后来我换了思路:别去要求人,去改通道。 这一篇讲我们怎么做的——在 AI 调用这条路上加了一层中间层,做三件事:出去之前脱敏、违规的内容拦住、全部记下来。
先说一句基调:这层的目标不是"禁止大家用 AI",是"让大家可以放心用 AI"。 这个目标差异决定了它的设计形态完全不同——前者会做成审批地狱,后者才可能被真的用起来。
一、三条设计原则(决定成败的其实是第一条)
这三条是我们被现实教育出来的,顺序就是优先级:
| ① 用户无感 | ||
| ② 默认安全 | ||
| ③ 可审计 |
第一条最重要,也是最多人做错的一条。
我见过最典型的错误做法是:做一个审批系统,员工每次要发数据给 AI 之前先提交申请、等人批准。这套东西在上线的第二周就会被绕过——因为凌晨三点没人会等审批,他会直接用手机。
所以我们的取舍是:宁可漏拦一些,也要保证零摩擦。 这条听起来很不"安全",但它才是能活下来的方案。
二、这层放在哪里:三种位置的选择
架构上有三个位置可以放这层,各有取舍:
| 出口代理 | ||||
| 本地客户端插件 | ||||
| 内网模型 |
我们最后选的是"出口代理 + 关键场景内网模型"的组合——因为纯代理挡不住手机,而纯内网模型成本太高且效果打折扣。代理解决"大多数无意的疏忽",内网模型解决"确实敏感的场景"。
这里必须说一句实话:没有任何一种方案能拦住一个铁了心要把数据发出去的人。 所以我们的目标从一开始就不是"100% 拦截",而是——
把"高频无意识的疏忽"变成"低频有意识的违规"。
前者是每天发生几十次的、没人觉得有问题的行为;后者是罕见的、留下了痕迹的行为。这个差别就是这层网关的全部价值。
三、脱敏层:三个必须做对的细节
脱敏本身不难,难的是三个细节。我们前面都栽过。
细节一:可逆映射——AI 的回答里会带着占位符回来
这是我们最早没想到的问题。
我们把日志里的 IP 替换成 IP_1、服务名替换成 SVC_A 之后发给模型。模型分析完回来,回答里写的是"建议检查 SVC_A 到 IP_1 的连接数"——这个回答没法用,因为我不知道 SVC_A 是哪个服务。
所以脱敏必须是可逆的:本地维护一张映射表,模型返回后再把占位符还原。
关键的一条规则:映射表只存在本地,永远不发给模型。 这张表本身就是一份敏感资产(它等于你系统的真实拓扑),必须和配置一起管控。
细节二:脱敏的对象不只是日志正文
我们踩过的坑:日志正文脱敏做得很好,但文件名、URL 路径、HTTP Header、报错栈里的路径全都带着真实信息。
比如一个文件名叫 prod-order-db-backup-20261001.sql 的日志——正文打了码,文件名把生产库的全名暴露了。
所以清单要覆盖:正文、文件名、路径、Header、URL 参数、报错栈、注释、配置里的标识符。 这份清单是活的,每次发现新的泄露点就加一条。
细节三:脱敏规则不许用 AI 判断(上一篇的老话)
再强调一次,因为总有人想在这里走捷径:让 AI 判断"这段数据敏不敏感",等于先把数据发了出去。
脱敏必须是确定性的:正则、字段白名单、字典匹配。规则可以错(误杀或漏放),但规则必须是可复现、可审计、可解释的。 一个说"我觉得这段不敏感"的黑盒,在安全上没有任何价值。
四、拦截层:三类规则,三种处置
我们把规则分了三类,对应三种处置动作。这个分级很关键——如果所有规则都是"硬阻断",这套东西会被投诉到死。
| 硬阻断 | |||
| 脱敏放行 | |||
| 记录告警 |
注意第二类是主体,占了规则数的绝大部分。 一套只有"拦"和"放"两档的系统,最后一定会把用户逼走——因为安全规则天然会误杀,而误杀一次就让人失去信任。
分三档的意义在于:不需要拦的东西就别拦,只需要知道的东西就只记录。
关于第三类,有个小设计我觉得挺有用:告警不发给使用者本人,发给安全负责人。 因为我们要观察的是"模式"(这个人这段时间反复在处理客户数据),不是单次行为。给本人发通知,只会让他在下次绕过。
五、审计层:记五个字段就够,但必须有"月度视角"
审计最常犯的错是"什么都记"——记了一堆日志,从来没人看。所以我们只记五个字段:
| 数据分类 | 最关键的一维 | |
最关键的是第四维"数据分类"——它让我们不需要看内容,也能发现异常模式。
我举个例子:我们有一次月度看板发现某个同事连续三天大量发送"客户数据"类请求。不是恶意,是他在做一个客户数据迁移的排查——但这个行为本身应该被知情,因为那批数据的敏感等级很高。 我们后来给他开了内网模型的权限,问题就解决了:他需要做的事还是能做,只是数据不出去了。
这个案例告诉我们审计的真正价值不是抓人,是发现"流程缺了什么"。
月度视角可以看三张表(都很简单):
拦截 Top10:哪些规则拦得最多 → 说明大家的习惯在哪里,也说明哪些场景最需要一个合规的替代方案 误杀率:被拦的请求里有多少是误判 → 这个数字高说明规则太粗,会逼人绕过 数据分类分布:各类数据的调用比例变化 → 客户数据类的占比持续上升,就该考虑上内网模型了
六、两个副作用,和一点真实收益
我不想把这层写得像个完美方案,所以副作用也写出来。
副作用一:规则误杀率高,需要持续调
上线第一个月,我们的误杀率大概在 30%——三分之一的请求被误标(比如把正常的 10.x 网段当成真实 IP 拦了、把业务字段名当成敏感词拦了)。
这一个月的主要工作就是调规则,而且必须每天调。如果没有人负责持续维护,这套东西会在第三周边际糊掉,然后被彻底关掉。 这是我们最大的教训:安全机制不是"上线",是"运营"。
副作用二:总有人会绕过,所以要给一条"更好的路"
我们上线后不久就发现有人在用手机发数据。查下来原因很朴素:代理有个 5 秒延迟,他觉得慢。
这就是第一条设计原则(用户无感)的意义所在——任何增加摩擦的东西都会被绕过,哪怕摩擦只有 5 秒。
怎么解决?两个动作:一是把延迟优化掉(性能是安全的一部分,这句话一点不夸张);二是给"确实需要发敏感数据"的场景提供一条合法的路——我们开了内网模型账号,申请一次、长期有效。
关键是这条合法的路必须比绕过更省事。 如果合规路径比违规路径更麻烦,那你的合规就是摆设。
真实收益:团队的心里负担轻了
这一点我原本没预期到。
上线三个月后,我在一次沟通里听到一句话:"现在不用每次发之前都纠结一下了。"
这句话其实说明了一件事:之前那种"要不要发"的纠结,是真实存在的心理负担。 每个人都知道可能有风险,但没人知道边界在哪,所以每次都在模糊地带犹豫。
有了这层网关之后,规则变成了明确的:该脱敏的自动脱敏,该拦的会拦,发出去的东西有记录。 大家不需要判断"我能不能发",只需要正常工作。
从这个角度看,这层网关最大的价值不是防住了多少次外泄,是把一个模糊的责任问题变成了一个明确的机制问题。
七、红线:六条
不要让这层遇到任何一点麻烦。 摩擦是绕过的唯一驱动力。性能、延迟、操作步骤,在这套系统里都是安全指标。 不要用 AI 判断数据是否敏感。 判断之前数据已经出去了。脱敏必须确定性、可复现、可审计。 不要只做"拦",要有"脱敏放行"这一档。 一套只有拦和放的系统必然被投诉到关闭。绝大多数请求应该是"改一改就让它走"。 不要把映射表发给模型。 占位符映射表等于你的真实拓扑,它必须只存在本地、和配置同级管理。 不要只做阻断不做记录。 阻断解决单次行为,记录解决模式问题。审计的价值在于发现"流程缺了什么",不是抓人。 不要忘了权限这一层。 网关管的是"数据出口",权限管的是"AI 能做什么动作"。这是两件事,缺一个都不成立——一个只看不写的 AI,和一次没被记录的外泄,同样危险。
八、收个尾
这篇的核心一句话:别去要求人记得脱敏,去让通道默认脱敏。
我们走了两段路:先发规范、再开大会,两周后回到原点;然后才动手改通道,三个月后成了日常。这两段路的关键差别是——前者要求人在最不方便的时刻做出正确判断,后者把这个判断从人身上拿走了。
这也是我这一年最深的一个体会:所有"依赖自觉"的安全措施,都会在真实故障的压力下失效。 能做成的机制,都是不需要你想起它的机制。
下一篇我写这条链上最后一块拼图:内网模型——用一台机器跑起来我们自己的 AI,什么场景该走它、什么场景不必走、以及真实的效果差距有多大。 关注「AI运维实战」,不迷路。