AI 应用的权限、敏感信息与数据安全

0 阅读7分钟

摘要

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. 权限上下文

public record AccessContext(String tenantId,
                            String userId,
                            Set<String> roles,
                            String applicationCode,
                            Set<String> scopes) {
}

AccessContext 从已认证身份构建,不接受客户端直接传入角色或权限范围。

2. 检索前过滤

public List<KnowledgeChunk> retrieve(AccessContext access, String query) {
    List<String> bases = authorizationService.permittedBases(access);
    if (bases.isEmpty()) {
        return List.of();
    }

    SearchRequest request = SearchRequest.builder()
            .tenantId(access.tenantId())
            .knowledgeBases(bases)
            .principals(access.principals())
            .query(query)
            .limit(5)
            .build();
    return vectorSearchService.search(request);
}

向量库查询条件至少包含 tenantId、知识库 ID 和授权主体。应用层过滤只能作为额外保护,不能替代存储层条件。

3. 敏感信息脱敏

public String redact(String content) {
    String result = 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]");
    return result;
}

正则只处理明确模式。结构化业务数据应在进入 Prompt 前按字段删除,例如直接移除 idCard、bankCard 和 accessToken。

4. 安全日志

public void logModelCall(ModelAudit audit) {
    auditLogger.info("model_call traceId={} tenantId={} app={} model={} inputTokens={} outputTokens={}",
            audit.traceId(),
            audit.tenantId(),
            audit.applicationCode(),
            audit.modelCode(),
            audit.inputTokens(),
            audit.outputTokens());
}

日志保存关联标识和用量,不保存完整问题、文档内容、工具参数和供应商响应。排障需要原始数据时,通过受控的短期调试开关单独采集。

5. 工具执行前重检

public ToolResult execute(AccessContext access, ToolCall call) {
    ToolDefinition tool = toolRegistry.get(call.name());
    authorizationService.checkTool(access, tool);

    Object parameter = schemaValidator.validate(tool.inputSchema(), call.arguments());
    authorizationService.checkBusinessScope(access, tool, parameter);

    return toolExecutor.execute(access, tool, parameter);
}

高风险操作还要增加审批状态或用户确认令牌。模型不能通过修改参数自行提升权限。

6. 数据保留策略

retention:
  conversation: 180d
  model-trace: 30d
  security-audit: 365d
  deleted-document-grace: 7d

不同数据的保留期不同。安全审计通常需要比普通会话保留更长时间,但审计内容也应避免重复保存敏感原文。

五、常见问题与实践建议

1. 不要把秘密放进 Prompt

API Key、数据库密码、私钥和会话令牌不属于模型上下文。工具执行所需凭证由服务端凭据管理组件注入,不经过模型。

2. 供应商选择要匹配数据级别

公开数据可以使用云端模型。机密数据需要确认供应商的数据保留、训练使用、区域和访问控制条款。受限数据默认只进入经过批准的本地推理环境。

3. 删除必须覆盖衍生数据

删除文档时同步处理:

  • 原文件;
  • 解析文本;
  • 切片;
  • 向量;
  • 缓存;
  • 搜索索引;
  • 由该文档生成且不再需要的调试样本。

4. 防注入不能替代权限

用户可能在问题中要求模型忽略限制、输出文档原文或调用工具。系统 Prompt 可以降低这类问题的影响,但真正的边界必须是检索授权、工具鉴权和输出检查。

5. 安全检查要可观测

记录授权拒绝、脱敏命中、跨租户拦截和工具拒绝次数。异常升高可能是攻击,也可能是权限配置错误。

六、进阶思考

1. 加密边界

位置措施
浏览器到 APITLS
服务之间内部 TLS 或网格加密
数据库磁盘加密和字段级加密
对象存储服务端加密和私有访问
向量库租户隔离、静态加密
密钥KMS 或专用密钥管理服务

字段级加密适合证件号等小字段,不适合所有会话内容。加密不能替代访问控制。

2. 输出安全检查

回答返回前可以执行:

  • 机密标记检查;
  • 密钥模式扫描;
  • 外部链接和数据外发检查;
  • 不允许承诺或越权表述检查;
  • 工具结果与回答的一致性检查。

检查失败时返回受控提示,并记录安全事件。

3. 权限变更传播

用户离开部门或文档 ACL 变化后,缓存、检索引擎和长期记忆都要失效。可以为文档和 ACL 设计版本号,查询时携带版本,避免权限更新延迟。

4. 安全事件响应

至少准备以下操作:

  • 停用应用版本;
  • 吊销模型 Key;
  • 禁用工具;
  • 冻结租户;
  • 清理缓存和会话;
  • 导出审计记录;
  • 轮换受影响密钥。

这些操作需要管理权限和演练,不应临时直接修改生产数据库。

结论

AI 应用的数据安全不能依赖模型“理解并遵守规则”。权限应在检索和工具执行之前生效,敏感字段应在进入 Prompt、日志和 Trace 之前移除,存储与删除则要覆盖文档、切片、向量和缓存等全部衍生数据。

后续可以把这套权限模型接入统一 AI 平台,并结合模型调用监控继续完善预算、异常访问和安全告警。

参考资料