Help us learn about your current experience with the documentation. Take the survey.

使用 SBOM 进行依赖扫描

  • Tier: Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
  • Status: Beta

使用 CycloneDX SBOM 进行依赖扫描会分析应用程序的依赖项,查找已知漏洞。所有依赖项都会被扫描,包括传递依赖项

依赖扫描通常被视为软件成分分析(SCA)的一部分。SCA 可能包含检查代码所用项目的方面。这些项目通常包括应用程序和系统依赖项,它们几乎总是从外部来源导入,而非来自您自己编写的项目。

依赖扫描可以在应用程序生命周期的开发阶段运行。每次流水线生成 SBOM 报告时,安全检测结果都会在源分支和目标分支之间进行识别和比较。检测到的漏洞及其严重程度会列在合并请求中,使您能够在代码变更提交之前主动解决应用程序风险。当发布新的安全公告时,报告的 SBOM 组件的安全检测结果也会被 持续漏洞扫描 识别,与 CI/CD 流水线无关。

GitLab 提供依赖扫描和 容器扫描,以确保覆盖所有这些依赖类型。为了尽可能覆盖您的风险区域,我们鼓励您使用所有安全扫描器。有关这些功能的比较,请参阅 依赖扫描与容器扫描对比

快速入门

通过以下选项之一启用使用 SBOM 的依赖扫描功能:

  • 使用最新的依赖扫描 CI/CD 模板 Dependency-Scanning.latest.gitlab-ci.yml 启用 GitLab 提供的分析器。
    • 默认使用(已弃用)的 Gemnasium 分析器。
    • 要启用新的依赖扫描分析器,请将 CI/CD 变量 DS_ENFORCE_NEW_ANALYZER 设置为 true
    • 存储库中必须存在 支持的锁文件、依赖关系图触发文件,才能在流水线中创建 dependency-scanning 作业。
  • 使用 扫描执行策略 和最新模板启用 GitLab 提供的分析器。
    • 默认使用(已弃用)的 Gemnasium 分析器。
    • 要启用新的依赖扫描分析器,请将 CI/CD 变量 DS_ENFORCE_NEW_ANALYZER 设置为 true
    • 存储库中必须存在 支持的锁文件、依赖关系图触发文件,才能在流水线中创建 dependency-scanning 作业。
  • 使用 依赖扫描 CI/CD 组件 启用新的依赖扫描分析器。
  • 将成功的流水线生成的 CycloneDX SBOM 文档作为 CI/CD 工件报告 提供。

您应该使用新的依赖扫描分析器。详情请参见 启用分析器。如果您使用(已弃用)的 Gemnasium 分析器,请参考 传统依赖扫描功能 的启用说明。

启用分析器

依赖扫描分析器生成与 GitLab 兼容的 CycloneDX SBOM 报告。如果您的应用程序无法生成此类报告,可以使用 GitLab 分析器生成。

请在此 反馈问题 中分享您对新依赖扫描分析器的任何反馈。

先决条件:

  • 存储库中必须存在 支持的锁文件或依赖关系图,或者必须将其作为工件传递给 dependency-scanning 作业。
  • .gitlab-ci.yml 文件中需要包含该组件的 stage
  • 对于自托管运行器,您需要一个具有 dockerkubernetes 执行程序的 GitLab Runner。
    • 如果您在 GitLab.com 上使用 SaaS 运行器,此功能默认启用。

要启用分析器,您必须:

  • 使用最新的依赖扫描 CI/CD 模板 Dependency-Scanning.latest.gitlab-ci.yml,并通过将 CI/CD 变量 DS_ENFORCE_NEW_ANALYZER 设置为 true 来强制使用新的依赖扫描分析器。

    include:
      - template: Jobs/Dependency-Scanning.latest.gitlab-ci.yml
    
    variables:
      DS_ENFORCE_NEW_ANALYZER: 'true'
  • 使用 扫描执行策略 和最新模板,并通过将 CI/CD 变量 DS_ENFORCE_NEW_ANALYZER 设置为 true 来强制使用新的依赖扫描分析器。

  • 使用 依赖扫描 CI/CD 组件

    include:
      - component: $CI_SERVER_FQDN/components/dependency-scanning/main@0

触发文件

当使用 最新的依赖扫描 CI 模板 时,触发文件会创建 dependency-scanning CI/CD 作业。分析器不会扫描这些文件。 如果您使用触发文件来 构建 支持的锁文件,您的项目将得到支持。

语言 文件
C#/Visual Basic *.csproj, *.vbproj
Java pom.xml
Java/Kotlin build.gradle, build.gradle.kts
Python requirements.pip, Pipfile, requires.txt, setup.py
Scala build.sbt

语言特定说明

如果您的项目没有将支持的锁文件依赖关系图提交到存储库,您需要提供一个。

以下示例展示了如何为流行语言和包管理器创建 GitLab 分析器支持的文件。

Go

如果您的项目仅提供 go.mod 文件,依赖扫描分析器仍可以提取组件列表。但是,依赖路径 信息不可用。此外,如果同一模块有多个版本,您可能会遇到误报。

为了获得改进的组件检测和功能覆盖,您应提供使用 Go 工具链中的 go mod graph 命令 生成的 go.graph 文件。

以下示例 .gitlab-ci.yml 演示如何在 Go 项目上启用具有 依赖路径 支持的 CI/CD 组件。依赖关系图作为 build 阶段的作业工件输出,在依赖扫描运行之前。

stages:
  - build
  - test

include:
  - component: $CI_SERVER_FQDN/components/dependency-scanning/main@0

go:build:
  stage: build
  image: "golang:latest"
  script:
    - "go mod tidy"
    - "go build ./..."
    - "go mod graph > go.graph"
  artifacts:
    when: on_success
    access: developer
    paths: ["**/go.graph"]
Gradle

对于 Gradle 项目,请使用以下任一方法创建依赖关系图。

  • Nebula Gradle Dependency Lock Plugin
  • Gradle 的 HtmlDependencyReportTask
依赖锁定插件

此方法提供有关直接依赖项的信息。

要在 Gradle 项目上启用 CI/CD 组件:

  1. 编辑 build.gradlebuild.gradle.kts 以使用 gradle-dependency-lock-plugin 或使用初始化脚本。
  2. 配置 .gitlab-ci.yml 文件以生成 dependencies.lockdependencies.direct.lock 工件,并将它们传递给 dependency-scanning 作业。

以下示例演示如何为 Gradle 项目配置组件。

stages:
  - build
  - test

image: gradle:8.0-jdk11

include:
  - component: $CI_SERVER_FQDN/components/dependency-scanning/main@0

generate nebula lockfile:
  # 在 build 阶段运行可确保 dependency-scanning 作业接收可扫描的工件。
  stage: build
  script:
    - |
      cat << EOF > nebula.gradle
      initscript {
          repositories {
            mavenCentral()
          }
          dependencies {
              classpath 'com.netflix.nebula:gradle-dependency-lock-plugin:12.7.1'
          }
      }

      allprojects {
          apply plugin: nebula.plugin.dependencylock.DependencyLockPlugin
      }
      EOF
      ./gradlew --init-script nebula.gradle -PdependencyLock.includeTransitives=true -PdependencyLock.lockFile=dependencies.lock generateLock saveLock
      ./gradlew --init-script nebula.gradle -PdependencyLock.includeTransitives=false -PdependencyLock.lockFile=dependencies.direct.lock generateLock saveLock
      # generateLock 将锁文件保存在项目的 build/ 目录中
      # saveLock 将其复制到项目根目录。为了避免重复
      # 并准确获取依赖项的位置,使用 find 删除
      # build/ 目录中的锁文件。
  after_script:
    - find . -path '*/build/dependencies*.lock' -print -delete
  # 收集所有生成的工件并将它们传递给顺序阶段中的作业。
  artifacts:
    paths:
      - '**/dependencies*.lock'
      - '**/dependencies*.lock'
HtmlDependencyReportTask

此方法提供有关传递依赖项和直接依赖项的信息。

HtmlDependencyReportTask 是获取 Gradle 项目依赖项列表的替代方法(已在 gradle 版本 4 到 8 中测试)。要在依赖扫描中使用此方法,需要提供运行 gradle htmlDependencyReport 任务生成的工件。

stages:
  - build
  - test

# 定义包含 Java 和 Gradle 的镜像
image: gradle:8.0-jdk11

include:
  - component: $CI_SERVER_FQDN/components/dependency-scanning/main@0

build:
  stage: build
  script:
    - gradle --init-script report.gradle htmlDependencyReport
  # gradle 任务将依赖项报告写入 build/reports/project/dependencies 下的 javascript 文件。
  # 由于文件名非标准化,after_script 会查找并重命名该文件为
  # `gradle-html-dependency-report.js`,将其复制到与 `build.gradle` 相同的目录中。
  after_script:
    - |
      reports_dir=build/reports/project/dependencies
      while IFS= read -r -d '' src; do
        dest="${src%%/$reports_dir/*}/gradle-html-dependency-report.js"
        cp $src $dest
      done < <(find . -type f -path "*/${reports_dir}/*.js" -not -path "*/${reports_dir}/js/*" -print0)
  # 将 html 报告工件传递给后续的依赖扫描阶段。
  artifacts:
    paths:
      - "**/gradle-html-dependency-report.js"

上面的命令使用 report.gradle 文件,可以通过 --init-script 提供,或者其内容可以直接添加到 build.gradle 中:

allprojects {
    apply plugin: 'project-report'
}

依赖项报告可能指示某些配置的依赖项解析 FAILED。在这种情况下,依赖扫描会记录警告但不会使作业失败。如果您希望在报告解析失败时使流水线失败,请将以下额外步骤添加到上面的 build 示例中。

while IFS= read -r -d '' file; do
  grep --quiet -E '"resolvable":\s*"FAILED' $file && echo "Dependency report has dependencies with FAILED resolution status" && exit 1
done < <(find . -type f -path "*/gradle-html-dependency-report.js -print0)
Maven

以下示例 .gitlab-ci.yml 演示如何在 Maven 项目上启用 CI/CD 组件。依赖关系图作为 build 阶段的作业工件输出,在依赖扫描运行之前。

要求:使用至少版本 3.7.0 的 maven-dependency-plugin。

stages:
  - build
  - test

image: maven:3.9.9-eclipse-temurin-21

include:
  - component: $CI_SERVER_FQDN/components/dependency-scanning/main@0

build:
  # 在 build 阶段运行可确保 dependency-scanning 作业接收 maven.graph.json 工件。
  stage: build
  script:
    - mvn install
    - mvn org.apache.maven.plugins:maven-dependency-plugin:3.8.1:tree -DoutputType=json -DoutputFile=maven.graph.json
  # 收集所有 maven.graph.json 工件并将它们传递给
  # 顺序阶段中的作业。
  artifacts:
    paths:
      - "**/*.jar"
      - "**/maven.graph.json"
pip

如果您的项目提供由 pip-compile 命令行工具 生成的 requirements.txt 锁文件,依赖扫描分析器可以提取组件列表和依赖关系图信息,从而支持 依赖路径 功能。

或者,您的项目可以提供由 pipdeptree --json 命令行工具 生成的 pipdeptree.json 依赖关系图导出。

以下示例 .gitlab-ci.yml 演示如何在 pip 项目上启用具有 依赖路径 支持的 CI/CD 组件。build 阶段在依赖扫描运行之前将依赖关系图输出为作业工件。

stages:
  - build
  - test

include:
  - component: $CI_SERVER_FQDN/components/dependency-scanning/main@0

build:
  stage: build
  image: "python:latest"
  script:
    - "pip install -r requirements.txt"
    - "pip install pipdeptree"
    - "pipdeptree --json > pipdeptree.json"
  artifacts:
    when: on_success
    access: developer
    paths: ["**/pipdeptree.json"]

由于 已知问题pipdeptree 不会将 可选依赖项 标记为父包的依赖项。因此,依赖扫描将它们标记为项目的直接依赖项,而不是传递依赖项。

Pipenv

如果您的项目仅提供 Pipfile.lock 文件,依赖扫描分析器仍可以提取组件列表。但是,依赖路径 信息不可用。

为了获得改进的功能覆盖,您应提供由 pipenv graph 命令 生成的 pipenv.graph.json 文件。

以下示例 .gitlab-ci.yml 演示如何在 Pipenv 项目上启用具有 依赖路径 支持的 CI/CD 组件。build 阶段在依赖扫描运行之前将依赖关系图输出为作业工件。

stages:
  - build
  - test

include:
  - component: $CI_SERVER_FQDN/components/dependency-scanning/main@0

build:
  stage: build
  image: "python:3.12"
  script:
    - "pip install pipenv"
    - "pipenv install"
    - "pipenv graph --json-tree > pipenv.graph.json"
  artifacts:
    when: on_success
    access: developer
    paths: ["**/pipenv.graph.json"]
sbt

要在 sbt 项目上启用 CI/CD 组件:

以下示例 .gitlab-ci.yml 演示如何在 sbt 项目上启用具有 依赖路径 支持的 CI/CD 组件。build 阶段在依赖扫描运行之前将依赖关系图输出为作业工件。

stages:
  - build
  - test

include:
  - component: $CI_SERVER_FQDN/components/dependency-scanning/main@0

build:
  stage: build
  image: "sbtscala/scala-sbt:eclipse-temurin-17.0.13_11_1.10.7_3.6.3"
  script:
    - "sbt dependencyDot"
  artifacts:
    when: on_success
    access: developer
    paths: ["**/dependencies-compile.dot"]

理解结果

依赖扫描分析器为每个检测到的支持的锁文件或依赖关系图导出生成 CycloneDX 软件物料清单(SBOM)。

CycloneDX 软件物料清单

依赖扫描分析器为它检测到的每个支持的锁文件或依赖关系图导出输出一个 CycloneDX 软件物料清单(SBOM)。CycloneDX SBOM 作为作业工件创建。

CycloneDX SBOM:

  • 命名为 gl-sbom-<package-type>-<package-manager>.cdx.json
  • 可作为依赖扫描作业的作业工件获取。
  • 作为 cyclonedx 报告上传。
  • 保存在与检测到的锁文件或依赖关系图导出文件相同的目录中。

例如,如果您的项目具有以下结构:

.
├── ruby-project/
│   └── Gemfile.lock
├── ruby-project-2/
│   └── Gemfile.lock
└── php-project/
    └── composer.lock

以下 CycloneDX SBOM 将作为作业工件创建:

.
├── ruby-project/
│   ├── Gemfile.lock
│   └── gl-sbom-gem-bundler.cdx.json
├── ruby-project-2/
│   ├── Gemfile.lock
│   └── gl-sbom-gem-bundler.cdx.json
└── php-project/
    ├── composer.lock
    └── gl-sbom-packagist-composer.cdx.json

合并多个 CycloneDX SBOM

您可以使用 CI/CD 作业将多个 CycloneDX SBOM 合并为单个 SBOM。

GitLab 使用 CycloneDX Properties 在每个 CycloneDX SBOM 的元数据中存储实现特定的详细信息,例如依赖关系图导出和锁文件的位置。如果将多个 CycloneDX SBOM 合并在一起,此信息将从合并后的文件中移除。

例如,以下 .gitlab-ci.yml 摘录演示了如何合并 Cyclone SBOM 文件并验证生成的文件。

stages:
  - test
  - merge-cyclonedx-sboms

include:
  - component: $CI_SERVER_FQDN/components/dependency-scanning/main@0

merge cyclonedx sboms:
  stage: merge-cyclonedx-sboms
  image:
    name: cyclonedx/cyclonedx-cli:0.27.1
    entrypoint: [""]
  script:
    - find . -name "gl-sbom-*.cdx.json" -exec cyclonedx merge --output-file gl-sbom-all.cdx.json --input-files "{}" +
    # 可选:验证合并的 sbom
    - cyclonedx validate --input-version v1_6 --input-file gl-sbom-all.cdx.json
  artifacts:
    paths:
      - gl-sbom-all.cdx.json

优化

要根据您的需求优化使用 SBOM 的依赖扫描,您可以:

  • 从扫描中排除文件和目录。
  • 定义查找文件的最大深度。

从扫描中排除文件和目录

要从扫描中排除文件或目录,请在 .gitlab-ci.yml 中使用 DS_EXCLUDED_PATHS 并包含逗号分隔的模式列表。这将阻止指定的文件和目录成为扫描目标。

定义查找文件的最大深度

要优化分析器行为,您可以通过 DS_MAX_DEPTH 环境变量设置最大深度值。值为 -1 表示扫描所有目录,无论深度如何。默认值为 2

推广

在您对单个项目的使用 SBOM 的依赖扫描结果有信心后,您可以将其扩展到其他项目:

  • 使用 强制扫描执行 在组范围内应用使用 SBOM 的依赖扫描设置。
  • 如果您有独特的要求,使用 SBOM 的依赖扫描可以在 离线环境 中运行。

支持的包类型

为了使安全分析有效,SBOM 报告中列出的组件必须在 GitLab Advisory Database 中有对应的条目。

GitLab SBOM 漏洞扫描器可以报告具有以下 PURL 类型 的组件的依赖扫描漏洞:

  • cargo
  • composer
  • conan
  • gem
  • golang
  • maven
  • npm
  • nuget
  • pypi

自定义分析器行为

如何自定义分析器取决于启用解决方案。

在将这些更改合并到默认分支之前,请在合并请求中测试 GitLab 分析器的所有自定义。否则可能会导致意外结果,包括大量误报。

使用 CI/CD 模板自定义行为

当使用最新的依赖扫描 CI/CD 模板 Dependency-Scanning.latest.gitlab-ci.yml扫描执行策略 时,请使用 CI/CD 变量

可用的 CI/CD 变量

以下变量允许配置全局依赖扫描设置。

CI/CD 变量 描述
DS_EXCLUDED_ANALYZERS 指定要从依赖扫描中排除的分析器(按名称)。
DS_EXCLUDED_PATHS 根据路径从扫描中排除文件和目录。逗号分隔的模式列表。模式可以是 glob(请参阅 doublestar.Match 了解支持的模式),或文件或文件夹路径(例如 doc,spec)。父目录也匹配模式。这是在扫描执行之前应用的预过滤器。默认值:"spec, test, tests, tmp"
DS_MAX_DEPTH 定义分析器应搜索支持文件进行扫描的目录级别深度。值为 -1 表示扫描所有目录,无论深度如何。默认值:2
DS_INCLUDE_DEV_DEPENDENCIES 设置为 "false" 时,不报告开发依赖项。仅支持使用 Composer、Conda、Gradle、Maven、npm、pnpm、Pipenv、Poetry 或 uv 的项目。默认值:"true"
DS_PIPCOMPILE_REQUIREMENTS_FILE_NAME_PATTERN 定义使用 glob 模式匹配处理哪些需求文件(例如 requirements*.txt*-requirements.txt)。模式应仅匹配文件名,而非目录路径。语法详情请参阅 glob 模式文档
SECURE_ANALYZERS_PREFIX 覆盖提供官方默认镜像(代理)的 Docker 注册表的名称。
DS_FF_LINK_COMPONENTS_TO_GIT_FILES 将依赖列表中的组件链接到提交到存储库的文件,而不是在 CI/CD 流水线中动态生成的锁文件和图文件。这确保所有组件都链接到存储库中的源文件。默认值:"false"
覆盖依赖扫描作业

要覆盖作业定义,请声明一个与要覆盖的作业同名的新作业。将此新作业放在模板包含之后,并在其下指定任何额外的键。例如,这为 dependency-scanning 作业配置了 dependencies: [] 属性:

include:
  - template: Jobs/Dependency-Scanning.gitlab-ci.yml

dependency-scanning:
  dependencies: ["build"]

使用 CI/CD 组件自定义行为

当使用依赖扫描 CI/CD 组件时,可以通过配置 inputs 来自定义分析器。

它如何扫描应用程序

使用 SBOM 进行依赖扫描的方法依赖于两个不同的阶段:

  • 首先,依赖检测阶段专注于创建项目中依赖项及其关系(依赖关系图)的完整清单。此清单捕获在 SBOM(软件物料清单)文档中。
  • 其次,在 CI/CD 流水线完成后,GitLab 平台处理您的 SBOM 报告,并使用内置的 GitLab SBOM 漏洞扫描器执行彻底的安全分析。这是与 持续漏洞扫描 相同的扫描器。

这种关注点分离和此架构的模块化允许通过扩展语言支持、在 GitLab 平台内实现更紧密的集成和体验,以及转向行业标准报告类型,更好地支持客户。

依赖检测

使用 SBOM 进行依赖扫描需要将检测到的依赖项捕获在 CycloneDX SBOM 文档中。但是,此功能的模块化方面允许您选择如何生成此文档:

  • 使用 GitLab 提供的依赖扫描分析器(推荐)
  • 使用 GitLab 提供的(已弃用)Gemnasium 分析器
  • 使用自定义作业和第三方 CycloneDX SBOM 生成器或自定义工具。

要激活使用 SBOM 的依赖扫描,提供的 CycloneDX SBOM 文档必须:

当使用 GitLab 提供的分析器时,这些要求会得到满足。

安全分析

上传兼容的 CycloneDX SBOM 文档后,GitLab 会自动使用 GitLab SBOM 漏洞扫描器执行安全分析。每个组件都会根据 GitLab Advisory Database 进行检查,并按以下方式处理扫描结果:

如果 SBOM 报告由默认分支上的 CI/CD 作业声明:将创建漏洞,并可以在 漏洞报告 中查看。

如果 SBOM 报告由非默认分支上的 CI/CD 作业声明:将创建安全检测结果,并可以在 流水线视图的安全选项卡 和 MR 安全小部件中查看。此功能位于功能标志后面,并在 Epic 14636 中跟踪。

离线支持

  • Tier: Ultimate
  • Offering: GitLab Self-Managed

对于在通过互联网访问外部资源方面受到限制、限制或间歇性访问的环境中的实例,您需要进行一些调整才能成功运行依赖扫描作业。有关更多信息,请参阅 离线环境

要求

要在离线环境中运行依赖扫描,您必须拥有:

  • 一个具有 dockerkubernetes 执行程序的 GitLab Runner。
  • 依赖扫描分析器镜像的本地副本。
  • 访问 包元数据库。这是获取依赖项许可证和公告数据所必需的。

分析器镜像的本地副本

要使用依赖扫描分析器:

  1. 将以下默认依赖扫描分析器镜像从 registry.gitlab.com 导入到您的 本地 Docker 容器注册表 中:

    registry.gitlab.com/security-products/dependency-scanning:v0

    将 Docker 镜像导入本地离线 Docker 注册表的过程取决于 您的网络安全策略。请咨询您的 IT 人员,以找到可接受且已批准的流程,用于导入或临时访问外部资源。这些扫描器会 定期更新 新定义,您可能需要定期下载它们。如果您的离线实例可以访问 GitLab 注册表,您可以使用 Security-Binaries 模板 下载最新的依赖扫描分析器镜像。

  2. 配置 GitLab CI/CD 以使用本地分析器。

    将 CI/CD 变量 SECURE_ANALYZERS_PREFIX 的值设置为您本地的 Docker 注册表 - 在此示例中为 docker-registry.example.com

    include:
      - template: Jobs/Dependency-Scanning.latest.gitlab-ci.yml
    
    variables:
      SECURE_ANALYZERS_PREFIX: "docker-registry.example.com/analyzers"

安全策略

使用安全策略在多个项目中强制执行依赖扫描。适当的策略类型取决于您的项目是否将可扫描的工件提交到其存储库中。

扫描执行策略

扫描执行策略 支持所有将可扫描工件提交到其存储库中的项目。这些工件包括锁文件、依赖关系图文件以及其他可以直接分析以识别依赖项的文件。

对于具有这些工件的项目,扫描执行策略提供了强制执行依赖扫描最快、最直接的方法。

流水线执行策略

对于没有将可扫描工件提交到其存储库中的项目,您必须使用 流水线执行策略。这些策略使用自定义 CI/CD 作业在调用依赖扫描之前生成可扫描的工件。

流水线执行策略:

  • 作为您 CI/CD 流水线的一部分生成锁文件或依赖关系图。
  • 根据您的特定项目需求自定义依赖检测过程。
  • 为 Gradle 和 Maven 等构建工具实现语言特定说明。

示例:Gradle 项目的流水线执行策略

对于没有将可扫描工件提交到存储库中的 Gradle 项目,需要使用包含工件生成步骤的流水线执行策略。此示例使用 nebula 插件。

在专用的安全策略项目中创建或更新主策略文件(例如 policy.yml):

pipeline_execution_policy:
- name: Enforce Gradle dependency scanning with SBOM
  description: Generate dependency artifact and run Dependency Scanning.
  enabled: true
  pipeline_config_strategy: inject_policy
  content:
    include:
      - project: $SECURITY_POLICIES_PROJECT
        file: "dependency-scanning.yml"

添加 dependency-scanning.yml

stages:
  - build
  - test

variables:
  DS_ENFORCE_NEW_ANALYZER: "true"

include:
  - template: Jobs/Dependency-Scanning.latest.gitlab-ci.yml

generate nebula lockfile:
  image: openjdk:11-jdk
  stage: build
  script:
    - |
      cat << EOF > nebula.gradle
      initscript {
          repositories {
            mavenCentral()
          }
          dependencies {
              classpath 'com.netflix.nebula:gradle-dependency-lock-plugin:12.7.1'
          }
      }

      allprojects {
          apply plugin: nebula.plugin.dependencylock.DependencyLockPlugin
      }
      EOF
      ./gradlew --init-script nebula.gradle -PdependencyLock.includeTransitives=true -PdependencyLock.lockFile=dependencies.lock generateLock saveLock
      ./gradlew --init-script nebula.gradle -PdependencyLock.includeTransitives=false -PdependencyLock.lockFile=dependencies.direct.lock generateLock saveLock
  after_script:
    - find . -path '*/build/dependencies.lock' -print -delete
  artifacts:
    paths:
      - '**/dependencies.lock'
      - '**/dependencies.direct.lock'

这种方法确保:

  1. 在 Gradle 项目中运行的流水线生成可扫描的工件。
  2. 依赖扫描被强制执行并可以访问可扫描的工件。
  3. 策略范围内的所有项目一致地遵循相同的依赖扫描方法。
  4. 配置更改可以集中管理并应用于多个项目。

有关为不同构建工具实现流水线执行策略的更多详细信息,请参阅 语言特定说明

故障排除

在使用依赖扫描时,您可能会遇到以下问题。

警告:grep: command not found

分析器镜像包含最少的依赖项,以减少镜像的攻击面。因此,通常在其他镜像中找到的实用程序(如 grep)在镜像中缺失。这可能会导致作业日志中出现类似 /usr/bin/bash: line 3: grep: command not found 的警告。此警告不会影响分析器的结果,可以忽略。