AI数据从采集到删除的全生命周期安全
AI 数据安全不是在模型输出后用正则把手机号打星。一次 AI 请求可能复制数据到用户输入、会话历史、RAG Chunk、Embedding、Tool Result、Prompt、第三方 Provider、流式缓冲、Trace、缓存、评估集和人工标注平台。只处理其中一份,其他副本仍可能泄露或继续被检索。
核心目标是:
知道数据是什么
→ 为什么需要
→ 谁能访问
→ 能发到哪里
→ 保存了几份
→ 保存多久
→ 怎样撤销和删除
→ 如何证明控制有效本章讲工程原理和通用控制方向,不替代组织所在司法辖区、行业和合同所要求的法律合规评估。
一、学习目标
学完后,你应该能够:
- 区分 AI 数据安全、模型行为安全和传统应用安全。
- 画出数据在 Prompt、RAG、Tool、Provider、日志、缓存和评估集中的副本链。
- 建立数据分类、字段级策略、处理目的和允许目的地。
- 区分删除、掩码、泛化、假名化、匿名化、哈希、HMAC 和加密。
- 解释为什么普通哈希不能可靠保护手机号、身份证等低熵数据。
- 设计发送外部模型前的字段级最小化和阻断规则。
- 设计 RAG 的入库分级、ACL、检索过滤、引用和删除传播。
- 设计 Tool Result 的字段投影、再鉴权、脱敏和限长。
- 评估第三方 Provider 的留存、训练使用、区域、子处理者和删除能力。
- 设计租户、ACL、模型、Prompt 和索引版本隔离的缓存 Key。
- 管理日志、Trace、评估集和人工标注中的敏感副本。
- 解释删除请求为何需要清单、状态机、对账、备份到期和例外记录。
- 运行字段策略 Demo 和删除传播 Demo。
- 根据 requestId 和 dataSubjectId 排查越权、日志污染和删除不完整。
二、AI数据安全与AI安全有什么区别
| 维度 | AI数据安全 | AI行为与系统安全 |
|---|---|---|
| 主要问题 | 数据是否被多收、多发、越权、长期留存 | 模型是否被注入、误导或诱导调用工具 |
| 主要对象 | 输入、文档、Prompt、Tool、日志、缓存、评估集 | 指令层级、Tool权限、Agent动作、输出行为 |
| 主要控制 | 分类、目的限制、最小化、ACL、加密、删除 | 注入防护、参数校验、幂等、审批、沙箱 |
两者会交叉。例如 RAG 文档注入属于行为攻击,但如果恶意文档诱导模型泄露其他患者资料,最终又是数据安全事件。真正的边界必须由后端权限和数据控制实现,不能只靠 Prompt。
三、一条数据会被复制到哪里
flowchart TD
A["用户输入或业务记录"] --> B["API网关与业务后端"]
B --> C["会话与Prompt编排"]
B --> D["Tool调用"]
B --> E["RAG检索"]
E --> F["Chunk、Metadata与向量"]
C --> G["模型网关"]
D --> C
F --> C
G --> H["本地或第三方Provider"]
H --> I["模型输出与流式缓冲"]
I --> J["业务响应和结果缓存"]
B --> K["日志、Trace和指标"]
I --> K
K --> L["评估集、反馈与人工标注"]
F --> M["快照、备份和灾备副本"]3.1 为什么数据副本容易被忽略
业务表可能只保存一份患者记录,但 AI 链路为了调试和评估又保存:
- 完整用户问题。
- 完整 Prompt。
- RAG 片段。
- Tool HTTP 请求和响应。
- Provider 请求日志。
- SSE 临时缓冲。
- 会话记忆。
- 语义缓存。
- 线上失败样本。
- 标注平台导出文件。
删除源记录不代表这些副本自动消失。
3.2 先做数据流清单
每条链路至少登记:
数据类别
字段和数据主体标识
业务目的
来源系统
处理服务
传输目的地和区域
存储位置
访问角色
加密方式
保留期限
删除能力
备份恢复方式
责任人没有清单就无法回答“这条身份证号是否发给了外部模型”“删除请求还剩哪些副本”。
四、分类分级必须落实到系统行为
示例分级,组织应根据法律、行业和业务风险制定自己的标准:
| 级别 | 示例 | AI链路默认方向 |
|---|---|---|
| Public | 已授权公开FAQ | 可处理,仍做版权和来源控制 |
| Internal | 内部接口文档、一般运维手册 | 仅授权用户和企业链路 |
| Sensitive | 手机号、地址、合同金额、患者标识 | 目的限制、最小化、假名化或脱敏 |
| Restricted | 密码、API Key、支付凭证、完整病历明细 | 默认阻断外部模型与普通日志 |
| Regulated | 医疗、金融、未成年人等受监管数据 | 合规评估、区域和审计控制 |
4.1 字段级目录
fieldName: patient_id
classification: Sensitive
purposes: [field_definition, authorized_case_analysis]
externalModelAllowed: false
localModelAllowed: conditional
logAction: HMAC_TOKEN
evaluationAction: SYNTHETIC_REPLACE
retentionDays: 30
owner: medical-data-governance4.2 分级不是只看字段名
自由文本可能包含手机号、病历和密钥;普通字段组合也可能重新识别个人。例如年龄、科室、稀有病和精确时间组合可能指向唯一患者。需要同时考虑:
- 显式标识符。
- 准标识符组合。
- 自由文本实体识别。
- 数据规模和可关联性。
- 处理目的和接收方。
五、目的限制与数据最小化
“有权限访问订单”不等于“可以把订单全部字段发给模型”。权限回答“能否访问”,目的限制回答“当前任务需要哪些字段”。
用户问订单是否发货,完整对象可能有:
{
"orderNo": "SO-1001",
"status": "SHIPPED",
"trackingNo": "YT123",
"phone": "13812345678",
"address": "北京市朝阳区...",
"internalCost": "83.60",
"paymentToken": "pay_secret"
}模型只需要:
{
"orderNo": "SO-1001",
"status": "SHIPPED",
"trackingNo": "YT123"
}flowchart TD
A["业务对象"] --> B["确认任务Purpose"]
B --> C["加载字段策略版本"]
C --> D{"字段是否为完成任务必需"}
D -- "否" --> E["Drop"]
D -- "是" --> F{"目的地是否允许该级别"}
F -- "否" --> G["阻断、改走本地或人工"]
F -- "是" --> H["保留、掩码、泛化或假名化"]
H --> I["发送最小上下文"]最小化应在调用 Provider 之前完成。只在模型输出后脱敏,敏感数据已经离开安全边界并可能进入 Provider 日志。
六、八种处理方式不能混为“脱敏”
| 方法 | 能否恢复 | 能否稳定关联 | 典型用途 |
|---|---|---|---|
| 删除 | 否 | 否 | 任务不需要的字段 |
| 掩码 | 原值仍在权威系统,展示不可逆方向 | 部分 | 给用户显示后四位 |
| 泛化 | 精度降低,通常不可直接恢复 | 可能 | 精确地址变城市、年龄变区间 |
| 摘要 | 只保留任务语义 | 取决于摘要 | 长记录变风险结论 |
| 假名化 | 通过受控映射可恢复 | 是 | patientId换随机Token |
| 普通哈希 | 理论不可逆,但可字典枚举 | 是 | 高熵内容校验,不适合裸哈希低熵PII |
| HMAC | 需密钥计算,防公开字典预计算 | 是 | 日志关联Token、去重 |
| 加密 | 持有密钥可恢复 | 是 | 存储或传输中保护原文 |
6.1 掩码
13812345678 → 138****5678适合展示,不等于匿名化。用户仍可能被其他字段识别。
6.2 假名化
patient_id=P1001 → subject_token=RANDOM-8f31映射表由独立受控服务保存。拿到映射或其他关联数据仍可还原主体,所以假名化数据仍应按敏感数据保护。
6.3 为什么手机号不能直接SHA-256后公开
手机号、身份证格式空间有限,攻击者可以枚举候选并计算相同哈希进行比对。盐能阻止通用预计算表,但如果盐公开且每条可验证,仍可能被逐条暴力枚举。
需要稳定关联又不暴露原值时,可使用服务端秘密密钥 HMAC:
token = HMAC(secretKey, normalizedValue)密钥必须在 KMS/Secret 中管理、限权和轮换。HMAC 也不是匿名化,拥有密钥或可查询 Token 服务仍能关联。
6.4 加密不等于最小化
数据在传输和存储时加密,进入模型计算前通常要解密。若模型根本不需要字段,正确措施是删除字段,而不是“加密后连同密钥一起发给模型”。
6.5 匿名化要求更高
真正匿名化要求合理方式下无法重新识别数据主体。只删姓名、换 ID 通常只是去标识或假名化。是否达到法律意义的匿名化需要结合攻击模型、外部数据和专业评估,文档不能用“打星号”直接宣称匿名。
七、传输加密、静态加密和信封加密
7.1 传输中
使用 TLS,校验证书和主机名;内部服务同样需要身份认证和网络策略。TLS 只保护链路,不能阻止接收方服务记录明文。
7.2 静态存储
数据库、对象存储、向量库、日志和备份都要考虑加密。磁盘加密防设备或快照直接泄露,但数据库管理员权限、应用查询权限仍要单独控制。
7.3 信封加密方向
flowchart TD
A["KMS中的主密钥KEK"] --> B["生成或解密数据密钥DEK"]
B --> C["DEK加密业务数据"]
C --> D["存储密文与被KEK加密的DEK"]
D --> E["授权服务请求KMS解封DEK"]
E --> F["内存中短暂解密使用"]应用不应把主密钥硬编码在配置、镜像、Prompt 或日志。密钥轮换需要版本、重加密策略、回滚和审计。
八、Prompt编排的数据安全
Prompt 可能包含:
- System/Developer 规则。
- 用户问题。
- 会话历史。
- RAG Chunk。
- Tool Result。
- Few-shot 示例。
每一部分都应有来源、分类、租户、保留和最大长度。
8.1 会话历史不是无限信任
历史中可能有已撤销权限的数据、过期 Token 或用户先前粘贴的隐私。每轮组装都应重新按当前身份和保留策略裁剪,不能因为曾经进入会话就永久可见。
8.2 Few-shot不能用真实敏感样本
示例会进入每个请求,真实患者和订单样本会被重复扩散。使用合成、匿名化并经审核的示例。
8.3 Prompt版本也可能敏感
System Prompt 可能包含内部流程、工具名称和风控规则。不要把密钥写入 Prompt;Prompt 存储需访问控制,但系统安全不能依赖“用户永远无法推断 Prompt”。
九、RAG全生命周期数据安全
flowchart TD
A["原始文档"] --> B["授权、分类和恶意内容检查"]
B --> C["解析、最小化和脱敏"]
C --> D["稳定docId、chunkId与ACL"]
D --> E["Embedding并写候选索引"]
E --> F["权限、删除和召回评估"]
F --> G["发布Alias"]
H["用户查询"] --> I["认证上下文生成Filter"]
I --> J["Filter-aware召回"]
J --> K["Rerank仍保留ACL"]
K --> L["Prompt预算与引用"]
L --> M["输出权限和引用校验"]9.1 入库前
- 确认文档处理授权和用途。
- 分类分级。
- 检测秘密、患者信息和恶意文档注入。
- 高敏内容决定阻断、脱敏、本地处理或不入库。
- 保存来源、owner、版本、tenantId、ACL、有效期。
9.2 Embedding也可能泄露信息吗
向量不是可直接阅读原文,但不能自动视为匿名。攻击者可能进行成员推断、相似性探测或利用关联数据推测内容;向量还关联 Metadata 和原文 ID。向量库、索引快照和 Embedding Cache 仍需权限、加密和删除治理。
9.3 检索时
tenantId、role、department、securityLevel 必须来自服务端认证上下文,在候选召回前或索引遍历中生效。Post-filter 不足以作为安全边界。
9.4 引用
模型只能返回本次已授权候选的 citationId;URL、页码和路径由应用根据真实 Metadata 渲染。不能让模型自由生成内部地址。
十、Tool Result数据安全
Tool 返回完整 Entity:
{
"status": "SHIPPED",
"phone": "13812345678",
"address": "...",
"paymentToken": "...",
"internalCost": "83.60"
}后端按场景执行字段投影:
{
"status": "SHIPPED",
"trackingNo": "YT123"
}步骤:
重新确认资源属于当前用户范围
→ 加载Purpose字段策略
→ Drop非必要字段
→ Mask/HMAC/泛化必要敏感字段
→ 限制条数、时间范围和文本长度
→ 删除内部异常栈与Header
→ 标记内容为不可信数据
→ 发送模型Tool Result 中的工单备注、网页和数据库自由文本可能包含 Prompt Injection,不能因为来源是内部服务就当成高优先级指令。
十一、第三方Provider评估
调用外部 Provider 前要形成可审计决策,而不是只看“企业版”标签。
11.1 数据处理问题清单
- 请求和响应是否保存,保存多久?
- 默认或可选是否用于训练、评估或人工审核?
- 数据处理区域和备份区域在哪里?
- 有哪些子处理者?
- 数据是否跨区域传输?
- 传输和静态加密如何做?
- 租户隔离和访问审计怎样实现?
- 删除、导出和事件通知能力是什么?
- Abuse Monitoring 是否保留内容?
- 合同、DPA、SLA 和事件响应责任如何约定?
具体结论必须基于当前合同和 Provider 文档,不能长期假设“API 数据一定不训练”。
11.2 Provider路由需要数据驻留约束
模型路由不仅看能力、延迟和价格,还要看:
dataClassification
allowedProviders
allowedRegions
retentionMode
localOnly高敏请求若没有合规可用模型,应拒绝、脱敏、转本地或人工,不能自动降级到数据边界更弱的 Provider。
11.3 本地模型也不自动安全
本地部署降低数据出组织边界风险,但仍有:
- 内部越权。
- 模型服务公网暴露。
- Prompt 明文日志。
- GPU 内存残留和临时文件。
- Tool 过度返回。
- 运维账号无审计。
- 备份和评估集扩散。
十二、日志、Trace和指标怎样记录
12.1 推荐默认记录
requestId、scene、tenantIdToken
principalIdToken、roles摘要
promptVersion、modelRoute、providerRegion
inputTokenCount、outputTokenCount
retrievedChunkIds、indexVersion
toolCallId、toolName、resultCode
policyVersion、classificationSummary
latency、status、errorType身份 Token 可使用受控 HMAC,使安全团队能关联同一主体而普通日志读者看不到原值。
12.2 默认不要记录
- 完整用户输入。
- 完整 Prompt。
- RAG 原文。
- 完整 Tool Result。
- 模型输出明文。
- Authorization Header、Cookie、API Key、密码。
12.3 受控调试样本
确需内容排障时:
- 明确工单和目的。
- 只采样必要请求。
- 先自动和人工复核脱敏。
- 单独加密存储。
- 最小人员访问。
- 短保留并自动删除。
- 记录访问审计。
指标标签不能放 patientId、手机号、完整 Query 等高基数字段,否则既泄露数据又拖垮指标系统。
十三、缓存为什么是高风险副本
AI 常见缓存:
- Prompt/响应缓存。
- Semantic Cache。
- Embedding Cache。
- RAG 结果缓存。
- Tool 结果缓存。
- Prefix/KV Cache。
13.1 Cache Key不能只有问题文本
至少考虑:
tenantIdToken
ACL或dataScopeHash
scene
promptVersion
modelVersion
knowledgeIndexVersion
embeddingRevision
toolDataVersion
locale否则 A 租户有权限的回答可能返回给 B 租户。
13.2 Value也要最小化
缓存完整 Prompt 或 Tool Entity 会形成长期敏感副本。优先缓存授权后的最小结果或稳定 ID,并设置 TTL、加密、容量和删除索引。
13.3 删除怎样命中缓存
只按 Query Hash 存缓存,很难按 dataSubjectId 或 docId 找出相关条目。可维护反向索引:
subjectToken/docId → cacheKeys或者使用短 TTL 和版本失效降低残留,但短 TTL 不能替代需要明确删除的场景。
十四、评估集和人工标注数据安全
线上失败样本常包含最真实也最敏感的数据。
14.1 入评估集前
- 确认用途和授权。
- 识别字段与自由文本实体。
- 用合成值替换手机号、身份证、订单号和患者标识。
- 保留任务难度,不保留真实身份。
- 文档片段按 ACL 和版权保存。
- 分离原始受控样本与可共享脱敏样本。
14.2 标注平台
- 标注人按项目和数据级别授权。
- 禁止本地下载、复制和截图方向的控制,具体结合终端治理。
- 水印、访问日志和异常下载告警。
- 标注说明不要暴露额外内部信息。
- 项目结束后撤权和删除导出。
14.3 LLM-as-Judge
把评估样本发送给另一个模型等于新增 Provider 和数据副本。Judge 也要经过同样的驻留、最小化和合同评估,不能因为它只“打分”就忽略数据安全。
十五、数据保留策略怎样设计
每类存储明确:
purpose
classification
retentionPeriod
retentionStart
deletionMethod
legalHoldPolicy
backupExpiry
owner
evidence不同对象可以不同:
| 对象 | 保留方向示例 |
|---|---|
| 会话原文 | 最短业务必要期,可由用户删除 |
| 脱敏运行日志 | 运维和安全审计期 |
| 高敏调试样本 | 极短、工单绑定 |
| 评估集 | 版本化并定期复核用途 |
| 不可变安全审计 | 按法规和组织政策保留,内容最小化 |
| 备份 | 按备份周期自然到期并防止恢复后复活 |
保留时长不能由文档凭空给统一数字,应由业务、法律和风险共同确定。
十六、删除请求为什么是分布式工作流
一个数据主体请求删除时,可能涉及:
业务主库
对象存储原文
RAG Chunk与向量
关键词索引
会话与Memory
Tool结果缓存
响应缓存
日志与Trace
评估集与标注导出
Provider留存
备份与灾备flowchart TD
A["接收删除请求并验证主体"] --> B["生成deletionId与subjectToken"]
B --> C["查询数据清单和Lineage"]
C --> D["向各可变存储发送删除任务"]
D --> E["立即禁止检索和使用"]
E --> F["各存储返回删除证据"]
F --> G["Provider删除或按合同确认"]
G --> H["备份登记到期不再恢复"]
H --> I["对账所有Required Target"]
I --> J{"是否全部完成或有合法例外"}
J -- "否" --> K["重试、告警或人工处理"]
J -- "是" --> L["关闭请求并保存最小审计证据"]16.1 先阻止继续使用
物理删除可能需要 Compaction 或备份到期。应先将主体/文档标为 revoked,所有检索、缓存和评估任务立即排除,再异步完成物理清理。
16.2 不可变日志和法定留存
有些安全审计或法律记录不能立即删除。设计时就应避免写入不必要原文,保存 HMAC Token、事件类型和最小证据。删除工作流对例外记录原因、范围、到期和审批,不能虚假声明已经物理擦除。
16.3 备份
离线备份通常不能逐条修改,否则破坏完整性。常见方向是:
- 在线系统立即删除/撤销。
- 备份按既定周期到期销毁。
- 恢复旧备份时重新应用删除清单,防止数据复活。
- 记录 backupExpiry 和恢复 Runbook。
十七、可运行Demo:Purpose驱动字段策略
下面仅使用 Python 标准库,演示相同业务对象在“外部模型上下文”和“运行日志”两个目的地下使用不同字段策略:
- 外部模型只保留发货状态所需字段。
- 手机号只在日志中掩码。
- patientId 在日志中用 HMAC Token 稳定关联。
- paymentToken、地址和内部成本始终删除。
- 未登记字段默认删除。
from __future__ import annotations
import hashlib
import hmac
import re
from enum import Enum
from typing import Any
class Action(str, Enum):
KEEP = "KEEP"
MASK_PHONE = "MASK_PHONE"
HMAC_TOKEN = "HMAC_TOKEN"
DROP = "DROP"
POLICIES: dict[str, dict[str, Action]] = {
"external_model_shipping_answer": {
"orderNo": Action.KEEP,
"status": Action.KEEP,
"trackingNo": Action.KEEP,
"phone": Action.DROP,
"patientId": Action.DROP,
"address": Action.DROP,
"internalCost": Action.DROP,
"paymentToken": Action.DROP,
},
"operations_log": {
"orderNo": Action.HMAC_TOKEN,
"status": Action.KEEP,
"trackingNo": Action.DROP,
"phone": Action.MASK_PHONE,
"patientId": Action.HMAC_TOKEN,
"address": Action.DROP,
"internalCost": Action.DROP,
"paymentToken": Action.DROP,
},
}
def mask_phone(value: str) -> str:
return re.sub(r"^(1[3-9]\d)\d{4}(\d{4})$", r"\1****\2", value)
def stable_hmac_token(value: str, secret: bytes) -> str:
normalized = value.strip().lower()
digest = hmac.new(secret, normalized.encode("utf-8"), hashlib.sha256).hexdigest()
return f"hmac256:{digest}"
def transform(
record: dict[str, Any], purpose: str, secret: bytes
) -> dict[str, Any]:
policy = POLICIES.get(purpose)
if policy is None:
raise ValueError("未登记Purpose,默认拒绝处理")
result: dict[str, Any] = {}
for field, value in record.items():
action = policy.get(field, Action.DROP)
if action is Action.KEEP:
result[field] = value
elif action is Action.MASK_PHONE:
result[field] = mask_phone(str(value))
elif action is Action.HMAC_TOKEN:
result[field] = stable_hmac_token(str(value), secret)
elif action is Action.DROP:
continue
return result
if __name__ == "__main__":
secret = b"demo-only-use-kms-in-production"
order = {
"orderNo": "SO-1001",
"status": "SHIPPED",
"trackingNo": "YT123",
"phone": "13812345678",
"patientId": "P-9001",
"address": "北京市朝阳区某小区",
"internalCost": "83.60",
"paymentToken": "pay_secret",
"unknownDebugField": "must-drop-by-default",
}
model_context = transform(order, "external_model_shipping_answer", secret)
log_context = transform(order, "operations_log", secret)
assert model_context == {
"orderNo": "SO-1001",
"status": "SHIPPED",
"trackingNo": "YT123",
}
assert log_context["phone"] == "138****5678"
assert log_context["patientId"].startswith("hmac256:")
assert "paymentToken" not in model_context and "paymentToken" not in log_context
assert "unknownDebugField" not in model_context and "unknownDebugField" not in log_context
print("external model:", model_context)
print("operations log:", log_context)Demo Secret 仅为教学,生产使用 KMS/Secret,并为 HMAC Key 记录版本。密钥轮换会改变 Token,需要双读迁移或明确旧新关联策略。
十八、可运行Demo:删除传播状态机
下面模拟删除请求必须等待所有 Required Target 确认;备份不能立即逐条擦除时,状态为 EXPIRY_SCHEDULED,并记录到期时间;任何 Target 失败都不能把请求标成完成。
from dataclasses import dataclass, field
from enum import Enum
class TargetStatus(str, Enum):
PENDING = "PENDING"
DELETED = "DELETED"
REVOKED = "REVOKED"
EXPIRY_SCHEDULED = "EXPIRY_SCHEDULED"
FAILED = "FAILED"
@dataclass
class Target:
name: str
status: TargetStatus = TargetStatus.PENDING
evidence: str | None = None
@dataclass
class DeletionRequest:
deletion_id: str
subject_token: str
targets: dict[str, Target] = field(default_factory=dict)
def complete(self) -> bool:
acceptable = {
TargetStatus.DELETED,
TargetStatus.REVOKED,
TargetStatus.EXPIRY_SCHEDULED,
}
return bool(self.targets) and all(
target.status in acceptable and target.evidence
for target in self.targets.values()
)
if __name__ == "__main__":
request = DeletionRequest(
deletion_id="del-20260716-001",
subject_token="hmac256:subject-demo",
targets={
name: Target(name)
for name in ["business_db", "rag_index", "cache", "evaluation_set", "backup"]
},
)
request.targets["business_db"] = Target(
"business_db", TargetStatus.DELETED, "db-audit-101"
)
request.targets["rag_index"] = Target(
"rag_index", TargetStatus.REVOKED, "index-tombstone-202"
)
request.targets["cache"] = Target(
"cache", TargetStatus.DELETED, "cache-purge-303"
)
request.targets["evaluation_set"] = Target(
"evaluation_set", TargetStatus.FAILED, "eval-worker-timeout"
)
request.targets["backup"] = Target(
"backup",
TargetStatus.EXPIRY_SCHEDULED,
"expires-2026-08-15-and-reapply-ledger-on-restore",
)
assert request.complete() is False
request.targets["evaluation_set"] = Target(
"evaluation_set", TargetStatus.DELETED, "eval-delete-404"
)
assert request.complete() is True
print("deletion complete:", request.complete())
for target in request.targets.values():
print(target.name, target.status.value, target.evidence)真实状态需要持久化、版本控制、重试队列、Deadline、法定例外审批和定期对账;不能只存在单进程内存。
十九、商业场景:医疗数据资产AI助手
19.1 场景
用户询问字段定义、采集异常和资产摘要。系统拥有医疗数据标准、接口文档、采集日志和部分患者标识。
19.2 安全链
flowchart TD
A["用户登录"] --> B["服务端获得医院、部门、角色和密级"]
B --> C["识别field_definition或incident_analysis Purpose"]
C --> D["RAG按tenant与ACL召回"]
D --> E["Tool按数据范围查询最小日志字段"]
E --> F["字段策略Drop患者值、连接密钥和内部地址"]
F --> G{"分类是否允许目标Provider"}
G -- "否" --> H["本地模型、进一步脱敏或人工"]
G -- "是" --> I["发送最小Prompt"]
I --> J["输出实体检测、引用和权限复核"]
J --> K["返回字段含义与证据,不返回真实患者样例"]19.3 字段解释和真实值必须分开
允许回答:
patient_id是患者标识字段,用于关联患者业务记录,属于敏感字段。不应为了“举例”检索和输出真实身份证或患者编号。教学示例使用明确的合成数据。
19.4 采集日志
日志查询工具只返回:
assetId、time、reasonCode、evidenceId、retryable删除连接串、用户名、密码、患者 ID、原始 SQL 和完整异常栈。需要深度排障时由受控运维系统查看,不通过普通聊天 Prompt 扩散。
二十、数据安全事件响应Runbook
20.1 发现模型输出了越权或敏感数据
- 立即关闭受影响场景、Provider 路由或切安全降级。
- 保存最小取证信息:requestId、时间、版本、主体 Token,避免再次复制明文。
- 确认数据来源:用户历史、RAG、Tool、缓存、Few-shot、模型参数或日志回灌。
- 检查谁接收了数据:终端用户、Provider、日志、评估流水线、人工标注。
- 阻断继续访问,清理缓存和候选索引,修复 ACL/字段策略。
- 按组织事件响应和通知流程评估影响范围。
- 加入确定性权限测试和脱敏回归样本。
20.2 日志中发现API Key或支付Token
- 先吊销并轮换密钥,不能只删日志。
- 确认日志索引、归档、备份、转发和告警系统中的副本。
- 限制日志访问并清理可变副本。
- 检查密钥是否被使用和是否存在异常调用。
- 修复源头字段策略、日志拦截和 Secret 扫描。
20.3 删除请求长期卡住
- 查看 deletionId 的各 Target 状态和最后错误。
- 检查稳定 subjectToken/docId 是否能定位所有副本。
- 检查评估集、标注导出和缓存是否缺反向索引。
- 对不可变日志确认最小化和合法保留例外。
- 对备份确认到期日期和恢复重放删除清单。
- 超出删除 SLO 时告警和人工升级,不能自动标完成。
20.4 外部Provider策略发生变化
- 暂停受影响分类的数据路由。
- 对比留存、训练、区域、子处理者和删除条款。
- 更新 Provider Allowlist 和 Policy Version。
- 使用安全评估集验证新路由。
- 必要时迁移到其他区域、本地模型或人工流程。
20.5 缓存出现跨租户回答
这是严重越权事故:
- 立即禁用相关缓存。
- 检查 Key 是否包含 tenant、ACL、Prompt、模型和索引版本。
- 根据缓存访问日志评估哪些主体收到错误结果。
- 清空污染缓存并轮换命名空间。
- 补 A/B 租户相同 Query 的隔离测试。
二十一、常见误区与后果
| 误区 | 正确理解 |
|---|---|
| 输出打星就安全 | 数据可能已进入Provider、日志和缓存 |
| 删除姓名就是匿名化 | 准标识符组合仍可重新识别 |
| 手机号SHA-256不可破解 | 低熵格式可被枚举,应最小化或受控HMAC |
| 加密后可以随便发送 | 接收方计算时会看到明文,先判断是否需要 |
| 向量不是原文所以不敏感 | 向量可被探测且关联Metadata,仍需治理 |
| 本地模型天然安全 | 内部越权、日志、备份和服务暴露仍存在 |
| Cache Key用Query即可 | 会跨租户、跨权限和跨版本串数据 |
| 评估集只是测试数据 | 常来自真实失败样本,是长期敏感副本 |
| 删除主库记录就完成 | RAG、缓存、Provider、评估集和备份仍存在 |
| 不可变日志可以记录完整Prompt | 应从源头最小化,只保留必要审计证据 |
二十二、面试标准回答
22.1 AI数据安全怎样做
先建立用户输入、RAG、Tool、Prompt、Provider、日志、缓存和评估集的数据流清单;按字段和自由文本分类分级,基于 Purpose 最小化数据;RAG 在召回前做租户和 ACL,Tool Result 做字段投影和脱敏;Provider 路由考虑留存、训练使用、区域和子处理者;所有副本设置加密、访问审计、保留和删除传播。
22.2 脱敏、假名化、哈希和加密有什么区别
掩码用于展示部分信息;假名化用受控 Token 替换身份,保留可关联性且可能恢复;普通哈希对低熵手机号容易被枚举,稳定关联更适合受控 HMAC;加密持有密钥可以恢复,用于传输和存储保护。它们都不能替代数据最小化,假名化也不自动等于匿名化。
22.3 为什么不能记录完整Prompt
完整 Prompt 聚合用户输入、历史、RAG 片段、Tool Result 和系统规则,日志又会被索引、转发、备份和更多人员访问,形成新的高风险副本。生产默认记录 requestId、版本、Chunk ID、Token、耗时和脱敏/HMAC主体标识;内容调试要工单授权、采样、脱敏、加密和短期自动删除。
22.4 第三方模型数据安全要评估什么
评估请求和响应的留存时间、是否用于训练或人工审核、处理与备份区域、跨境和子处理者、加密与租户隔离、删除导出能力、事件通知和合同责任。路由还要按数据级别配置允许 Provider/区域;高敏数据不能因主模型故障自动降级到未批准 Provider。
22.5 为什么删除请求是分布式工作流
同一数据可能存在业务库、RAG Chunk与向量、关键词索引、会话、缓存、日志、评估集、Provider和备份。删除请求要用稳定主体 Token 枚举 Target,先撤销检索和使用,再异步删除并收集证据;备份按周期到期且恢复时重放删除清单,法定留存记录例外,所有 Required Target 完成后才能关闭。
22.6 AI缓存为什么必须带权限和版本
同一个 Query 在不同租户、dataScope、Prompt、模型和知识库版本下结果不同。Key 只有问题文本会把 A 用户有权数据返回给 B 用户,也会返回过期索引结果。Key 至少包含租户 Token、ACL Hash、场景、Prompt、模型、索引和 Embedding Revision,Value 也只保存最小必要数据。
更多简洁回答见 AI应用工程化面试题,完整原理以本页为准。
二十三、关联知识点
- AI安全:Prompt Injection、工具越权和输出安全。
- Prompt任务编译:可信边界、上下文预算和日志版本。
- RAG数据治理:来源、ACL、删除和发布。
- 向量数据库:Filter、墓碑、备份和恢复。
- Tool Calling:字段投影、权限、审计和UNKNOWN。
- LLMOps:版本、评估、监控和事件响应。
- 信息安全:加密、签名、密钥和TLS基础。
二十四、学习验收清单
- [ ] 能画出AI数据的全部常见副本和处理者。
- [ ] 能为字段定义级别、Purpose、目的地和保留策略。
- [ ] 能区分掩码、泛化、假名化、匿名化、哈希、HMAC和加密。
- [ ] 能解释为什么低熵PII不能只做普通哈希。
- [ ] 能实现默认Drop的字段最小化策略。
- [ ] 能解释RAG向量为什么不能自动视为匿名数据。
- [ ] 能设计Provider Allowlist、Region和Retention路由。
- [ ] 能设计日志内容、受控调试和指标标签边界。
- [ ] 能设计租户与ACL隔离的缓存Key和删除反向索引。
- [ ] 能治理评估集、标注平台和LLM-as-Judge的数据副本。
- [ ] 能画出删除请求的Target状态机和备份到期处理。
- [ ] 能说明法定留存例外为何不能虚假标记为已物理删除。
- [ ] 能根据requestId和subjectToken完成泄露影响面排查。
达到这些标准后,才算理解 AI 数据安全,而不是只会说“敏感信息要脱敏”。
