极狐 GitLab

CycloneDX 文件的许可证扫描

Tier: 旗舰版

Offering: JihuLab.com,私有化部署

为了检测正在使用的许可证,许可证合规依赖于运行依赖扫描作业,并分析这些作业生成的 CycloneDX 软件物料清单(SBOM)。此扫描方法能够解析并识别 SPDX 列表中定义的 600 多种不同类型的许可证。第三方扫描器可用于生成依赖项列表,只要它们为受支持的语言生成 CycloneDX 报告产物,并遵循极狐GitLab CycloneDX 属性分类法即可。提供其他许可证的能力在史诗 10861中跟踪。

许可证扫描功能依赖于在外部数据库中收集的公开可用的软件包元数据, 并与极狐GitLab 实例自动同步。 扫描完全在极狐GitLab 实例内执行。 不会向外部服务发送任何上下文信息(例如项目依赖项列表)。

配置#

要启用 CycloneDX 文件的许可证扫描:

  • 使用依赖扫描模板
    • 开启依赖扫描 并确保满足其先决条件。
    • 在极狐GitLab 私有化部署上,您可以在极狐GitLab 实例的管理区域中选择要同步的软件包仓库元数据。要使此数据同步正常工作,您必须允许从极狐GitLab 实例到域 storage.googleapis.com 和 pmdb-dist-svc.runway.gitlab.net的出站网络流量。如果您的网络连接有限或没有网络连接,请参阅文档章节在离线环境中运行以获取更多指导。
  • 或者对适用的软件包仓库使用 CI/CD 组件。

支持的语言和软件包管理器#

许可证扫描支持以下语言和软件包管理器:

语言软件包管理器依赖扫描模板CI/CD 组件
.NETNuGet是否
C#是否
CConan是否
C++是否
Dartpub是否
Go1Go是否
JavaGradle是否
Maven是否
Android是是
JavaScript 和 TypeScriptnpm是否
pnpm是否
yarn是否
PHPComposer是否
Pythonsetuptools是否
pip是否
Pipenv是否
Poetry是否
RubyBundler是否
Rustcargo否是
Scalasbt是否
Swiftsbt是否

脚注:

  1. 不支持 Go 标准库(如 stdlib),它们会显示为 unknown 许可证。对这些库的支持在议题 480305中跟踪。

支持的文件和版本即依赖扫描所支持的文件和版本。

数据源#

受支持的软件包的许可证信息从以下来源获取。极狐GitLab 会对原始数据进行额外处理,包括将各种变体映射到规范的许可证名称。

许可证表达式#

极狐GitLab 从 CycloneDX SBOM 中的 expression 字段读取 SPDX 许可证表达式,包括用于自定义非 SPDX 许可证的 LicenseRef-[NAME] 语法。当组件的 SBOM 条目包含 expression 时,极狐GitLab 会存储并评估完整表达式。当 CycloneDX SBOM 不包含许可证信息时,极狐GitLab 会将组件与 PMDB 许可证数据进行匹配,该数据支持许可证表达式。

许可证审批策略中支持许可证表达式。当策略针对的许可证作为组件表达式中的某一项出现时,该策略会针对完整表达式正确评估。

基于检测到的许可证阻止合并请求#

用户可以通过配置许可证审批策略,根据检测到的许可证要求合并请求必须获得审批。

在离线环境中运行#

Tier: 旗舰版

Offering: 私有化部署

对于通过互联网对外部资源访问受限、受约束或时断时续的环境中的实例,需要进行一些调整,才能成功扫描 CycloneDX 报告中的许可证。更多信息,请参见离线实例的软件包元数据数据库。

使用 CycloneDX 报告作为许可证信息来源#

许可证扫描在可用时会使用 CycloneDX JSON SBOM 的 licenses 字段。如果许可证信息不可用,则使用从外部许可证数据库导入的许可证信息。许可证信息可以使用有效的 SPDX 标识符、许可证名称或 SPDX 许可证表达式提供。有关许可证字段格式的更多信息,请参阅 CycloneDX 规范。

提供 licenses 字段的兼容 CycloneDX SBOM 生成器可在 CycloneDX 工具中心找到。

配置许可证信息来源#

当两种来源都可用时,选择要使用的许可证信息来源。

要为项目配置首选的许可证信息来源:

  1. 在顶部栏中,选择搜索或跳转到并找到您的项目。
  2. 在左侧边栏中,选择安全 > 安全配置。
  3. 在许可证信息来源部分,选择以下任一项:
    • SBOM(默认)- 使用 CycloneDX 报告中的许可证信息。
      • 扫描器从项目中的 /gl-sbom-*.cdx.json 报告读取许可证信息。
      • 要覆盖某个许可证,请直接在此文件中更新许可证数据。
    • PMDB - 使用外部许可证数据库中的许可证信息。

启用或禁用 CycloneDX 文件的许可证扫描#

许可证扫描默认对所有已摄取的 CycloneDX SBOM 文件运行。您可以在安全配置页面按项目禁用许可证扫描。禁用后,来自 SBOM 摄取的许可证会在依赖项列表中显示为 unknown。

先决条件:

  • 您必须具有项目的维护者、所有者或安全管理员角色。

要启用或禁用 CycloneDX 文件的许可证扫描:

  1. 在顶部栏中,选择搜索或跳转到并找到您的项目。
  2. 在左侧边栏中,选择安全 > 安全配置。
  3. 在 CycloneDX 的许可证扫描部分,打开或关闭开关。

故障排除#

CycloneDX 文件未被扫描,且似乎没有提供任何结果#

确保 CycloneDX 文件遵循 CycloneDX JSON 规范。该规范不允许重复条目。包含多个 SBOM 文件的项目应将每个 SBOM 文件作为单独的 CI 报告产物上报,或者如果这些 SBOM 作为 CI 流水线的一部分被合并,则应确保移除重复项。

您可以按如下方式根据 CycloneDX JSON specification 验证 CycloneDX SBOM 文件:

shell
$ docker run -it --rm -v "$PWD:/my-cyclonedx-sboms" -w /my-cyclonedx-sboms cyclonedx/cyclonedx-cli:latest cyclonedx validate --input-version v1_4 --input-file gl-sbom-all.cdx.json Validating JSON BOM... BOM validated successfully.

如果 JSON BOM 验证失败,例如因为存在重复组件:

shell
Validation failed: Found duplicates at the following index pairs: "(A, B), (C, D)" #/properties/components/uniqueItems

此问题可以通过更新 CI 模板来修复,即使用 jq 从 gl-sbom-*.cdx.json 报告中移除重复组件,方法是覆盖产生重复组件的作业定义。例如,以下内容会从 gemnasium-dependency_scanning 作业生成的 gl-sbom-gem-bundler.cdx.json 报告文件中移除重复组件:

yaml
1include: 2 - template: Jobs/Dependency-Scanning.gitlab-ci.yml 3 4gemnasium-dependency_scanning: 5 after_script: 6 - apk update && apk add jq 7 - jq '.components |= unique' gl-sbom-gem-bundler.cdx.json > tmp.json && mv tmp.json gl-sbom-gem-bundler.cdx.json

移除未使用的许可证数据#

许可证扫描的变更(在极狐GitLab 15.9 中发布)要求实例上提供大量额外的磁盘空间。此问题已在极狐GitLab 16.3 中通过减少软件包元数据表的磁盘占用史诗解决。但如果您的实例在极狐GitLab 15.9 到 16.3 之间运行过许可证扫描,您可能需要移除不需要的数据。

要移除不需要的数据:

  1. 检查 package_metadata_synchronization 功能标志当前是否已启用,或之前是否曾启用,如果已启用,请将其禁用。使用 Rails 控制台执行以下命令。

    ruby
    Feature.enabled?(:package_metadata_synchronization) && Feature.disable(:package_metadata_synchronization)
  2. 检查数据库中是否存在已弃用的数据:

    ruby
    PackageMetadata::PackageVersionLicense.count PackageMetadata::PackageVersion.count
  3. 如果数据库中确实存在已弃用的数据,请按顺序运行以下命令将其移除:

    ruby
    ActiveRecord::Base.connection.execute('SET statement_timeout TO 0') PackageMetadata::PackageVersionLicense.delete_all PackageMetadata::PackageVersion.delete_all

漏洞扫描对某个 CycloneDX SBOM 没有产生任何结果#

如果您的 CycloneDX 文件已进行许可证扫描,但漏洞扫描没有产生任何结果,请参阅漏洞扫描对自定义或合并的 CycloneDX SBOM 没有产生任何结果。

依赖项许可证未知#

开源许可证信息存储在数据库中,用于解析项目依赖项的许可证。如果许可证信息不存在,或者该数据在数据库中尚不可用,则依赖项的许可证可能会显示为 unknown。

依赖项许可证的查找在流水线完成时进行,因此如果当时该数据不可用,就会记录一个 unknown 许可证。此许可证会一直显示,直到执行后续流水线并再次进行许可证查找。如果查找确认依赖项的许可证已更改,此时会显示新的许可证。