应将 SAST 工具(如 gitleaks)嵌入 GitLab CI 的 test 阶段实现源头拦截,启用 --fail-on-secrets 和 allow_failure: false 确保含密提交失败即阻断,并配合 MR 强制策略与历史全量扫描消除存量风险。

直接在 GitLab CI 的提交阶段拦截硬编码密码,关键不是“等扫描完再处理”,而是让 SAST 工具在 代码刚进流水线时就触发、快速反馈、失败即阻断。这不是后期审计,而是源头过滤。
把 SAST 扫描塞进最前端的 test 阶段
GitLab 默认的 test 阶段就是 SAST 的合法入口,无需新建阶段。只要确保你的 .gitlab-ci.yml 中没有删掉或重命名 test,SAST job 就能自然挂载进去。它会在代码检出后立即运行,比构建、部署早得多。
- 不要把 SAST 放到
build或deploy阶段——那样已错过最佳拦截时机 - 如果自定义了 stages,必须显式保留
test,否则 SAST 不会启动 - 使用极狐 GitLab 旗舰版可启用高级 SAST,对跨文件密码引用(比如 config 文件里写 password=xxx,代码里读取它)也能识别,基础版仅支持单文件正则匹配
选对工具:用 gitleaks 做轻量密钥快扫
比起通用型 SAST 扫描器,gitleaks 是专为硬编码密钥设计的“短刀”:启动快、规则准、误报少,特别适合放在 CI 最前端做秒级初筛。
- 它不分析语法树,只扫描文本模式——比如匹配
AKIA[0-9A-Z]{16}或password\s*=\s*["'].*["'] - 支持
keywords + regex双校验机制:只有同时出现password=和匹配到 32 位随机字符串,才报为高置信度风险 - 可配置
path规则,跳过node_modules/、dist/、*.min.js等干扰路径,提速又降噪
失败即终止:让含密提交无法合入
默认情况下,SAST job 即使发现漏洞也只生成报告,不会中断流水线。要实现“秒级洗涤”,必须让检测失败变成 pipeline 失败。
- 在 gitleaks 的 CI 调用中加
--fail-on-secrets参数,一发现密钥就返回非零退出码 - 配合 GitLab 的
rules策略,在 MR 场景下限定只在merge_requests事件触发,并开启allow_failure: false - 在 MR 页面启用“合并前需通过所有流水线作业”,这样含密提交会卡在“待批准”状态,开发者必须修复后才能合入
配套动作:避免“绕过扫描”的惯性操作
工具再强,也挡不住人为绕过。真正守住源头,得从流程上堵住常见漏洞口。
- 禁用
git push --force到主干分支,防止跳过 CI 直接推敏感内容 - 在项目设置中开启
Require all discussions to be resolved,确保安全问题被讨论并关闭后才允许合并 - 对历史代码库运行一次
gitleaks detect --all-commits全量扫描,把存量密钥挖出来轮换掉,否则新流程只防不住“新增”


















