摘要
AI 应用同时接触用户身份、历史会话、企业文档、模型供应商和外部工具。一旦权限边界不清,模型可能检索到不该看到的文档,工具可能执行超出用户权限的操作,日志也可能保存密钥、身份证号或客户数据。
本文继续企业智能客服与知识库助手,设计一套权限、敏感信息和数据安全方案,重点介绍:
- 用户、应用、知识库和工具的权限关系;
- 检索前授权与结果后过滤;
- Prompt、日志和 Trace 中的敏感信息处理;
- 工具调用的最小权限、审批和参数校验;
- 多租户数据隔离;
- 静态加密、传输加密和密钥管理;
- 数据保留、删除、审计和事件响应。
一、背景与问题
1. AI 后端扩大了数据暴露面
传统接口通常按请求返回明确字段。AI 应用则把多类数据一起放入上下文:
用户问题 历史会话 检索到的文档 工具返回的业务数据 系统 Prompt ↓ 模型供应商或本地模型 ↓ 回答、日志、Trace、缓存风险不只出现在最终回答中,还出现在数据流动过程中。
2. 常见安全问题
| 问题 | 后果 |
|---|---|
| 只在检索后过滤权限 | 无权限文档可能进入模型上下文 |
| 工具沿用服务账号 | 用户可间接执行超出权限的操作 |
| 日志记录完整 Prompt | 敏感信息进入日志平台 |
| 向量库缺少租户条件 | 跨租户语义检索 |
| 模型供应商无数据处理约定 | 企业数据离开可控边界 |
| 删除原文档后保留切片 | 数据删除不彻底 |
二、核心概念
1. 最小权限
每次模型调用只能获得完成当前任务所需的数据、工具和字段。权限判断基于当前用户、租户、应用和操作,不基于“模型是否可信”。
2. 检索前授权
知识库检索必须先缩小可访问范围:
用户身份 ↓ 可访问知识库 ↓ 可访问文档 ↓ 向量检索 ↓ 返回已授权切片不能先从全库召回,再指望模型自行遵守权限说明。
3. 敏感数据分类
| 级别 | 示例 | 默认处理 |
|---|---|---|
| 公开 | 产品介绍、公开文档 | 可以进入授权上下文 |
| 内部 | 流程说明、未公开配置 | 仅内部身份可检索 |
| 机密 | 合同、客户业务数据 | 加密、审计、限制导出 |
| 受限 | 密钥、证件号、支付数据 | 默认不进模型和日志 |
三、工作原理
1. 安全控制点
请求进入 ├─ 身份认证 ├─ 租户和应用授权 ↓ 上下文组装 ├─ 检索前权限过滤 ├─ 敏感字段脱敏 ├─ 工具白名单 ↓ 模型调用 ├─ 供应商允许列表 ├─ 数据出境策略 ├─ 最大上下文字段 ↓ 工具执行 ├─ 参数校验 ├─ 用户权限重检 ├─ 审批或二次确认 ↓ 存储与观测 ├─ 加密 ├─ 脱敏日志 └─ 审计事件每个控制点都要失败关闭:权限服务不可用时,不回退为全量访问。
2. 文档授权模型
tenant └─ knowledge_base └─ document ├─ owner ├─ classification └─ acl ├─ user ├─ role └─ department切片继承文档权限。文档权限变化后,需要同步更新检索引擎中的过滤字段,避免旧权限继续生效。
3. 工具授权模型
工具执行分三层:
应用是否启用工具 用户是否拥有业务权限 本次参数是否落在允许范围例如用户可以调用“查询订单”,但只能查询自己的订单;客服主管才可以查询任意订单。模型给出参数后,业务服务仍要按当前身份重新鉴权。
四、实战示例
1. 权限上下文
publicrecordAccessContext(StringtenantId,StringuserId,Set<String>roles,StringapplicationCode,Set<String>scopes){}AccessContext从已认证身份构建,不接受客户端直接传入角色或权限范围。
2. 检索前过滤
publicList<KnowledgeChunk>retrieve(AccessContextaccess,Stringquery){List<String>bases=authorizationService.permittedBases(access);if(bases.isEmpty()){returnList.of();}SearchRequestrequest=SearchRequest.builder().tenantId(access.tenantId()).knowledgeBases(bases).principals(access.principals()).query(query).limit(5).build();returnvectorSearchService.search(request);}向量库查询条件至少包含tenantId、知识库 ID 和授权主体。应用层过滤只能作为额外保护,不能替代存储层条件。
3. 敏感信息脱敏
publicStringredact(Stringcontent){Stringresult=content;result=result.replaceAll("(?i)sk-[a-z0-9]{20,}","[REDACTED_KEY]");result=result.replaceAll("\\b\\d{17}[0-9Xx]\\b","[REDACTED_ID]");result=result.replaceAll("\\b\\d{11}\\b","[REDACTED_MOBILE]");returnresult;}正则只处理明确模式。结构化业务数据应在进入 Prompt 前按字段删除,例如直接移除idCard、bankCard和accessToken。
4. 安全日志
publicvoidlogModelCall(ModelAuditaudit){auditLogger.info("model_call traceId={} tenantId={} app={} model={} inputTokens={} outputTokens={}",audit.traceId(),audit.tenantId(),audit.applicationCode(),audit.modelCode(),audit.inputTokens(),audit.outputTokens());}日志保存关联标识和用量,不保存完整问题、文档内容、工具参数和供应商响应。排障需要原始数据时,通过受控的短期调试开关单独采集。
5. 工具执行前重检
publicToolResultexecute(AccessContextaccess,ToolCallcall){ToolDefinitiontool=toolRegistry.get(call.name());authorizationService.checkTool(access,tool);Objectparameter=schemaValidator.validate(tool.inputSchema(),call.arguments());authorizationService.checkBusinessScope(access,tool,parameter);returntoolExecutor.execute(access,tool,parameter);}高风险操作还要增加审批状态或用户确认令牌。模型不能通过修改参数自行提升权限。
6. 数据保留策略
retention:conversation:180dmodel-trace:30dsecurity-audit:365ddeleted-document-grace:7d不同数据的保留期不同。安全审计通常需要比普通会话保留更长时间,但审计内容也应避免重复保存敏感原文。
五、常见问题与实践建议
1. 不要把秘密放进 Prompt
API Key、数据库密码、私钥和会话令牌不属于模型上下文。工具执行所需凭证由服务端凭据管理组件注入,不经过模型。
2. 供应商选择要匹配数据级别
公开数据可以使用云端模型。机密数据需要确认供应商的数据保留、训练使用、区域和访问控制条款。受限数据默认只进入经过批准的本地推理环境。
3. 删除必须覆盖衍生数据
删除文档时同步处理:
- 原文件;
- 解析文本;
- 切片;
- 向量;
- 缓存;
- 搜索索引;
- 由该文档生成且不再需要的调试样本。
4. 防注入不能替代权限
用户可能在问题中要求模型忽略限制、输出文档原文或调用工具。系统 Prompt 可以降低这类问题的影响,但真正的边界必须是检索授权、工具鉴权和输出检查。
5. 安全检查要可观测
记录授权拒绝、脱敏命中、跨租户拦截和工具拒绝次数。异常升高可能是攻击,也可能是权限配置错误。
六、进阶思考
1. 加密边界
| 位置 | 措施 |
|---|---|
| 浏览器到 API | TLS |
| 服务之间 | 内部 TLS 或网格加密 |
| 数据库 | 磁盘加密和字段级加密 |
| 对象存储 | 服务端加密和私有访问 |
| 向量库 | 租户隔离、静态加密 |
| 密钥 | KMS 或专用密钥管理服务 |
字段级加密适合证件号等小字段,不适合所有会话内容。加密不能替代访问控制。
2. 输出安全检查
回答返回前可以执行:
- 机密标记检查;
- 密钥模式扫描;
- 外部链接和数据外发检查;
- 不允许承诺或越权表述检查;
- 工具结果与回答的一致性检查。
检查失败时返回受控提示,并记录安全事件。
3. 权限变更传播
用户离开部门或文档 ACL 变化后,缓存、检索引擎和长期记忆都要失效。可以为文档和 ACL 设计版本号,查询时携带版本,避免权限更新延迟。
4. 安全事件响应
至少准备以下操作:
- 停用应用版本;
- 吊销模型 Key;
- 禁用工具;
- 冻结租户;
- 清理缓存和会话;
- 导出审计记录;
- 轮换受影响密钥。
这些操作需要管理权限和演练,不应临时直接修改生产数据库。
结论
AI 应用的数据安全不能依赖模型“理解并遵守规则”。权限应在检索和工具执行之前生效,敏感字段应在进入 Prompt、日志和 Trace 之前移除,存储与删除则要覆盖文档、切片、向量和缓存等全部衍生数据。
后续可以把这套权限模型接入统一 AI 平台,并结合模型调用监控继续完善预算、异常访问和安全告警。
参考资料
- OWASP Top 10 for Large Language Model Applications
- NIST AI Risk Management Framework
- Spring Security Reference
- OpenTelemetry Documentation