去年有个做SaaS的朋友找我,他们给客户做了一款AI文档分析产品——客户上传合同,AI回答合同相关的问题。
上线第二周出事了。A公司员工问了个问题,系统返回的答案里有一段B公司的合同原文。客户直接打电话过来质问。排查发现,向量数据库里压根没存"这份文档属于哪个客户"这个字段。所有客户的文档都在同一个池子里搜,谁问都能搜到别人的。
这事挺典型的。很多团队做RAG的时候,脑子里只有“检索-生成”这条线,完全没想过“谁有权限看什么”这件事。
今天聊聊多租户RAG的权限隔离怎么搞
多租户RAG的权限隔离,就像一栋写字楼的门禁——你刷卡只能进自己公司那层,进不了别人那层。至于你进了自己那层能进哪个房间,那是另一层权限,今天不展开。
RAG的权限隔离,就是把这套门禁系统搬到AI检索链路里。
第一步:需求定义——先搞清楚“隔离到什么粒度”
很多人一上来就问“用哪种隔离方案”,顺序反了。先想清楚你的业务需要什么粒度的隔离。
三个问题帮你定位:
第一,租户之间需要物理隔离还是逻辑隔离?
物理隔离:每个租户独立数据库/集群,数据物理上就不在一起。适合金融、政务、军工这类合规要求极高的场景。成本高,但最安全。
逻辑隔离:所有租户共享一套基础设施,通过字段(比如tenant_id)做逻辑区分。适合绝大多数SaaS场景。成本低,但需要在代码层把好关。
Azure的多租户RAG架构指南里提到,多租户方案中数据主要有两种存储方式:按租户独立存储,或者多租户共享存储。选哪种,取决于你的合规要求和预算。
第二,用户级权限需要多细?
是按租户级别隔离就够了(租户A看不到租户B的数据),还是需要租户内部再做细分(A公司的销售部看不到研发部的文档)?
如果是前者,租户级隔离就够。如果是后者,你得在租户隔离之上再加一层用户级权限控制。
第三,跨租户共享数据的需求存在吗?
有些场景下,部分数据需要跨租户共享——比如平台级的公共知识库、行业通用的合规文档。如果有这类需求,你的隔离方案得支持“例外”——大部分数据隔离,少部分数据公开。
我们当时给那个SaaS朋友做的时候,先帮他定了三条原则:
- 租户之间必须物理隔离(客户合同数据太敏感,逻辑隔离客户不放心)
- 租户内部暂时不需要用户级细分(每个公司的使用者就那么几个人)
- 没有跨租户共享需求(每个客户的合同都是独立的)
这三条定下来,方案就清晰了一半。
第二步:方案设计——三种隔离模式怎么选
隔离粒度定好了,接下来选技术方案。
腾讯云有一篇基于JWT的多租户RAG技术实现解析,把隔离模式分成了三种:
一种是物理隔离——每个租户一套独立数据库,最安全也最贵
每个租户使用独立的向量数据库域(比如独立的OpenSearch域)。FGAC(细粒度访问控制)角色授予全索引访问权限。
优点:物理隔离,安全性最高。缺点:成本高,每个租户一套独立资源。
适合:金融、政务、医疗等合规要求极高的场景。租户数量少(几十个以内),每个租户数据量大。
一种是索引级隔离——共享数据库但独立索引,平衡方案
多租户共享向量数据库域,但每个租户使用独立的索引(Collection)。FGAC角色限制只能访问特定租户的索引。
优点:成本和安全性之间的平衡点。缺点:索引数量有上限(取决于向量数据库的支持能力)。
适合:绝大多数SaaS场景。租户数量中等(几百到几千个),数据隔离要求严格但不至于要物理隔离。
另一种是文档级隔离——所有数据混在一个索引里,靠字段过滤区分租户,最便宜但代码层必须严格把关
多租户共享域和索引,所有文档在同一个索引里,通过文档级别的元数据字段(比如tenant_id)做过滤。
优点:成本最低,支持海量租户。缺点:需要在每次检索时显式加上租户过滤条件,代码层把关要严。
适合:To C应用或租户数量极大的场景(几万到几十万租户),每个租户数据量不大。
Milvus的官方文档也提到了类似的分层思路——从Database、Collection到Partition Key,数据组织粒度由大到小。粒度越大,隔离越彻底但成本越高;粒度越小,成本越低但数据组织需要更固定。
我们当时给那个SaaS朋友选的是模式二(索引级隔离)。原因是:客户数据敏感但租户数量不多(几十家),索引级隔离够用且成本可控。每个租户一个独立的Collection,检索时直接限定Collection,不存在“过滤漏掉”的风险。
选型的时候容易犯一个错——一上来就往最重的方案走
一上来就搞域级隔离,每个租户独立部署一套向量数据库。结果租户才10个,运维成本已经扛不住了。怎么避免:从成本最低的方案开始评估——文档级隔离够不够?不够再升级到索引级。别一步到位选最重的。
第三步:方案设计(续)——JWT + 元数据过滤,把“门禁”装进检索链路
隔离模式定好了,接下来是把权限控制嵌入到RAG的检索链路里。
核心思路就一句话:检索之前先过滤,只搜用户有权限看的数据。
具体怎么实现?
第一步:认证层注入租户身份。
用户登录时,系统生成JWT(JSON Web Token),把租户ID(tenant_id)写进JWT的payload里。后续每次请求,客户端带上这个JWT,后端解析出来就知道“这个请求属于哪个租户”。
第二步:检索前加过滤条件。
用户发起查询后,系统先从JWT里拿到tenant_id,然后在向量检索的请求里加上过滤条件——“只搜tenant_id等于这个值的文档”。
这就是“检索前元数据过滤”(Pre-retrieval Metadata Filtering)。它的核心价值是:在向量数据库开始做相似度搜索之前,就先按权限把搜索范围限制住。这样,即使后面的语义检索出了什么偏差,也不可能返回其他租户的数据。
Azure的多租户RAG架构指南里也强调了类似的做法:在多租户方案中,通常使用租户标识符作为分区键来提供租户之间的隔离。
第三步:多层防护,别只靠一层。
JWT过滤是第一道防线。但万一JWT解析出错、过滤条件写漏了呢?
所以需要在多个层面都加上防护:
- API层:验证JWT有效性,拒绝没有合法租户身份的请求
- 检索层:向量检索时强制带上tenant_id过滤
- 数据层:向量数据库本身配置RBAC(基于角色的访问控制),限制不同角色能访问的Collection
LLM Platform这个开源项目就是这么做的——JWT认证、RBAC权限控制、向量存储层租户过滤,三层防护叠加。
过滤逻辑这块,最大的风险是只在前端做了校验
有些团队在API层做了权限校验,觉得就够了。但检索链路里如果忘了在向量检索时加过滤条件,API层的校验根本拦不住——因为数据已经返回了。怎么避免:JWT里解析出来的tenant_id是唯一来源。不接受任何从请求参数里传入的租户标识,写死在代码里。
第四步:开发验证——用“越权测试”跑一遍
方案设计好了,别急着上线。先做一件事:故意让一个租户的用户,去查另一个租户的数据,看系统会不会拦住。
我们当时给那个SaaS朋友做验证的时候,专门写了一个测试脚本:
- 用租户A的JWT发起查询
- 在检索请求里手动把过滤条件改成租户B的tenant_id
- 看系统会不会返回租户B的数据
结果第一次测就翻车了。我们一开始的过滤逻辑是直接从请求参数里取的tenant_id,压根没跟JWT做校验。如果有攻击者知道其他租户的ID,直接伪造请求就能查到别人的数据。也就是说,只要有人知道租户B的tenant_id,就能伪造请求查到B的数据。
后来改成了“JWT里的tenant_id是唯一来源,请求参数里的tenant_id只用于日志记录,不用于过滤”。
验证阶段最容易忽略的是’越权测试’这条线
测了“自己的数据能查到”就觉得没问题了。没测“别人的数据查不到”。怎么避免:专门设计一组“越权测试用例”——每个用例的目标都是“试图访问 unauthorized 的数据”。全部被拒绝,才算通过。
第五步:上线迭代——审计日志不能省
权限隔离的系统上线之后,有一件事比功能本身更重要:审计日志。
谁在什么时候查了什么数据、查到了什么结果——这些都得有记录。
LLM Platform的做法是把每一次查询的request_id、tenant_id、latency、cost都记录到PostgreSQL里。一旦出现数据泄露的投诉,你能快速定位“是哪一次查询出了问题、涉及哪个租户、数据流向了哪里”。
我们当时给客户加了一个“安全审计看板”——每周自动生成一份报告,列出“跨租户访问尝试”(被拦截的)和“异常查询模式”(某个租户的查询量突然暴增)。前者用来发现潜在的攻击或配置错误,后者用来发现可能的数据泄露。
日志上了之后,还有一个问题很多人会踩——记了但没人看
审计日志攒了一大堆,从来没人分析。出了事才想起来翻,发现日志格式不规范,根本查不到关键信息。怎么避免:上线第一天就定好“谁负责看日志、多久看一次、看什么指标”。哪怕每周只花15分钟扫一遍“被拦截的跨租户访问”列表,也比攒着不看来得强。
检查清单
□ 有没有先回答“隔离到什么粒度”?(物理隔离 vs 逻辑隔离?租户级 vs 用户级?) □ 选了哪种隔离模式?(域级/索引级/文档级——根据租户数量和合规要求选) □ JWT里是否包含了tenant_id?(认证层注入租户身份) □ 向量检索时是否强制加了tenant_id过滤?(不依赖调用方传参) □ 有没有做“越权测试”?(故意查别人的数据,看会不会被拦住) □ 审计日志记录了吗?(谁、什么时候、查了什么、结果是什么) □ 审计日志有人定期看吗?(别攒着不分析)
三个常见坑(绕着走)
坑一:元数据过滤只在应用层做,向量数据库层没做限制。
应用层代码过滤了tenant_id,但向量数据库本身没有配置任何权限控制。万一应用层的过滤逻辑出了bug(比如代码升级时漏掉了过滤条件),数据就直接暴露了。
怎么避免:在向量数据库层也配置RBAC。Milvus提供了比较完善的RBAC机制,系统管理员可以为每个用户设置数据访问范围和权限级别。应用层过滤 + 数据库层RBAC,双重保险。
坑二:租户ID从客户端传入,不从JWT解析。
有些系统让客户端在请求里带上tenant_id,后端直接用这个值做过滤。攻击者可以伪造tenant_id,查到别的租户的数据。
怎么避免:租户ID只能从JWT解析,不接受客户端传入。客户端就算传了tenant_id,后端也忽略它,只用JWT里的。
坑三:忽略了“共享数据”的场景。
有些数据需要跨租户共享——比如平台级的帮助文档、行业通用的合规模板。如果隔离方案是一刀切的“每个租户只能看自己的数据”,这些共享数据就没人能看到了。
怎么避免:在设计阶段就识别出“共享数据”和“租户私有数据”两类。共享数据放在单独的Collection里,检索时同时检索“租户私有Collection + 共享Collection”。权限上,共享Collection对所有租户开放读权限。
最后一个问题:你现在那个RAG系统,如果明天有人伪造请求去查别人租户的数据,它能拦住吗?如果现在回答不了,先把这个测试做了再说。
行动指南:
第一步,画出你当前RAG系统的“数据流图”——从用户发起查询,到向量检索,到LLM生成回答。在图上标出“权限检查”发生在哪个环节。如果只有一个检查点,说明不够。
第二步,写一个“越权测试”脚本——用租户A的JWT,在检索请求里尝试查租户B的数据。跑一遍,看会不会被拦住。
第三步,检查你的审计日志——有没有记录"谁、什么时候、查了什么"?如果没有,排期补上。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋
📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~