很多团队做知识检索时,权限设计停在了两个位置:前台页面控制谁能看什么,工具调用控制谁能改什么。看起来已经足够稳,但 AI agent 一旦开始在后台主动检索、拼接证据、生成摘要,这两层就不够了。因为越权不一定发生在最终展示界面,更常发生在更早的地方:某个不该被这位用户看到的片段先进入候选集,被 reranker 抬了上来,再被模型吸收成一句看似中性的回答。即使系统最后没有原文泄露,事实本身也已经被带了出来。
这就是为什么 retrieval 不能假设自己只是“搜东西”。它本身就是权限边界的一部分。索引里存着什么、查询时先按什么范围过滤、派生摘要是否继承原始 ACL、引用展示时是否需要二次裁剪,这些问题只要少一个,系统就会出现一种非常难解释的风险:应用层看起来没越权,但 agent 实际已经在更底层借检索做了越界推断。
所以 Access-Controlled Retrieval 真正要解决的,不是把 ACL 复制一份到索引里,而是让权限、租户隔离和引用边界在知识层里保持同一套语义。没有 ACL propagation,Knowledge Plane 很容易变成平台里最会“偷偷知道太多”的那一层。
建议配合 AI agent Knowledge Source Onboarding Contract、AI agent Knowledge Plane Architecture、AI agent Multi-tenant Agent Platform 和 AI agent Data Redaction 一起看。
先给结论:检索层的权限问题,不只是“能不能搜到”,还包括“能不能被拿来推断”
| 控制位置 | 它能挡住什么 | 它挡不住什么 |
|---|---|---|
| UI / API 鉴权 | 用户直接打开不该看的页面或接口 | agent 在后台先看到片段再生成结论 |
| Tool scope | 不该调用的写入或高风险动作 | 检索候选本身就带出的敏感事实 |
| Retrieval ACL | 不让不该看的 source 进入候选集 | 需要继续和 citation、summary 继承逻辑配合 |
很多系统之所以在合规审查时卡住,就是因为它们默认“只要最终答案没贴原文,就不算越权”。这在传统搜索里可能还能争辩,在 AI agent 场景里通常不成立。因为模型一旦读过不该读的材料,后续哪怕只是抽象总结,也已经跨过了原始权限边界。
ACL propagation 的关键,不是把 source 权限抄一遍,而是让派生对象持续继承它
知识层里真正会不断长出来的问题,是派生对象比原始文档活得更久、流得更远。原文可能受部门权限保护,但 chunk、summary、embedding、rerank feature、甚至被写进 memory 的事实摘要,如果没有继承原始 ACL,很快就会变成新的越权入口。
一个更成熟的 ACL propagation 至少要覆盖:
- source 到 chunk:每个证据片段继承来源的租户、角色和环境边界
- chunk 到 index:索引分片、过滤投影和缓存 key 带上 ACL 维度
- chunk 到 summary / citation:任何派生摘要都标记自己继承自哪些原始权限集合
- retrieval 到 answer:当最终答案要引用或概括证据时,再次检查当前会话是否仍有资格消费这些事实
这看起来像是多做了一层工作,实际是避免系统在一次又一次“先搜到了再说”的便利做法里慢慢把权限边界磨平。
单索引后过滤、预过滤和多索引隔离,各自的代价完全不同
| 模式 | 看起来的优点 | 风险 | 更适合什么 |
|---|---|---|---|
| 单索引后过滤 | 实现快,索引管理简单 | 候选集已先看见不该看的内容,最容易出现隐性越权 | 低敏、单租户内部场景 |
| 查询前预过滤 | 候选进入前先缩权限范围 | 依赖 ACL projection 正确且实时 | 大多数中等敏感检索场景 |
| 多索引 / 分片隔离 | 权限边界天然清晰 | 存储和运维复杂度高 | 多租户、高敏、跨区域知识平面 |
很多团队会本能地偏向第一种,因为它最省事。问题是 AI agent 不只是“返回几个文档链接”,它会对候选集做语义消费。只要候选已经包含了不该看的内容,后面的后过滤就更像补救,不像边界本身。
Summary、Cache 和 Memory 这三层最容易把原始 ACL 悄悄抹平
真正的事故往往不是原文泄露,而是派生层过度复用。某个团队为了提升体验,把多个文档的检索结果先总结成主题摘要,再缓存给后续相似问题复用。单看这个设计很合理,直到他们发现:摘要并没有带来源 ACL,结果一个只看得到公共文档的角色,也开始收到基于内部规程总结出来的建议。
这就是为什么知识层的缓存和派生层不能只看内容相似度。它们必须同时看 authority scope。更稳的做法通常是:任何派生摘要、embedding cache、evidence summary 都必须带 source ACL envelope;一旦当前会话的 scope 缩小,这些派生对象即使内容匹配,也不能继续被复用。
失败案例:共享 FAQ 索引没直接泄露原文,但让低权限用户推断出了高权限规则
某团队把多个部门 FAQ 合进一套统一知识索引,希望 agent 可以更快回答内部问题。表面上他们做了结果页权限控制:用户看不到原文链接,也打不开不属于自己的文档。可很快支持就发现,某些普通角色虽然没拿到原文,却能从 agent 的回答里推断出只有管理层才知道的审批阈值和处理原则。
根因并不复杂:retrieval 候选集没有做预过滤,系统只是在最终展示前把链接藏起来。模型却早已消费了这些候选,并把它们转写成自然语言判断。
修复后,团队做了三层收口:
- 所有知识候选在进入 reranker 前先做 scope 过滤。
- summary 和 answer draft 继续继承 source ACL,避免派生层复用越界。
- 对高敏 source class,系统直接改成索引分片隔离,不再依赖后过滤补救。
这次事故最有价值的教训不是“要更小心权限”,而是理解了 retrieval 本身就是权限系统的一部分。
真正成熟的 Access-Controlled Retrieval,还要回答“权限变化之后旧索引怎么办”
权限边界不是静止的。租户迁移、部门重组、文档降级、员工离岗,都会让原来允许看的材料在今天不再允许看。只要索引和派生缓存不知道这件事,系统就会出现一种后知后觉的越权:权限已经变了,知识层还活在旧配置里。
所以 ACL propagation 还必须和删除、重算、失效传播绑定。至少要能回答:
- 某 source 的 ACL 改变后,哪些 chunk 和 summary 需要重投影或失效
- 当前用户角色变化后,旧 session 派生的 evidence pack 是否仍可继续使用
- 多租户环境里,cache key 是否已经带上 tenant 和 permission scope
这类设计如果缺失,平台迟早会因为“权限已经改了,但知识层还不知道”而反复踩同一类坑。
如果你现在只能先补一层,先让候选集在进入 reranker 前就完成权限过滤
很多团队会先想着做更细的结果页裁剪、更漂亮的权限说明。更值得优先补的是候选集边界。因为只要系统还允许不该看的内容先进入语义排序和模型上下文,后面任何展示层的控制都已经晚了一步。
AI agent 的检索权限真正成熟的标志,不是页面上没有暴露原文,而是系统从一开始就没有让不该看的证据参与思考。做到这一层,Knowledge Plane 才算真正有了边界感。
Checklist
- 检索候选是否在进入 reranker 和模型前就完成权限过滤
- chunk、summary、cache 和 memory 是否都继承原始 source ACL
- cache key 和派生对象是否显式包含 tenant 和 permission scope
- 高敏 source class 是否采用更强的索引分片或隔离策略
- ACL 变化后,旧索引与派生缓存是否能传播失效或重投影
- 最终回答在引用或概括 evidence 时是否仍会做二次权限校验
延伸阅读:


