[控场AI]
· 8 分钟阅读· 4,287 字

Agent记忆引发向量数据库授权漏洞:复现与基准测试

Agent记忆引发向量数据库授权漏洞:复现与基准测试

后台代理合成摘要写回向量库时丢失源文档ACL,导致多租户权限泄漏。

文章揭示多智能体系统持久化共享记忆时的一个授权漏洞:后台代理跨文档合成摘要块并写回向量数据库,却未继承源文档的访问控制列表,使普通用户可能检索到机密上下文。作者用开源工具sentinel-eval在Chroma与LlamaIndex基线上离线复现,24份文档测试中原始RAG泄漏率为0%,而Agent记忆场景3个合成任务有2个泄漏。文章分析了严格父交集修复的可用性代价、向量库缺乏祖先权限DAG遍历能力的问题,以及社区在运行时权限图查找与按用户/角色隔离向量库之间的分歧,最后给出写入路径附加权限元数据、测试先行等实践建议。

多智能体系统在持久化共享记忆时,可能引入一个容易被忽视的授权漏洞:后台代理在写入向量数据库时,会丢失源文档的访问控制列表(ACL)。本文基于一个开源本地测试工具,在Chroma和LlamaIndex基线上量化了这一风险,并探讨了不同修复方案的利弊。

reddit source: Agent memory creates a major authorization vulnerability in vector databases (offline reproduction &

漏洞是如何产生的:从RAG到Agent记忆的权限断层

许多团队认为,只要直接RAG查询附带了元数据过滤器,多租户隔离就已经解决。但后台代理的写入路径可能破坏这一假设。典型场景如下:一个后台工作进程以宽泛的读权限运行,用于跨不同项目文档总结上下文;它将多个来源合并成一个摘要块(chunk);随后将该块写回共享向量集合,并在过程中丢弃了父文档的ACL。由于新生成的块没有任何访问控制标签,普通用户查询向量数据库时,就能拉取到本无权阅读的机密上下文。

问题的核心在于:向量数据库在查询时通常只基于元数据过滤,而摘要块继承了来源文档的内容,却没有继承其权限属性。代理在合成新内容时,往往只关注语义合并,忽略了安全元数据的传递。

ACL(访问控制列表)与向量数据库的元数据过滤

ACL 是附加在文件或文档上的权限清单,逐项指定主体(用户、组、角色)对资源的读、写、执行等权限。在传统文件系统中,ACL 由操作系统内核在每次打开文件时强制校验。而在向量数据库语境下,ACL 需要被压缩为可查询的元数据字段(如 allowed_roles: ["eng-team","admin"]),因为向量检索的流程是先做近似最近邻(ANN)搜索,再对候选结果按元数据条件过滤,权限判断发生在检索之后、返回之前。这一架构意味着:安全完全依赖于每条向量记录是否携带正确的权限元数据。一旦某个块在写入时没有 ACL 字段,查询过滤条件对该块形同虚设——它要么因缺少字段而被默认放行,要么因匹配不到任何限制而暴露。这正是代理写回时丢失 ACL 会造成泄漏的根本原因。

元数据过滤器与多租户隔离的局限

许多 RAG 系统的多租户隔离依赖于“查询时附加元数据过滤”,例如每次检索都强制带上 tenant_id == current_tenant。这种模式在文档直接入库时是有效的,因为写入方就是原始文档的所有者,tenant_id 和 ACL 在入库时一次性写死。但当引入后台代理后,写入路径变得多跳:代理读取多个来源、合成新块、再写回。合成块是由代理程序生成的,它既不是原始文档的副本,也没有天然归属的租户或权限。如果代理的代码只传递了内容向量和语义元数据(如来源文档 ID),而没有显式继承并写入 ACL,那么该块就处于“无权限标签”状态。元数据过滤的前提是字段存在,缺失字段的块在多数向量库的过滤语义中不会被排除,这是权限断层的技术细节。

离线复现:sentinel-eval的测试结果

为了量化这一风险,开发者构建了本地测试工具sentinel-eval(Apache-2.0许可)。该工具在24份文档的测试语料上运行,比较了原始RAG和Agent记忆两种场景。

  • 原始RAG:泄漏率为0%。检索到18个公共块,0个受限块暴露。
  • Agent记忆:3个合成任务中有2个发生泄漏。其中两个跨边界工作负载泄漏了6/18的“金丝雀”(canary,用于检测泄漏的标记),而公共对照任务干净通过。

这些数据表明,当代理进行跨文档摘要并写回时,权限边界可能被实质性绕过。测试套件包含23个本地测试,使用模拟向量,几秒内完成,确定性且无需API密钥或网络调用。复现命令如下:

git clone https://github.com/harishbalasubramanian/sentinel-eval
cd sentinel-eval
uv run sentinel-eval live --framework chroma

代码托管在GitHub,供社区审查和扩展。

“金丝雀”标记与泄漏率度量

金丝雀(canary)源自矿工用金丝雀检测瓦斯泄漏的隐喻,在安全测试中指嵌入在受保护内容里的可检测标记——如果该标记出现在不该出现的输出中,就证明发生了泄漏。sentinel-eval 的做法是在受限文档中植入独特的字符串或语义指纹,然后以普通用户身份发起查询,检查检索结果中是否包含这些标记。泄漏率由此定义为“暴露的受限块数 / 受限块总数”。这种度量方式比人工审查更客观、可复现,且不依赖模型输出质量,只关注数据可见性。原始 RAG 的 0% 泄漏说明直接检索路径的元数据过滤是生效的;Agent 记忆场景的 6/18 泄漏则说明合成写回路径绕过了过滤,因为新块根本没有被标记为受限。

确定性离线测试的价值

sentinel-eval 使用模拟向量并在本地几秒内完成 23 个测试,无需 API 密钥或网络调用。这种设计的核心价值在于确定性:泄露与否不依赖嵌入模型的随机性、不依赖远程服务的可用性,每次运行结果一致,便于在 CI 中作为回归门禁。对于权限这类安全属性,可重复的负向测试(证明漏洞存在)和正向测试(证明修复有效)同样重要,而真实向量库加远程嵌入的组合往往难以稳定复现边界条件。

朴素修复方案的局限

一个直观的修复是取严格的父文档交集:只有当用户对摘要涉及的所有源文档都有访问权限时,才允许读取该摘要。这确实能堵住漏洞,但代价是多源摘要几乎无法被普通用户检索——只有顶级管理员才能满足条件。这削弱了多源摘要的实用价值。

另一个问题是,作者将血缘信息保存在source_documents元数据字段中,但向量数据库在查询时没有干净的方式遍历祖先权限DAG(有向无环图)。这意味着,即使记录了来源,运行时进行权限图查找也可能低效或复杂。直接在查询时做图遍历,可能引入延迟和额外的系统依赖。

权限 DAG 与祖先遍历

文档之间的派生关系天然构成有向无环图(DAG):原始文档派生出摘要块,摘要块又可能派生出更高层的摘要,每个节点继承其所有祖先的权限约束。查询一个衍生块时,理想的权限判断是取所有祖先 ACL 的交集——用户必须对每一个祖先都有读权限。问题在于向量数据库的查询接口面向的是扁平元数据过滤,而不是图遍历。元数据字段里即便记录了 source_documents 列表,查询时也无法递归展开这些 ID 再查它们的 ACL,除非应用层多次往返查询或预先把所有祖先权限展平写入每个块。前者引入延迟和 N+1 查询问题,后者则面临图变化时元数据同步的一致性挑战。父交集方案之所以“安全但不可用”,正是因为交集在深层派生链上会迅速收缩为空集,导致多源摘要只有同时拥有全部源权限的超级管理员才能读取。

社区探讨:运行时权限图 vs. 按用户/角色隔离向量库

作者在帖子中询问其他团队如何处理持久化Agent记忆的授权问题,提出了两种常见方向:

  1. 运行时权限图查找:在查询时动态解析摘要块的源文档权限,判断当前用户是否有权读取。这要求向量数据库支持复杂的元数据关联查询,或在外围服务中实现权限解析层。
  2. 按用户/角色隔离向量存储:为每个用户或角色维护独立的向量集合,从根本上避免跨边界数据混合。这简化了权限模型,但增加了存储成本和数据冗余,尤其当用户数量大或角色频繁变更时。

两种方案各有取舍。运行时查找更灵活,但实现复杂且可能影响性能;隔离存储更安全简单,但扩展性受限。目前尚无社区共识,这反映出Agent记忆的授权模型仍是一个开放问题。

命名空间隔离与存储成本

按用户或角色隔离向量库,通常借助向量数据库的命名空间(namespace)或集合(collection)机制实现——Chroma 支持多 collection,Pinecone 等支持 namespace,每个隔离单元有独立的索引空间。这种方案把权限判断前移到连接层:用户只能访问自己的命名空间,跨边界混合在物理上不可能发生。代价是索引碎片化:每个命名空间都要维护完整的 HNSW 图结构,内存和存储开销随用户数线性增长;跨用户的全局语义搜索也无法进行,因为检索被限制在单个命名空间内。角色隔离比用户隔离粒度更粗、碎片更少,但角色频繁变更时需要迁移数据。运行时权限图查找则相反,索引只有一份,权限在查询后动态裁剪,灵活但把复杂度推给了应用层,且要求权限服务与向量检索在同一延迟预算内协同。两者的取舍本质上是“隔离换空间”与“共享换复杂度”的权衡。

实践建议与开放问题

对于正在构建多智能体系统的团队,以下几点值得关注:

  • 写入路径的权限继承:确保代理在生成摘要块时,将源文档的ACL以某种形式附加到新块上。即使不能完全解决,也能为后续权限检查提供依据。
  • 测试先行:使用类似sentinel-eval的工具进行离线测试,验证自己的系统是否存在类似泄漏。测试应覆盖跨边界合成任务,而不仅仅是公共数据。
  • 权衡可用性与安全性:严格的父交集虽然安全,但可能牺牲多源摘要的可用性。可以考虑基于用户权限的动态摘要生成,而非预先合成。
  • 关注向量数据库的权限原语:目前主流向量数据库对祖先权限遍历的支持有限,团队可能需要在外围构建权限服务。

这一漏洞提醒我们,Agent记忆的持久化不仅仅是技术实现问题,更是安全设计问题。随着多智能体系统普及,授权模型需要与记忆架构同步演进。

要点总结

  • 后台代理在合成并写回摘要块时,可能丢失源文档ACL,导致权限泄漏。
  • sentinel-eval测试显示,Agent记忆场景下3个合成任务有2个泄漏,而原始RAG无泄漏。
  • 严格父交集修复会牺牲多源摘要的可用性,向量数据库缺乏原生权限DAG遍历能力。
  • 社区在运行时权限图查找和按用户/角色隔离向量库之间尚无共识。
  • 建议团队在写入路径附加权限元数据,并用离线工具测试跨边界合成任务。
分享:

相关推荐