fix(security): 凭证扫描补 AI 服务商密钥形态与 api_key 赋值(ADR-021)
CI / docs-build (push) Successful in 47s

M4 将引入 AI 服务商凭证,而现行规则表对其完全不覆盖。夹具实测:
5 种真实形态(ANTHROPIC_API_KEY=sk-ant-…、OPENAI_API_KEY=sk-proj-…、
openai_api_key: "sk-…"、api_key = "…"、api-token: "…")修复前全部
漏网退出 0,修复后全部拦下。

- 新增 AK-ANTHROPIC(sk-ant-)、AK-OPENAI(sk- / sk-proj- / sk-svcacct-)
- KEY-ASSIGN 扩至 api[-_]?(key|secret|token) 与 auth[-_]?token
  (原模式只认 access_key / secret_key 两族)
- ALLOW 补 x{3,}:使「讲解规则的文档」不被规则自身拦下
- git-workflow.md 覆盖面概述同步(细节仍以脚本规则表为唯一来源)

验证:占位夹具仍放行;三仓 --all 全绿零误报;三仓副本 md5 同构
640994c12bfa78b4512e872d709ed685;mkdocs --strict exit 0。

依据 iteration-4/08 §漏检清单(决策 G),须先于任何 AI key 落地。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-14 15:57:05 +08:00
parent 79b33dba31
commit 8f97e34900
2 changed files with 7 additions and 3 deletions
+6 -2
View File
@@ -15,7 +15,9 @@ set -u
mode="${1:---all}"
# 允许清单:行内出现任一形态即放行(${} 注入、占位值、明显示例值)
ALLOW='\$\{[^}]*\}|\{\{[^}]*\}\}|changeme|change[-_]me|your[-_][a-zA-Z0-9_-]+|<[a-zA-Z0-9 ,_.-]+>|placeholder|example|sample|dummy|fake|redacted|\*\*\*'
# 注:x{3,}xxx / xxxx…)是本项目文档描述凭证形态时的既有占位约定,
# 放行它使「讲解规则的文档」不会被规则自身拦下(如 iteration-4/08 §漏检清单)。
ALLOW='\$\{[^}]*\}|\{\{[^}]*\}\}|changeme|change[-_]me|your[-_][a-zA-Z0-9_-]+|<[a-zA-Z0-9 ,_.-]+>|placeholder|example|sample|dummy|fake|redacted|\*\*\*|x{3,}'
# 内容扫描跳过:本脚本与 hook 自身(含规则文本,非凭证)
SKIP_PATHS='(^|/)scripts/(check-secrets\.sh|hooks/pre-commit)$'
@@ -29,9 +31,11 @@ RULES=$(cat <<'EOF'
AK-AWS - - AKIA[0-9A-Z]{16}
AK-QCLOUD - - AKID[0-9A-Za-z]{16,}
AK-ALIYUN - - LTAI[0-9A-Za-z]{12,}
AK-ANTHROPIC - - sk-ant-[A-Za-z0-9_-]{16,}
AK-OPENAI - - sk-(proj-|svcacct-)?[A-Za-z0-9]{20,}
MINIO-DEFAULT i - minio[-_.]?admin
PRIVATE-KEY - - ^[[:space:]]*-----BEGIN [A-Z ]*PRIVATE KEY-----[[:space:]]*$
KEY-ASSIGN i - (access[-_]?key(_?id)?|secret[-_]?(access[-_]?)?key)["']?[[:space:]]*[:=][[:space:]]*["']?[A-Za-z0-9+/=_-]{8,}
KEY-ASSIGN i - (access[-_]?key(_?id)?|secret[-_]?(access[-_]?)?key|api[-_]?(key|secret|token)|auth[-_]?token)["']?[[:space:]]*[:=][[:space:]]*["']?[A-Za-z0-9+/=_-]{8,}
JWT-SECRET i - (jwt[-_.]?secret|signing[-_]?key|token[-_]?secret|hmac[-_]?(key|secret))["']?[[:space:]]*[:=][[:space:]]*["']?[A-Za-z0-9+/=_-]{8,}
DB-PASSWORD i \.(ya?ml|properties|toml|conf|ini)(\.sample|\.example)?$ (password|passwd|pwd)["']?[[:space:]]*[:=][[:space:]]*["']?[^[:space:]"'$]{6,}
EOF