基于大模型判断数据库字段是否为敏感数据,识别敏感类型与级别,用于诊断环的敏感资产发现
接收 metadata-query 的输出,利用大模型的语义理解能力,结合字段名、字段注释、样例数据, 判断每个字段是否为敏感数据,并输出敏感类型与敏感级别。
metadata-query(输入:表结构 + 样例数据)
│
▼
sensitive-identifier(本 Skill)
│
▼
输出给 access-decision(作为脱敏依据)
输出给 risk-alert(作为告警内容)
直接消费 metadata-query 的输出 JSON,无需额外参数。
{
"schema": "模式名",
"tables": [
{
"table_name": "T_USER",
"columns": [
{
"column_name": "PHONE",
"data_type": "VARCHAR",
"data_length": 20,
"comment": "手机号码"
}
],
"sample_data": [
{ "ID": 1, "PHONE": "13800138000", "NAME": "张三" },
{ "ID": 2, "PHONE": "13900139000", "NAME": "李四" }
]
}
]
}
metadata-query 输出的 sample_data 为行级对象数组,本 Skill 需按以下规则提取为字段级的 sample_values(字符串数组):
对每个 table:
对每个 column:
column.sample_values = sample_data
.map(row => row[column.column_name])
.filter(val => val !== null && val !== undefined)
.slice(0, 5) // 最多保留 5 个样例值
提取后的内部数据结构:
{
"column_name": "PHONE",
"sample_values": ["13800138000", "13900139000"]
}
对每个字段,综合以下三个信号进行判断:
| 信号 | 来源 | 权重 |
|---|---|---|
| 字段名 | column_name | 高(如 PHONE、ID_CARD、BANK_ACCOUNT) |
| 字段注释 | comment | 高(如"手机号"、"身份证"、"密码") |
| 样例数据 | sample_values | 中(如 13800138000、110101199001011234) |
使用以下标准分类体系:
{
"personal_identity": ["身份证号", "护照号", "军官证", "社保号"],
"personal_contact": ["手机号", "固定电话", "电子邮箱", "通讯地址"],
"financial": ["银行卡号", "支付账号", "交易金额", "账户余额"],
"authentication": ["密码", "支付密码", "安全问题答案", "生物特征"],
"health": ["病历号", "诊断信息", "用药记录", "体检报告"],
"location": ["GPS坐标", "家庭住址", "常驻地"],
"other": ["其他自定义敏感类型"]
}
| 级别 | 判定条件 | 示例 |
|---|---|---|
| HIGH | 可直接用于身份冒用或财产损失 | 身份证号、银行卡号、密码 |
| MEDIUM | 可关联到个人但不可直接造成损失 | 手机号、邮箱、住址 |
| LOW | 批量后可能有隐私风险 | 性别、年龄段、职业 |
当字段名和注释不明确、样例数据也不典型时,输出低置信度标记,建议人工复核。
| 策略枚举 | 中文名称 | 适用场景 | 示例 |
|---|---|---|---|
MASK_FULL | 完全掩码 | 不需要原始值 | 138****1234 → *********** |
MASK_PARTIAL | 部分掩码 | 保留可读性 | 138****1234 |
FPE_ENCRYPT | 格式保留加密 | 需要可逆、保持格式 | 13800138000 → 15699827211 |
GENERALIZATION | 泛化 | 统计分析场景 | 25岁 → 20-30岁 |
PERTURBATION | 扰动/加噪 | 数值类敏感数据 | 10000 → 10234 |
AGGREGATION | 聚合 | 批量查询场景 | 单条金额 → 月总额 |
RANDOM_REPLACE | 随机替换 | 测试环境 | 真实姓名 → 随机假名 |
REDACTION | 直接删除 | 非必须字段 | 整列删除或返回 NULL |
TOKENIZATION | 令牌化 | 需要关联查询 | 真实值 ↔ Token 映射表 |
{
"schema": "模式名",
"scan_time": "2024-01-01T00:00:00Z",
"results": [
{
"table_name": "T_USER",
"column_name": "PHONE",
"is_sensitive": true,
"sensitive_type": "personal_contact",
"sensitive_type_label": "个人联系方式",
"sensitive_level": "MEDIUM",
"confidence": 0.95,
"evidence": "字段名 PHONE 暗示手机号,样例数据匹配 11 位手机号格式",
"masking_strategy": "MASK_PARTIAL",
"masking_strategy_label": "部分掩码",
"recommendation": "建议脱敏显示为 138****1234,保留前3后4位用于客服核对",
"alternative_strategies": ["FPE_ENCRYPT", "RANDOM_REPLACE"]
},
{
"table_name": "T_USER",
"column_name": "ID_CARD",
"is_sensitive": true,
"sensitive_type": "personal_identity",
"sensitive_type_label": "身份证号",
"sensitive_level": "HIGH",
"confidence": 0.99,
"evidence": "字段名 ID_CARD 暗示身份证号,样例数据匹配 18 位格式",
"masking_strategy": "FPE_ENCRYPT",
"masking_strategy_label": "格式保留加密",
"recommendation": "建议使用 FPE 保持身份证18位格式,支持审计追溯时解密",
"alternative_strategies": ["MASK_PARTIAL", "TOKENIZATION"]
},
{
"table_name": "T_USER",
"column_name": "AGE",
"is_sensitive": true,
"sensitive_type": "other",
"sensitive_type_label": "其他",
"sensitive_level": "LOW",
"confidence": 0.85,
"evidence": "字段名 AGE 表示年龄,属于弱隐私信息",
"masking_strategy": "GENERALIZATION",
"masking_strategy_label": "泛化",
"recommendation": "建议将具体年龄转换为年龄段(如 20-30岁)",
"alternative_strategies": ["AGGREGATION"]
},
{
"table_name": "T_ORDER",
"column_name": "CREATE_TIME",
"is_sensitive": false,
"evidence": "创建时间不属于个人敏感数据"
}
],
"statistics": {
"total_columns": 20,
"sensitive_columns": 8,
"high_risk": 2,
"medium_risk": 4,
"low_risk": 2
}
}
ID 在用户表和订单表中含义不同)HIGH 级别(身份证、银行卡):优先 FPE_ENCRYPT 或 TOKENIZATION,需支持可逆MEDIUM 级别(手机号、邮箱):优先 MASK_PARTIAL,保留必要可读性LOW 级别(年龄、性别):优先 GENERALIZATION 或 AGGREGATIONRANDOM_REPLACE,避免真实数据泄露REDACTION 直接删除