Files
patbond-doc/docs/development/iterations/iteration-3/12-secret-scan-rollout.md
T
lixi f17e6f1215
CI / docs-build (push) Successful in 34s
docs: M3 第一波收口——报告 09~14 与契约草案入档挂导航
- 09 V5+community 骨架(191→206)、10 埋点队列三项(272→286)、
  11 契约草案(13 路径/19 操作)、12 防泄漏三仓落地、
  13 media MinIO 闭环 + auth 契约测试(→226,抓修 1 漂移)、14 收口总表
- backend-modules.md 更新五模块/六容器口径
- 媒体凭据形态已定型(契约冻结输入),剩余待定型点在 T3-04/05

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-08 17:13:49 +08:00

6.7 KiB
Raw Blame History

12 M3 第一波:凭证防泄漏检查落地(ADR-021)

  • 执行人:Git Workflow Master
  • 日期:2026-09-08
  • 依据:ADR-021(CI 兜底 grep 第一波必做、先于 MinIO 凭证进开发机)、iteration-3/08 §4 两层纯 shell 方案
  • 交付边界:本报告只记录,不入 mkdocs 导航;T3-03 自本波 CI 全绿起解除对象存储凭证引入限制。

1. 落地形态

两层检查、同一规则表,单一来源为各仓入库的 scripts/check-secrets.sh(纯 shell + git + grep,零外部依赖、零外部 action,符合三仓 CI「手动克隆本实例」模式约束)。三仓副本内容逐字节同构(cp -p 分发),调整规则时三仓同步提交。

载体 触发 扫描范围
第一层(推荐) scripts/hooks/pre-commit → 同一脚本 --staged 本地 git commitgit config core.hooksPath scripts/hooks 启用,每人每仓一次) 暂存区内容 + 暂存文件名
第二层(强制兜底) 三仓 ci.yml checkout 后首个 step,同一脚本 --all 每次 push / PR 全部已跟踪文件(本次 push 变更文件的超集;--force-with-lease--no-verify 均无法绕过)

CI 采用 --all 而非「仅 diff 变更文件」的原因:三仓 CI 均为 depth-1 浅克隆,无可靠的 push 前基点可 diff;全量扫描是变更文件的严格超集且实测最慢仓仅 6.7 秒,顺带覆盖历史存量。ci.yml 只加 step,既有逻辑零改动。

2. 规则集清单(9 条)

内容规则 8 条(规则表内 ID):

ID 检测 形态
AK-AWS AWS/MinIO S3 兼容 AK AKIA + 16 位大写字母数字
AK-QCLOUD 腾讯云 SecretId AKID + 16 位以上字母数字
AK-ALIYUN 阿里云 AK LTAI + 12 位以上字母数字
MINIO-DEFAULT MinIO 默认凭证 minio·admin 及连写变体(忽略大小写)
PRIVATE-KEY 私钥块 独占一行-----BEGIN …PRIVATE KEY----- PEM 头
KEY-ASSIGN access/secret key 实值赋值 accessKey/secret_key/… 后接 :/= 与 8 位以上实值
JWT-SECRET JWT/签名密钥材料 jwt-secret/signing-key/token-secret/hmac-key 赋值实值
DB-PASSWORD 数据库口令非注入形态 仅限配置类文件(yml/yaml/properties/toml/conf/ini 及其 .sample/.example),password/passwd/pwd 赋 6 位以上非 ${} 实值

文件名黑名单 1 条(NAME-DENY):.env/.env.*credentials*、密钥导出 CSVrootkey.csv*accessKeys*.csv 形态)本体禁入版本库;.sample/.example 后缀豁免。

允许清单(行级放行):${…}/{{…}} 注入形态、changeme/change-meyour-xxx<占位>placeholder/example/sample/dummy/fake/redacted***。二进制文件经 grep -I 自然跳过;脚本与 hook 自身(含规则文本)路径豁免。

2.1 关键校准(避免误伤的两处设计)

  1. PRIVATE-KEY 采用「PEM 头独占一行」判据patbond-api 有两处合法的 PEM 头字面量——TestJwtKeys.java(测试密钥运行时生成,无入库密钥材料)与 RsaPrivateKeyLoader.java(解析代码的 .replace(...))。两处 PEM 头都嵌在代码字符串中而非独占一行,该判据下自然通过,无需路径白名单;真实 .pem 文件或粘进 yaml 的密钥块(头行独立)仍必中。
  2. DB-PASSWORD 限定配置类文件api 测试代码与 Readme 的 curl 示例大量使用 "password":"secret123" 假值,Java/Markdown 不在该规则文件范围内;配置类文件中现有口令全部为 ${PATBOND_DB_PASSWORD:…} 注入形态(docker-compose.yml、application.yml.sample 逐行核实),实值直写才会命中。

3. 误报实测:三仓现有全部已跟踪文件零误报

仓库 已跟踪文件数 --all 扫描结果 耗时
patbond-api 194+本次 3 零命中,exit 0 5.6s
patbond-flutter 234+本次 3 零命中,exit 0 6.7s
patbond-doc 74+本次 4 零命中,exit 0 2.1s

另以 --staged 模式对本次新增文件(脚本、hook、ci.yml、git-workflow.md)复扫,同样零命中——即规则集对自身与规范文档不误伤。

4. 拦截自测(临时仓构造假凭证,验证后已删除,未入库)

在 scratchpad 一次性 git 仓中构造全假样本(编造值,无任何真实凭证),结果:

  • 应拦 9 类全部命中AKIA 假 AK、AKID、LTAI、minio·admin(连写形态)、独立 PEM 头、accessKey/secretKey 实值赋值、yml 中 password 实值、.env 文件本体(NAME-DENY)——--staged--all、文件参数三种模式一致,exit 1。
  • hook 真实阻断git config core.hooksPath scripts/hooksgit commit 被 pre-commit 拒绝(exit 1),输出命中清单与处置指引(真凭证先轮换后清历史)。
  • 应放行全部通过${PATBOND_DB_PASSWORD:patbond} 注入、changeme/your-access-key 占位、.env.sample——零误拦,exit 0。
  • 顺带发现的既有防线:本机全局 gitignore 已含 .envgit add -A 根本加不进暂存区,NAME-DENY 是其后的第二道。

5. 三仓提交与 CI 状态

仓库 分支 提交 内容 CI
patbond-api dev 8330885 脚本 + hook + ci.yml 加 Secret scan step 见下
patbond-flutter dev 66f983d 同上(同构副本) 见下
patbond-doc main 8e1fe2f 脚本 + hook + ci.yml step + git-workflow.md「凭证防泄漏检查」节 见下

CI 状态(Gitea commit status API 逐仓核实,2026-09-08):三仓全部 success——api CI / backend-test (push)16:35:08 完成)、flutter CI / flutter-gates (push)16:37:29)、doc CI / docs-build (push)16:38:14)。新增 Secret scan step 未破坏任何既有流水线。

patbond-doc 本地 mkdocs build --strict 通过后才提交;他人未提交内容(backend-modules.md 改动、09/10/11 号报告)未混入本次提交。启用说明见 patbond-doc docs/development/git-workflow.md「凭证防泄漏检查(ADR-021)」节,命令示例已按参数化路径规范书写(cd <你的工作区>/<仓名>)。

6. 遗留与提醒

  • T3-03 解锁条件已满足后引入 MinIO 凭证时:AK/SK 只进被 gitignore 的 .envcompose ${} 注入),.sample 用占位值——直写实值会被本规则集拦下。
  • 两位开发者各自需在三仓执行一次 git config core.hooksPath scripts/hooks(CI 兜底不依赖此步,但本地拦截更早更省事)。
  • 规则表若增补(如 M4 引入新云厂商),三仓 scripts/check-secrets.sh 必须同步修改、同波提交。