合规框架

  • 引入于 13.9 版本。
  • 功能标志删除于 13.12 版本。

您可以创建一个作为标记的合规框架,标识您的项目具有某些合规要求或需要额外的监督。标签可以选择性地对应用它的项目强制执行合规流水线配置。

合规框架是在顶级群组上创建的。群组所有者可以创建、编辑和删除合规框架:

  1. 在左侧边栏中,选择 搜索或转到 并找到您的群组。
  2. 选择 设置 > 通用
  3. 展开 合规框架 部分。
  4. 创建、编辑或删除合规框架。

子群组和项目可以访问在其顶级群组上创建的所有合规框架。但是,无法在子群组或项目级别创建、编辑或删除合规框架。项目所有者可以选择一个框架来应用于他们的项目。

为项目添加合规框架

先决条件:

  • 项目所属的群组必须具有合规框架。

要将合规性框架分配给项目:

  1. 在左侧边栏中,选择 搜索或转到 并找到您的项目。
  2. 选择 设置 > 通用
  3. 展开 合规框架
  4. 选择合规框架。
  5. 选择 保存更改
note 无法将框架添加到个人命名空间中的项目中。

GraphQL API

引入于极狐GitLab 14.2。

您可以使用 GraphQL API 向项目添加合规性框架。

如果您使用 GraphQL 在子群组上创建合规性框架,并且用户具有正确的权限,则该框架将在根祖先上创建。极狐GitLab UI 提供了一个只读视图来阻止这种行为。

默认合规框架

引入于极狐GitLab 15.6。

群组所有者可以设置默认的合规框架。默认框架适用于所有在该群组中创建的新的和导入的项目。 它不影响应用于现有项目的框架。默认框架无法删除。

设置为默认的合规性框架具有 默认 标记。

设置和移除默认值

引入于极狐GitLab 15.7。

群组所有者可以将合规框架设置为默认(或移除该设置):

  1. 在左侧边栏中,选择 搜索或转到 并找到您的群组。
  2. 选择 设置 > 通用
  3. 展开 合规性框架 部分并找到要设置(或移除)为默认的合规性框架。
  4. 选择合规框架的垂直省略号 ( ),然后选择 设置默认值(或 移除默认)。

用于设置默认合规性框架的 GraphQL 变更示例

创建一个新的合规框架并将其设置为该群组的默认框架。

mutation {
    createComplianceFramework(
        input: {params: {name: "SOX", description: "Sarbanes-Oxley Act", color: "#87CEEB", default: true}, namespacePath: "gitlab-org"}
    ) {
        framework {
            id
            name
            default
            description
            color
            pipelineConfigurationFullPath
        }
        errors
    }
}

将现有的合规框架设置为该群组的默认框架。

mutation {
    updateComplianceFramework(
        input: {id: "gid://gitlab/ComplianceManagement::Framework/<id>", params: {default: true}}
    ) {
        complianceFramework {
            id
            name
            default
            description
            color
            pipelineConfigurationFullPath
        }
    }
}

合规流水线

  • 引入于极狐GitLab 13.9,禁用在功能标志 ff_evaluate_group_level_compliance_pipeline 后。
  • 默认启用于极狐GitLab 13.11。
  • 功能标志移除于极狐GitLab 14.2。

群组所有者可以在与其他项目分开的项目中配置合规流水线。默认情况下,运行合规流水线配置(例如,.compliance-gitlab-ci.yml),而不是运行标记项目的流水线配置(例如,.gitlab-ci.yml)。

但是,合规流水线配置可以引用标记项目的 .gitlab-ci.yml 文件,这样:

  • 合规流水线还可以运行标记的项目流水线的作业。允许集中控制流水线配置。
  • 合规流水线中定义的作业和变量不能被标记项目的 .gitlab-ci.yml 文件中的变量更改。
note 项目流水线必须首先包含在合规流水线配置的顶部以防项目覆盖下游设置。

有关更多信息,请参阅:

对标记项目的影响

用户无法知道合规流水线已配置,并且可能会困惑为什么他们自己的流水线根本没有运行,或者包括他们自己没有定义的作业。

在标记的项目上创作流水线时,没有任何迹象能看出是否已配置合规流水线。 项目级别的唯一标记是合规框架标记本身,但该标记签并未说明框架是否配置了合规流水线。

因此,与项目用户就合规流水线配置进行沟通,以减少不确定性和混乱。

配置合规流水线

配置合规流水线:

  1. 在左侧边栏中,选择 搜索或转到 并找到您的群组。
  2. 选择 设置 > 通用
  3. 展开 合规框架 部分。
  4. 合规流水线配置(可选)中,添加合规框架配置的路径。使用 path/file.y[a]ml@group-name/project-name 格式。例如:

    -.compliance-ci.yml@gitlab-org/gitlab - .compliance-ci.yaml@gitlab-org/gitlab

此配置由合规框架标记为应用的项目继承。在应用了合规框架标记的项目中,将运行合规流水线配置,而不运行打标记的项目自己的流水线配置。

在标记项目中运行流水线的用户必须至少具有合规项目的报告者角色。

进行扫描时,此功能与扫描执行策略有一些重叠。我们还没有统一这两个功能的用户体验。

配置示例

以下示例 .compliance-gitlab-ci.yml 包含 include 关键字以确保标记的项目流水线也被执行。

include:  # Execute individual project's configuration (if project contains .gitlab-ci.yml)
  - project: '$CI_PROJECT_PATH'
    file: '$CI_CONFIG_PATH'
    ref: '$CI_COMMIT_SHA' # Must be defined or MR pipelines always use the use default branch
    rules:
      - if: $CI_PROJECT_PATH != "my-group/project-1" # Must be the hardcoded path to the project that hosts this configuration.

# Allows compliance team to control the ordering and interweaving of stages/jobs.
# Stages without jobs defined will remain hidden.
stages:
  - pre-compliance
  - build
  - test
  - pre-deploy-compliance
  - deploy
  - post-compliance

variables:  # Can be overridden by setting a job-specific variable in project's local .gitlab-ci.yml
  FOO: sast

sast:  # None of these attributes can be overridden by a project's local .gitlab-ci.yml
  variables:
    FOO: sast
  image: ruby:2.6
  stage: pre-compliance
  rules:
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
      when: never
    - when: always  # or when: on_success
  allow_failure: false
  before_script:
    - "# No before scripts."
  script:
    - echo "running $FOO"
  after_script:
    - "# No after scripts."

sanity check:
  image: ruby:2.6
  stage: pre-deploy-compliance
  rules:
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
      when: never
    - when: always  # or when: on_success
  allow_failure: false
  before_script:
    - "# No before scripts."
  script:
    - echo "running $FOO"
  after_script:
    - "# No after scripts."

audit trail:
  image: ruby:2.7
  stage: post-compliance
  rules:
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
      when: never
    - when: always  # or when: on_success
  allow_failure: false
  before_script:
    - "# No before scripts."
  script:
    - echo "running $FOO"
  after_script:
    - "# No after scripts."

include 定义中的 rules 配置避免了循环包含,以防合规流水线必须能够在托管项目本身中运行。 如果您的合规流水线仅在标记的项目中运行,则可以将其省略。

外部托管的合规流水线和自定义流水线配置

上面的示例假设所有项目都在同一项目中托管其流水线配置。 如果任何项目使用项目外部托管的配置

  • 示例合规流水线配置中的 include 部分必须进行调整。 例如,使用 include:rules

    include:
      # If the custom path variables are defined, include the project's external config file.
      - project: '$PROTECTED_PIPELINE_CI_PROJECT_PATH'
        file: '$PROTECTED_PIPELINE_CI_CONFIG_PATH'
        ref: '$PROTECTED_PIPELINE_CI_REF'
        rules:
          - if: $PROTECTED_PIPELINE_CI_PROJECT_PATH && $PROTECTED_PIPELINE_CI_CONFIG_PATH && $PROTECTED_PIPELINE_CI_REF
      # If any custom path variable is not defined, include the project's internal config file as normal.
      - project: '$CI_PROJECT_PATH'
        file: '$CI_CONFIG_PATH'
        ref: '$CI_COMMIT_SHA'
        rules:
          - if: $PROTECTED_PIPELINE_CI_PROJECT_PATH == null || $PROTECTED_PIPELINE_CI_CONFIG_PATH == null || $PROTECTED_PIPELINE_CI_REF == null
    
  • 必须将 CI/CD 变量添加到具有外部流水线配置的项目中。在这个例子中:

    • PROTECTED_PIPELINE_CI_PROJECT_PATH:托管配置文件的项目的路径,例如 group/subgroup/project
    • PROTECTED_PIPELINE_CI_CONFIG_PATH:项目中配置文件的路径,例如 path/to/.gitlab-ci.yml
    • PROTECTED_PIPELINE_CI_REF:检索配置文件时使用的引用,例如 main

源自项目派生的合并请求中的合规流水线

当合并请求源自派生时,要合并的分支通常只存在于派生中。 当为具有合规流水线的项目创建此类合并请求时,上述代码段会失败,并显示 Project <project-name> reference <branch-name> does not exist! 错误消息。 发生此错误的原因是在目标项目的上下文中,$CI_COMMIT_REF_NAME 的计算结果为不存在的分支名称。

要获取正确的上下文,请使用 $CI_MERGE_REQUEST_SOURCE_PROJECT_PATH 而不是 $CI_PROJECT_PATH。 该变量仅在合并请求流水线中可用。

include:  # Execute individual project's configuration (if project contains .gitlab-ci.yml)
  - project: '$CI_MERGE_REQUEST_SOURCE_PROJECT_PATH'
    file: '$CI_CONFIG_PATH'
    ref: '$CI_COMMIT_REF_NAME'
    rules:
      - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  - project: '$CI_PROJECT_PATH'
    file: '$CI_CONFIG_PATH'
    ref: '$CI_COMMIT_REF_NAME'
    rules:
      - if: $CI_PIPELINE_SOURCE != 'merge_request_event'

确保合规作业始终运行

合规流水线使用极狐GitLab CI/CD 为您提供很大的灵活性,用于定义您喜欢的任何类型的合规作业。根据您的目标,这些作业可以配置为:

  • 由用户修改。
  • 不可修改。

一般来说,如果合规工作中的值:

  • 已设置,则它不能被项目级配置更改或覆盖。
  • 未设置,则可能设置了项目级配置。

您可以根据您的用例自由选择。

以下是一些最佳实践,可确保这些作业始终完全按照您定义的方式运行,并且下游项目级流水线配置无法对其进行更改:

  • rules:when:always添加到每个合规作业中。这确保它们不可修改并且始终运行。
  • 显式设置作业引用的任何变量。这会:
    • 确保项目级流水线配置不会设置它们并改变它们的行为。
    • 包括驱动您的作业逻辑的任何作业。
  • 显式设置要在其中运行作业的容器镜像。这可确保您的脚本步骤在正确的环境中执行。
  • 显式设置任何相关的极狐GitLab 预定义的作业关键字。 这可确保您的作业使用您想要的设置,并且它们不会被项目级流水线覆盖。

在 14.7 及更早版本中避免使用父流水线和子流水线

note 此建议不适用于 14.8 及更高版本,因为修复添加了组合合规流水线以及父子流水线的兼容性。

合规流水线从标记项目中的每一个流水线的运行开始。这意味着,如果标记项目中的流水线触发子流水线,则合规流水线首先运行。这可以触发父流水线,而不是子流水线。

因此,在具有合规框架的项目中,您应该将父子流水线替换为以下内容:

  • 直接 include 语句,为父流水线提供子流水线配置。
  • 使用触发 API 运行的在另一个项目中的子流水线,而不是父子流水线功能。

此替代方案可确保合规流水线不会重新启动父流水线。

故障排除

合规性作业被目标仓库覆盖

如果您在合规流水线配置中使用 extends 语句,合规性作业将被目标仓库作业覆盖。例如,您可以进行以下 .compliance-gitlab-ci.yml 配置:

"compliance job":
  extends:
    - .compliance_template
  stage: build

.compliance_template:
  script:
    - echo "take compliance action"

您还可以进行以下 .gitlab-ci.yml 配置:

"compliance job":
  stage: test
  script:
    - echo "overwriting compliance action"

此配置会导致目标仓库流水线覆盖合规流水线,并且您会收到 overwriting compliance action 消息。

为了避免覆盖合规作业,请勿在合规流水线配置中使用 extends 关键字。例如,您可以进行以下 .compliance-gitlab-ci.yml 配置:

"compliance job":
  stage: build
  script:
    - echo "take compliance action"

您还可以进行以下 .gitlab-ci.yml 配置:

"compliance job":
  stage: test
  script:
    - echo "overwriting compliance action"

此配置不会覆盖合规流水线,您会收到 take compliance action 消息。

未显示预填充变量

15.3 及更高版本中的合规流水线可能会阻止预填充变量在手动启动流水线时出现。

要解决此问题,请在执行单个项目配置的 include: 语句中使用 ref: '$CI_COMMIT_SHA' 而不是 ref: '$CI_COMMIT_REF_NAME'

配置示例已更新了以下更改:

include:
  - project: '$CI_PROJECT_PATH'
    file: '$CI_CONFIG_PATH'
    ref: '$CI_COMMIT_SHA'