← 返回题目列表

RAG 如何做权限控制?

高频 困难 第 16 / 29 题 更新于 2026/09/18
RAG权限控制ACL多租户

简化版

RAG 权限必须在检索前和上下文组装前由后端基于真实身份强制执行,不能靠 Prompt 要求模型保密。索引中的每个 chunk 继承租户、文档 ACL/安全域和权限版本;查询做租户隔离与 pre-filter,候选再实时 ACL 复查,只有授权文本能进入 LLM。缓存、引用、日志和权限变更也必须遵守同一边界。

详细版

认证确定用户是谁,授权决定能对哪些 document 执行 read。粗粒度可按 tenant/space 分区,细粒度用用户组、ABAC 或 policy_id;权限过滤条件由服务端生成,模型与用户都不能修改。向量库无法高效复杂过滤时,可扩大授权分区内候选并 post-filter,但不能先把无权内容发给模型再遮答案。

撤权用版本化事件和 deny/tombstone 秒级生效,主动失效检索、上下文和答案缓存;引用点击再次鉴权,日志最小化。评测包括跨租户查询、同主题无权文档、缓存复用、旧会话、索引迁移和时间差攻击,核心硬指标是无权 chunk 进入上下文次数必须为零。

身份令牌 -> 授权服务 -> tenant/security-domain pre-filter -> ANN
                                         -> candidate ACL post-check -> LLM context

完整版教学

一、权限控制发生在生成之前

如果无权文档已经进入 LLM 上下文,即使回答最终没显示,数据也可能被外部模型处理、日志记录或后续轮次泄露。输出过滤太晚。安全目标是未经授权的 chunk 从不越过上下文边界。

Prompt 中“不要泄露”只能帮助模型行为,不能证明隔离。授权必须由确定性服务根据当前认证主体和资源策略判定,失败时 fail closed。

二、认证、授权和检索要分清

认证得到 user_id、tenant 和可信 claims;授权计算 can_read(user, document, context);检索只在授权集合中排名。用户问题里的“我是管理员”不影响真实身份,模型生成的 filter 也不能增加权限。

allow = authenticated
     && same_tenant
     && policy_engine.can_read(subject, document)
     && document.status == active

记忆钩子:检索分数决定“相关不相关”,授权策略决定“能看不能看”;相关性永远不能补偿权限不足。

三、多租户隔离有哪些方案

物理独立索引隔离强,适合高价值少量租户,但运维成本高;共享索引用 tenant_id 强过滤,规模效率高但配置错误影响大;分安全域的混合方式在二者之间。选择取决于威胁模型、租户数和合规。

模式隔离成本风险
每租户独立索引索引数量爆炸
共享索引+过滤逻辑漏 filter 即泄露
安全域分区+ACL中强策略较复杂

共享模式在 SDK 层强制注入 tenant filter,业务调用方不能选择关闭。

四、细粒度 ACL 如何进入索引

每个 chunk 继承 document_id 和 acl_version,可带 allowed_groups 或 policy_id。组成员变化频繁时,不宜把所有 user_id 展开到每块;查询时将可信用户组映射成过滤,或由策略服务复查候选。文档移动文件夹也要触发 ACL 更新。

权限字段与内容字段分开版本化。内容 hash 不变不代表 ACL 不变。索引中缺权限元数据的文档默认不可见,不能默认 public。

五、Pre-filter 与 Post-check 缺一不可

Pre-filter 减少无权候选并防中间系统接触数据;但向量库实现、复杂组策略和索引陈旧可能产生漏洞。最终 context builder 对每个 document_id 调用当前授权或验证签名,形成第二道门。

Post-filter 后结果不足时,只能在授权空间扩大搜索,不能用无权结果补齐 Top-k。候选 ID 的日志和指标也可能泄露文档存在性,跨租户可见性需限制。

六、缓存与会话如何继承权限

最终答案可能概括私有文档,语义缓存不能跨权限共享。key 包含 tenant 与 permission fingerprint,命中时重新检查依赖文档 ACL。用户离组后,旧会话中的历史摘要也要清理或重新构造。

引用 URL 使用受控下载路由,每次点击鉴权,不能暴露对象存储永久链接。权限事件按 document tag 失效检索、context 和 answer 缓存;TTL 只作兜底。

七、如何测试零泄露目标

构造两个租户同名文档、同租户不同组、撤权后的缓存命中、索引 lag、旧会话和恶意 filter。观察每阶段候选,硬断言 unauthorized chunk 不进入 Prompt。最终答案不含秘密只是辅助指标,因为模型可能碰巧没复述。

例如 10000 次红队请求,输出泄露 0 次但有 3 次无权 chunk 被发送给模型,仍判失败。监控 unauthorized_context_count=0、ACL check latency、撤权传播 P99 和 fail-closed 次数。

八、常见误区与追问

  • 误区:在 System Prompt 写“尊重权限”就够了。 模型不知道真实 ACL,也可能被注入绕过。
  • 误区:最后答案脱敏就没有泄露。 无权正文进入 LLM 或日志已经越界。
  • 误区:共享缓存只要查询相同就可复用。 答案依赖用户可见证据,必须权限隔离。
  • 追问:向量库不支持 ACL 怎么办? 按租户/安全域分区,扩大授权域候选后实时 post-check,或更换能力。
  • 追问:权限缺失字段如何处理? 默认拒绝并告警,不可按 public 处理。
  • 追问:如何处理撤权延迟? deny overlay 先行、缓存主动失效、查询实时复查,物理清理异步。

九、加强记忆

RAG 权限可记成“身份后端定、索引先过滤、上下文再复查、缓存跟权限、撤权先阻断”。模型与用户不能生成授权,任何无权 chunk 都不进入 LLM;引用和旧会话同样再次鉴权。安全验收看中间上下文零越权,而不只看最终是否偶然没有泄露。