17 质量与安全门禁工具
质量门禁不是“把工具装进 CI”,而是把团队接受什么代码、发现什么风险、由谁处理、什么时候可以例外,变成可复现且可审计的工程规则。规则从开发者本机开始,串联 IDE、Git Hook、构建工具、CI 和共享扫描平台,同一输入在不同执行面必须得到可解释的一致结果。
工具负责发现与阻断,业务 owner 负责判断修复影响,安全团队负责风险处置策略,平台团队负责执行环境和凭证边界。误报、基线、升级、绕过、报告数据和责任人缺少任何一项,红灯都会逐渐退化成被习惯性跳过的噪声。
门禁分层
格式化解决风格差异,Lint 和静态分析发现代码缺陷,SAST 查找安全模式,SCA 对照依赖和镜像漏洞库,Secret 扫描寻找凭证痕迹,提交门禁负责尽早反馈。它们不能互相替代,也不能因为工具数量多就自动形成治理能力。
阅读顺序
| 文章 | 开发者先跑通 | 团队继续治理 |
|---|---|---|
| ESLint | JavaScript/TypeScript 规则与 flat config 可复现 | 类型信息、抑制、插件供应链和 IDE/CI 一致性 |
| Prettier | 确定性格式检查与幂等写入可复现 | parser、插件、ignore、批量迁移与格式回滚 |
| Stylelint | CSS 与扩展语法违规被拦截 | custom syntax、disable、插件和样式输入边界 |
| Checkstyle | Java 源码结构违规被构建拦截 | Token、规则文件、source set、抑制与升级差异 |
| SpotBugs | 编译后字节码缺陷被识别 | classpath、Bug Pattern、Filter、baseline 与分析错误 |
| PMD | 源码 AST 规则与 CPD 反例被拦截 | 类型解析、ruleset、缓存、抑制与规则迁移 |
| SonarQube | 服务、Scanner 和 Quality Gate 跑通 | 数据库、权限、Profile/Gate、分支和升级边界 |
| Semgrep | 源码正反 fixture 被规则稳定裁决 | 模式与数据流、规则测试、退出码、SARIF 和升级差异 |
| CodeQL | 目标模块进入 database 并被查询 | Extractor、构建覆盖、Query Pack、SARIF 和数据库资产 |
| Trivy | 文件系统、镜像和 SBOM 进入明确 scanner | 数据库、离线缓存、VEX、退出码与多目标覆盖 |
| Grype | 固定 SBOM 被可追溯数据库复扫 | 包目录、matcher、阈值、VEX 和跨流水线证据 |
| OWASP Dependency-Check | Java 依赖证据与 CPE 匹配可解释 | Analyzer、NVD、suppression、插件与数据同步 |
| Gitleaks | Git 与目录中的测试凭据按规则被拦截 | Fingerprint、baseline、历史覆盖和固定退出码 |
| TruffleHog | 无害自定义 Detector 在离线模式命中 | 多 Source、解码、结果状态和在线验证边界 |
| detect-secrets | baseline 之外的新增候选被 Hook 阻断 | 插件、过滤器、人工审计和渐进清零 |
| pre-commit | 跨语言 Hook 按固定 revision 运行 | 隔离环境、stages、缓存、供应链与 CI 复核 |
| Husky | Node 仓库把脚本接到原生 Git Hook | core.hooksPath、prepare、新 clone、GUI 与卸载 |
| lint-staged | 只对 index 中的匹配文件执行任务 | 部分暂存、并发写入、备份恢复与 Monorepo 配置 |
| commitlint | 最终提交消息按同一规则解析和裁决 | parser、共享配置、Hook、提交区间和合并策略 |
| Changesets | 包级变更意图形成可审查 release plan | Monorepo 传播、version、预发布、publish 与恢复 |
共通门禁合同
每条规则至少写清:规则 ID、目的、执行位置、失败证据、默认严重度、owner、修复方式、误报申诉、临时豁免期限和升级策略。没有这些信息的“红灯”只会积累绕过,没有长期约束力。
本机检查用于快速反馈,CI 是不可绕过的最终复核,IDE 只提供辅助提示。三处使用同一份版本锁定和配置源;任何仅存在于个人 IDE 的规则都不算团队门禁,任何只能在 CI 复现的失败也属于工程缺陷。
共通安全底线
- 扫描器使用只读、最小权限凭证;Fork PR、外部贡献和受信分支的 Secret 可见性必须区分。
- SARIF、源码片段、依赖清单、镜像层、Secret 命中和 SonarQube 报告本身都可能是敏感资产。
- 忽略、baseline、suppression、noqa 和 skip 都必须带原因、owner、到期时间和审计入口。
- 漏洞库或规则集不可用时要区分 fail-open 与 fail-closed;选择必须与环境风险匹配,不能静默跳过。
- 真 Secret 泄漏先撤销和轮换,再讨论删除历史;删除 Git 记录不能让已经暴露的凭证重新安全。
- 规则升级先在报告模式测量存量,再分批收紧新代码和全量代码,不能一次升级制造永久红灯。
