Data Desensitization Skill (v3)
能力概述
对任意格式的数据执行隐私脱敏,内置中国个人隐私识别规则,支持用户追加自定义字段和策略。
v3 核心升级:
- 策略注册表(StrategyRegistry):6 种内置策略,支持运行时注册自定义策略
- XML 标签名匹配:
<password>secret</password>现在也能命中 - YAML 引号保留:
password: "secret"→password: "[REDACTED]",引号不丢失 - YAML 列表项脱敏:
- 手机13812345678也会被扫描 - INI/Properties 合并基类:消除代码重复,保留原始分隔符(
=/:) - Log 引擎修复:custom_fields 不再遗漏
- JSON 格式保持:单行 JSON 输出仍为单行
- 中文宽度感知:姓名脱敏
张三→张*,视觉对齐更准确
支持的文件格式
| 格式 | 扩展名 | 引擎 | 说明 | |------|--------|------|------| | 纯文本 | .txt | TextEngine | 正则全文扫描 | | JSON | .json | JSONEngine | 递归遍历 + 文本值正则 + 格式保持 | | CSV | .csv | CSVEngine | 列名匹配 + 正则 | | TSV | .tsv | TSVEngine | 制表符分隔 | | YAML | .yaml/.yml | YAMLEngine | 行级解析 + 引号保留 + 列表项 | | XML | .xml | XMLEngine | 标签名 + 属性 + 文本内容 | | Markdown | .md | MarkdownEngine | 代码块保护 | | INI | .ini/.cfg | INIEngine | section/key=value + 分隔符保留 | | Properties | .properties | PropertiesEngine | Java 属性文件 | | 日志 | .log/.out | LogEngine | 逐行正则扫描 |
格式自动检测:根据文件扩展名自动选择引擎,也可用
--format强制指定。
工作流程
Phase 1:分析数据与需求
- 判断用户输入的数据类型(文本片段 / 文件路径)。
- 如为文件,自动检测格式(支持 10+ 种扩展名)。
- 确认是否有自定义字段要求(如用户说"把
company_id也脱敏")。 - 如用户未指定策略,采用默认规则(见
references/desensitize_rules.md)。
在分析时,读取 references/desensitize_rules.md 以了解完整的内置规则和字段关键词映射。
Phase 2:选择执行方式
根据数据规模和复杂度,选择以下两种方式之一:
方式 A:调用脚本(推荐,适合文件和大量数据)
使用 scripts/desensitize.py 脚本处理。系统 Python 命令为 python3。
常用命令示例:
# 脱敏自由文本
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py \
--text "手机:13812345678,邮箱:user@example.com"
# 自动脱敏 JSON 文件(含文本值正则扫描)
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py \
--file /path/to/data.json --auto --show-hits
# 脱敏 YAML 配置文件
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py \
--file /path/to/config.yaml --fields "password:remove,api_key:remove" --show-hits
# 脱敏 XML 文件(标签名 + 属性双重匹配)
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py \
--file /path/to/data.xml --auto --output data_masked.xml
# 脱敏 Markdown(代码块保护)
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py \
--file /path/to/readme.md --auto --show-hits
# 脱敏日志文件
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py \
--file /path/to/app.log --auto --output app_masked.log
# 脱敏 INI 配置(保留原始分隔符)
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py \
--file /path/to/settings.ini --fields "db_password:remove"
# 仅字段名匹配,关闭正则扫描
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py \
--file /path/to/data.json --auto --no-regex --show-hits
# Dry Run:仅查看哪些字段会被命中
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py \
--file /path/to/data.json --auto --dry-run
# 列出所有支持的格式
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py --list-formats
# 列出所有脱敏策略
python3 ~/.workbuddy/skills/data-desensitization/scripts/desensitize.py --list-strategies
脚本参数速查:
| 参数 | 说明 |
|------|------|
| --text / -t | 直接传入文本字符串 |
| --file / -f | 输入文件路径(自动检测格式) |
| --output / -o | 输出文件路径(默认打印终端) |
| --fields | 自定义字段,逗号分隔,支持 field:strategy |
| --strategy / -s | 默认策略(mask/hash/remove/email_mask/name_mask/keep_prefix) |
| --auto / --no-auto | 开启/关闭自动检测(默认开启) |
| --no-regex | 关闭对文本值的正则扫描(仅字段名匹配) |
| --format | 强制指定格式(json/csv/tsv/yaml/xml/markdown/ini/properties/log/text) |
| --show-hits | 打印命中的字段或规则 |
| --dry-run | 仅输出命中信息,不执行脱敏 |
| --list-formats | 列出所有支持的格式 |
| --list-strategies | 列出所有脱敏策略 |
方式 B:内联处理(适合小段文本或简单结构)
当用户粘贴的数据量很小(< 50行 / < 3KB),直接在回复中完成脱敏并展示结果,无需调用脚本。
内联处理规则(按优先级):
- 手机号 →
138****5678(前3后4) - 身份证 →
1101**********1234(前4后4) - 邮箱 →
u***@e***.com - 银行卡号 →
6222********7890(前4后4) - 密码/Token →
[REDACTED] - 姓名 →
张*(保留姓氏) - IP 地址 →
***.***.***.*** - 地址 →
上海市***
Phase 3:输出结果
- 脱敏后的数据:完整展示脱敏结果。
- 命中摘要:列出被脱敏的字段/规则及数量。
- 策略说明(可选):如用户询问,解释各字段采用的策略及原因。
- 输出文件:如用户提供了文件路径,说明脱敏后文件的保存位置。
支持的脱敏策略
| 策略 | 效果 | 示例 |
|------|------|------|
| mask | 中间掩码,保留首尾 | 138****5678 |
| email_mask | 邮箱专用掩码 | u***@e***.com |
| name_mask | 姓名专用:保姓掩名(中文宽度感知) | 张* |
| hash | SHA256 前16位 | a3f2c891b04d7e12 |
| remove | 完全替换为 [REDACTED] | [REDACTED] |
| keep_prefix | 仅保留前N位 | 上海市*** |
策略注册表支持运行时扩展:通过
STRATEGY_REGISTRY.register(name, fn)添加自定义策略。
默认隐私字段覆盖范围
内置自动识别以下字段(文本正则和字段名双重检测):
- 通讯类:手机号、固话、邮箱
- 证件类:身份证、护照、驾照(通用18位格式)
- 金融类:银行卡号、账号、薪资收入
- 凭证类:密码、密钥、Token、API Key(默认 remove)
- 位置类:家庭地址、IP 地址
- 人员类:姓名、用户名
- 时间类:生日、出生日期
详细规则和字段关键词映射见 references/desensitize_rules.md。
格式特殊处理
JSON:双重脱敏 + 格式保持
- 字段名匹配 + 文本值正则扫描
- 单行保持:原始 JSON 为单行时,输出仍为单行
- 空值(
""、null)不触发脱敏
XML:标签名 + 属性 + 文本
- 标签名匹配:
<password>secret</password>→<password>[REDACTED]</password> - 属性匹配:
<user phone="13812345678"/>→phone字段命中 - 引号类型保留:原始用双引号就保留双引号
YAML:引号保留 + 列表项
- 引号包裹保留:
password: "secret"→password: "[REDACTED]" - 列表项脱敏:
- 手机13812345678也会被扫描 - 中文 key:
用户:形式的 key 正常解析 - 行级解析,无需 PyYAML 依赖
Markdown:代码块保护
正文区域的隐私信息会被脱敏,但代码块(```围栏和行内代码)内容保持原样。
INI/Properties:分隔符保留
- 保留原始分隔符(
=或:) - 注释行和空行原样保留
- 代码结构合并为
_KvLineEngine基类
日志:格式保留
逐行正则扫描,保留时间戳、日志级别等结构信息。custom_fields 逻辑已修复。
常见场景处理
场景1:用户粘贴一段含隐私的文本
→ 直接使用内联方式处理,展示脱敏前后对比。
场景2:用户上传/指定 JSON 文件
→ 调用脚本 --file xxx.json --auto --show-hits,输出脱敏结果。
场景3:用户要求对 YAML 配置脱敏
→ 调用脚本 --file config.yaml --auto --show-hits。
场景4:用户要求对特定字段脱敏
→ 解析用户指定字段,构建 --fields 参数,调用脚本。
场景5:用户要求脱敏后保存新文件
→ 在原文件名末尾追加 _masked,使用 --output 参数写入。
场景6:用户说"只脱敏手机和邮箱,不要改其他的"
→ 使用 --no-auto --fields "phone:mask,email:email_mask" 关闭自动检测,仅处理指定字段。
场景7:用户上传日志文件
→ 调用脚本 --file app.log --auto --output app_masked.log。
场景8:用户上传 Markdown 文档
→ 调用脚本 --file doc.md --auto,代码块自动保护。
场景9:用户上传 XML 数据
→ 调用脚本 --file data.xml --auto,标签名+属性双重匹配。
注意事项
- 脱敏操作不可逆,执行前可先运行
--dry-run确认影响范围。 - 处理敏感文件时,建议在告知用户后再写入磁盘。
- 超大文件(> 100MB)建议先询问用户是否分批处理。
- 如用户需要可逆加密(而非不可逆脱敏),说明这超出本 Skill 范围,建议使用对称加密方案。
- XML 引擎使用正则解析,超复杂嵌套 XML(如 SOAP 消息)建议先用文本模式预览。
- YAML 引擎为纯 Python 实现,不支持多行字符串折叠、锚点引用等高级特性。
微信扫一扫