合并请求绿了,发版却被密钥或依赖漏洞拦下——多半是流水线里 Semgrep、Trivy、Gitleaks 各跑各的:三份日志、三种退出码、没有统一 Finding,误报也没法按同一指纹抑制。
结论: 把代码安全(SAST,静态应用安全测试)、密钥扫描、依赖/镜像漏洞(SCA,软件成分分析)收进同一检查任务,归一成同一套 Finding,再由策略给出
PASSED/FAILED/SKIPPED。社区版 GPL-3.0 可自由使用、修改和分发(以仓库 LICENSE 为准)。这套路径可替代「流水线里一串独立扫描脚本」;不能替代全站 DAST、主机入侵检测或资产盘点平台。
采购上「商业 SAST / GitLab Ultimate / Snyk 怎么选」见文末参考:选型对照。下面讲替换拼凑脚本 + Semgrep 迁出。
1. 你现在卡在哪
| 现象 | 常见原因 |
|---|---|
| PR 只拦了 SAST,主干才扫镜像 | 三条 Job 分期接入,没有统一门禁策略 |
| 同一问题在 Semgrep 日志和 Trivy 报告里各出现一次 | 没有跨引擎指纹与处置入口 |
| CI 退出码「1」分不清是超门禁还是引擎挂了 | 脚本把所有非零都当失败 |
| 换规则包要改三处 YAML | 规则版本没进同一任务模型 |
| Finding 全空却 PASSED | stub 引擎或漏洞库空(见翻车表) |
最短路径:装引擎 → doctor 非 stub → 小仓 sast+secret → 控制台能看到 Finding 与门禁 → 并行一周再删独立 Job。
2. 能力怎么对应(术语一次说清)
| 能力 | 白话 | 默认引擎 | 典型目标 |
|---|---|---|---|
sast |
静态看代码里的危险模式(注入、XSS、不安全反序列化等) | OpenGrep | 源码 / Git 仓库 |
secret |
找硬编码 AK/SK、Token、私钥、连接串 | Gitleaks | 源码 / Git(可加深历史) |
sca |
看依赖、制品、镜像里的已知 CVE 与许可证相关问题 | Trivy | 目录依赖、制品、镜像 |
质量类(异味、复杂度等)可另开,默认不计入安全门禁;具体引擎以控制台/手册为准,不要把 SonarQube Scanner 当成默认安全内核。
目标类型主路径:上传包、Git 仓库、制品 URL、容器镜像;CLI 还可扫本机目录。控制台不以扫服务器任意路径为主。
3. 从三条脚本到一个门禁
3.1 替换前(示意)
# 问题:三份日志、三种退出码语义、结果无法统一治理
semgrep:
script: [semgrep ci --config auto]
trivy-fs:
script: [trivy fs --exit-code 1 .]
gitleaks:
script: [gitleaks detect --source . --exit-code 1]
3.2 替换后:同一 Job
命令形态以当前发行包 angus-security --help 为准;下面是可复制示意:
export ANGUS_SECURITY_URL="https://security.example.com" # 以控制台接入为准
export ANGUS_SECURITY_TOKEN="***" # 只放 CI Secret,勿写入仓库
# 本机/CI 工作区(DIRECTORY);或改 GIT_REPO / ARTIFACT / IMAGE
angus-security scan run \
--target-type DIRECTORY \
--path . \
--capabilities sast,secret,sca \
--fail-on high
退出码(以当前 CLI 为准;与产品文档约定一致时):
| 码 | 含义 | CI 怎么处理 |
|---|---|---|
0 |
通过门禁 | 继续 |
1 |
扫描成功,但 Finding 超过策略 | 阻断合并/发布,去修或抑制 |
2 |
执行错误(引擎/网络等) | 告警平台,勿当业务漏洞 |
3 |
配置或鉴权错误 | 修 Token / 参数,勿当业务漏洞 |
门禁还有 SKIPPED(例如策略未覆盖该能力)——跳过 ≠ 通过。
3.3 GitLab 最小一步(平台细节内链)
# .gitlab-ci.yml(示意)
security-scan:
stage: security
script:
- angus-security tools doctor || true
- angus-security scan run --target-type GIT_REPO
--repo "$CI_REPOSITORY_URL"
--ref "$CI_COMMIT_SHA"
--capabilities sast,secret
--fail-on high
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
分层建议:PR 用 sast+secret + 较高阈值;夜间/发版再加 sca(制品或镜像)。GitHub Actions / Jenkins 差异与完整分层见文末参考:CI 集成清单。
4. 从 Semgrep 迁出:规则与门禁对照
OpenGrep 面向与 Semgrep 同类的规则匹配场景;迁出按「规则包 → 任务能力 → 门禁」三步,而不是逐条改写全部规则。
| Semgrep 侧习惯 | 迁到统一任务时怎么做 |
|---|---|
semgrep ci --config auto / 自建 ruleset |
任务勾选 sast;规则包版本绑在项目或任务上(以控制台为准) |
| PR 只扫变更文件 | 用较浅扫描级别(如 QUICK);完整库放夜间 |
--severity-threshold / 自写 exit |
改用平台 --fail-on / 策略阈值,统一 PASSED/FAILED |
| SARIF 上传 GitHub | 任务完成后从报告或 Finding 导出 SARIF(见文末参考:报告怎么出) |
| 密钥另跑 Gitleaks Job | 同一任务加 secret,不要再挂第二条脚本 |
4.1 并行迁出清单(建议一周)
- 新 Job 与旧 Semgrep Job 并行,先不删旧 stage。
- 同一小仓各跑一次:对比高危/阻断级数量级是否同量级(不要求条数逐条相等)。
- 打开
secret,确认密钥类不再依赖独立 Gitleaks Job。 - 抽 3~5 条高危:确认控制台有指纹,可走抑制(TTL 见存量抑制文)。
- 确认退出码 1/2/3 在 CI 通知里已分开(别再「非零=漏洞」)。
- 再删
semgrep/trivy-*/gitleaks独立 stage;发版门禁加上sca前先做金丝雀镜像或制品。
规则细节与语言覆盖以当前规则包为准,不要宣称「覆盖所有语言/框架」。若依赖仅存在于 Semgrep 生态的第三方规则包,先核验 OpenGrep 规则包是否覆盖,再迁。
5. 控制台怎么确认「收成一套了」
纯文字路径(无截图):
- 打开对应检查任务:状态已完成;能力列同时含你勾选的 sast/secret/sca。
- Finding 列表能按引擎/能力筛选,而不是去三份外部日志里翻。
- 任务摘要上的门禁结果为
PASSED/FAILED/SKIPPED之一,且与 CI 退出码语义一致(1=超门禁,不是 2/3)。 - 需要给领导/审计时,从报告出快照,不要截 Finding 首页——见文末参考:报告怎么出。
6. 翻车与边界
| 现象 | 常见原因 | 处理 |
|---|---|---|
| Finding 全空且门禁 PASSED | stub 引擎或库空 | doctor 确认 OpenGrep/Gitleaks/Trivy 非 stub;SCA 假绿查漏洞库(见文末参考:内网漏洞库 / doctor) |
| 仍出现三条 Job | 只加了新 Job、旧 Job 未删 | 并行验收后删独立 stage |
| 退出码 2 被当成漏洞 | 引擎未装 / Token 失效 | 区分门禁失败与执行失败 |
| 密钥刷屏 | 测试夹具、文档示例触发 | 抑制见文末参考:Finding 抑制 |
| 以为入库扫过就等于治理完成 | 把 Repo 轻量门禁当成 Security | Repo 执法、Security 做深度 Finding——见文末参考:Repo 联动 |
明确不做: 全站 DAST、RASP/主机入侵检测、Qualys 类资产盘点、扫描即过等保、AI 自动开修复 PR。
FAQ
这能完全替代 Semgrep OSS 吗?
在「CI 里跑规则匹配 + 统一门禁」主路径上,可以替代多脚本拼凑。第三方规则包缺口先核验再迁。
社区版够不够跑通?
社区版 GPL-3.0 可自由使用;install-engines + 第一次扫描即可验证替代路径。席位、配额、商业能力以控制台/当前文档为准,本文不列报价。
和「只把 Sonar 当安全扫描」有什么差别?
质量分析与安全模式匹配不是一回事。安全主路径是 OpenGrep / Gitleaks / Trivy;质量门禁另开,默认不计入安全门禁结论。
多脚本合成后,旧 SARIF 还要吗?
治理以平台 Finding 为准;需要给 IDE/工单时再导出 SARIF。见文末参考:报告怎么出。
和选型文什么关系?
本文回答「三条脚本怎么收成一门禁」。云端 SCA / 商业 SAST / GitLab 套件怎么挑见文末参考:选型对照。
小结
- 三条独立脚本 → 一个任务、一套 Finding、一门禁。
- 先
doctor,再sast+secret,并行一周再删旧 Job;发版再加sca。 - 退出码要分清「超门禁」和「没跑起来」。
- 不替代 DAST/主机安全;Repo 轻量门禁 ≠ Security 深度治理。
参考文章
- AngusSecurity 是什么:https://www.anguskit.com/zh/blog/what-is-angussecurity-capabilities-and-boundaries
- CLI 首次扫描:https://www.anguskit.com/zh/blog/angussecurity-cli-first-scan-guide
- 离线引擎与 doctor:https://www.anguskit.com/zh/blog/angussecurity-offline-engines-doctor-checklist
- CI 集成清单:https://www.anguskit.com/zh/blog/cicd-security-scanning-gitlab-github-jenkins
- Finding 抑制:https://www.anguskit.com/zh/blog/angussecurity-finding-suppress-disposition-guide
- 安全扫描报告怎么出:https://www.anguskit.com/zh/blog/security-scan-report-snapshot-export
- 内网漏洞库更新:https://www.anguskit.com/zh/blog/intranet-vuln-db-offline-update-rollback
- 商业 SAST / GitLab Ultimate / Snyk 怎么选:https://www.anguskit.com/zh/blog/private-appsec-vs-snyk-gitlab-commercial-sast
- AngusRepo 制品门禁联动:https://www.anguskit.com/zh/blog/angussecurity-angusrepo-artifact-gate-integration
- 文档中心:https://www.anguskit.com/zh/docs/security