脱敏闸门 · 上传前敏感信息拦截
在内容离开本机之前拦住它。
这是什么,不是什么
| 做法 | 问题 | |
|---|---|---|
| 常见做法 | 把内容涂黑给你看 | 涂完你自己也不知道有没有漏;原始内容可能已被传给第三方模型 |
| 脱敏闸门 | 判定"能不能发" + 生成"能发的副本" + 提交前自动拦截 | —— |
三条硬承诺:
1. 断网运行——只用 Python 标准库,不调用任何 LLM / API / 网络服务。你的原文一个字节都不出本机。
2. 双域覆盖——密钥凭据 + 个人隐私一次扫全。现有工具通常只做一半。
3. 能当闸门用——gate 命中即 exit 1,可直接接 CI;hook-install 一键装 pre-commit。
什么时候用
- 要把代码、配置、日志、表格发给外部(同事、群聊、论坛、AI 对话框、在线表格)之前
- 想在
git commit之前卡住含密钥的文件 - 排查仓库里已经存在的密钥
- 需要一批"长得像真的、但不是真的"测试数据
一分钟上手
# 0) 先自测,确认工具本身正常(用内置虚构样本)
python3 scripts/redact.py selftest
# 1) 扫描:看有没有敏感信息
python3 scripts/redact.py scan ./src
python3 scripts/redact.py scan ./src --json # 机器可读
# 2) 判定:这个东西能不能发出去(命中高危 exit 1)
python3 scripts/redact.py gate ./report.csv
python3 scripts/redact.py gate ./report.csv --strict # 连 PII 也拦
# 3) 脱敏:生成可安全发送的副本
python3 scripts/redact.py redact --src ./report.csv --dst ./report_safe.csv
# 4) 提交拦截:装 git pre-commit 钩子
python3 scripts/redact.py hook-install
4 种脱敏策略怎么选
| 策略 | 效果 | 用在什么时候 |
|---|---|---|
pseudonym (默认) |
保格式假名,同一实体恒等映射 | 要保留数据可用性(测试数据、样例给外部) |
mask |
遮蔽主体,保留特征位 | 只要能看出"是手机号"就够 |
hash |
加盐 HMAC 截断,不可逆 | 需要做关联统计但不能还原 |
remove |
整段删除 | 要"扫不出来"就用这个 |
> ⚠️ 保格式假名的代价:假身份证仍是合法身份证格式,扫描器照样能认出它是身份证。
> 目标是"上传后绝对扫不出",就用 --strategy remove;目标只是"别泄露真实数据",用默认的 pseudonym 就够。
# 全局改策略
python3 scripts/redact.py redact --src in.csv --dst out.csv --strategy remove
# 按类型单独指定
python3 scripts/redact.py redact --src in.csv --dst out.csv \
--kind-strategy cn_mobile=mask --kind-strategy email=pseudonym
安全降级是强制的:密钥类(私钥/API Key/AK/JWT/连接串)和口令类,即使你指定 pseudonym 或 mask,也一律降级为 remove——假造一个"看起来还能用"的密钥,或者只遮一半的密钥,都是危险的做法。
12 类检测器
密钥凭据侧:private_key(PEM 私钥)· platform_key(OpenAI/Anthropic、GitHub、GitLab、Slack、HuggingFace、Stripe、Google、npm、SendGrid、Square、Doppler 等)· cloud_ak(AWS/腾讯云/阿里云)· jwt · db_url · password_assign
隐私侧:cn_id_card(GB11643 校验位)· cn_bank_card(Luhn)· cn_mobile · email · private_ip · internal_domain
全部带校验位验证,不是裸正则硬匹配:18 位数字必须通过身份证校验位才报,16-19 位必须通过 Luhn 才报,JWT 必须能解出 header 且含 alg 才报——这大幅压低了误报。
> 完整规则、正则与校验算法、误报控制见 references/检测规则库.md。
接进 CI
# .github/workflows/ci.yml
- name: 上传前敏感信息闸门
run: python3 scripts/redact.py gate . --strict
gate 命中即 exit 1,流水线直接失败。
边界与免责
- 只处理文本类文件:
.py/.js/.md/.json/.yaml/.toml/.txt/.log/.csv/.env等。PDF/Word/Excel 的二进制深度改写不在范围内(本工具会跳过它们,不做半吊子的处理)。 - 不识别人名、中文地址、任意格式的自定义密钥——规则型检测有边界,强依赖大模型的那类技能反而会把原文传出去。
- 脱敏不能替代密钥吊销:真密钥外泄过,第一件事是去平台吊销轮换,脱敏只是止血。
- 编码兼容 UTF-8(严格保留 BOM 有无)与 GBK;目录扫描自动跳过
.git、node_modules、二进制与常见大文件。 - 假名映射表(
--map-out)含明文原值,必须加密保管并加入.gitignore。
> 策略取舍与假名表管理见 references/策略选型与假名表.md;人工上传前 checklist 与 CI 接入见 references/上传前检查清单.md。
输入输出示例
- 输入:一段含「身份证 11010519491231002X,卡号 6222 0202 0000 1234 567」的文本 + 策略「假名化」
- 输出:脱敏后全文(假身份证仍过校验位、假卡号仍过 Luhn,下游可继续跑通)+ 风险清单(类型/位置/等级)。
常见问题
- 和付费版怎么选? 本地版全文不出本机;要在服务器流水线直接调 API 或不想装环境才用付费版。
- 会漏检吗? 12 类覆盖常见格式,自造格式的敏感值(如手写的非常规工号)不在检测范围,结果里会声明这一点。