极狐 GitLab

Merge request approval policies

Tier: 旗舰版

Offering: JihuLab.com, 极狐GitLab 私有化部署, 极狐GitLab Dedicated

版本历史
  • 群组级别扫描结果策略在极狐GitLab 15.6 中引入
  • 扫描结果策略功能在极狐GitLab 16.9 中重命名为合并请求批准策略。
扫描结果策略功能在极狐GitLab 16.9 中重命名为合并请求批准策略。

您可以将合并请求批准策略用于多种目的,包括:

  1. 从安全和许可证扫描仪检测结果以强制执行批准规则。例如,一种类型的合并请求策略是安全批准策略,允许根据一个或多个安全扫描作业的发现需要批准。合并请求批准策略在 CI 扫描作业完全执行后评估,并根据已发布的流水线中的作业产物报告评估漏洞和许可证类型策略。
  2. 对满足特定条件的所有合并请求强制执行批准规则。例如,强制所有合并请求目标为默认分支的合并请求由具有开发者和维护者角色的多个用户进行审核。
  3. 在项目上强制执行安全和合规设置。例如,阻止编写或提交合并请求更改的用户批准合并请求。或者阻止用户推送或强制推送到默认分支,以确保所有更改都通过合并请求。
当创建或删除受保护分支时,策略批准规则会同步,延迟为 1 分钟。

以下视频概述了极狐GitLab 合并请求批准策略(以前的扫描结果策略):

限制#

  • 您只能对受保护的目标分支强制执行合并请求批准策略。
  • 每个策略最多可以分配五个规则。
  • 每个安全策略项目最多可以分配五个合并请求批准策略。
  • 为群组或子群组创建的策略可能需要一些时间才能应用于该群组中的所有合并请求。所需时间由项目数量和这些项目中的合并请求数量决定。通常,所需时间是几秒钟。对于拥有数千个项目和合并请求的群组,这可能需要几分钟时间,基于我们之前的观察。
  • 合并请求批准策略不检查产物报告中生成的扫描结果的完整性或真实性。
  • 合并请求批准策略根据其规则进行评估。默认情况下,如果规则无效或无法评估,则需要批准。您可以使用fallback_behavior字段更改此行为。

流水线要求#

合并请求批准策略根据流水线的结果执行。在实施合并请求批准策略时,请考虑以下几点:

  1. 合并请求批准策略评估已完成的流水线作业,忽略手动作业。当手动作业运行时,策略会重新评估合并请求的作业。
  2. 对于评估安全扫描仪结果的合并请求批准策略,所有指定的扫描仪必须输出安全报告。如果没有,则会强制批准以降低引入漏洞的风险。此行为可能影响:
    • 尚未建立安全扫描的新项目。
    • 在配置安全扫描之前创建的分支。
    • 在分支之间具有不一致扫描仪配置的项目。
  3. 流水线必须为启用的所有扫描仪生成产物,包括源分支和目标分支。如果没有,则没有比较基础,因此无法评估策略。您应该使用扫描执行策略来强制执行此要求。
  4. 策略评估取决于成功且已完成的合并基础流水线。如果跳过合并基础流水线,则具有合并基础流水线的合并请求将被阻止。
  5. 策略中指定的安全扫描仪必须在项目中配置并启用。否则,无法评估合并请求批准策略,并需要相应的批准。

使用安全扫描仪与合并请求批准策略的最佳实践#

创建新项目时,您可以在该项目上同时执行合并请求批准策略和安全扫描。但是,配置不正确的安全扫描仪会影响合并请求批准策略。

在新项目中有多种配置安全扫描的方法:

  1. 在项目的 CI/CD 配置中,通过在初始 .gitlab-ci.yml 配置文件中添加扫描仪。
  2. 在扫描执行策略中强制流水线运行特定安全扫描仪。
  3. 在流水线执行策略中控制必须在流水线中运行的作业。

对于简单的使用案例,您可以使用项目的 CI/CD 配置。对于全面的安全策略,考虑将合并请求批准策略与其他策略类型结合使用。

为了尽量减少不必要的批准要求并确保准确的安全评估:

  1. 首先在默认分支上运行安全扫描:在创建功能分支之前,确保安全扫描已在默认分支上成功运行。
  2. 使用一致的扫描仪配置:在源分支和目标分支中运行相同的扫描仪,最好在单个流水线中。
  3. 验证扫描是否产生产物:确保扫描成功完成并产生产物以进行比较。
  4. 保持分支同步:定期将默认分支的更改合并到功能分支。
  5. 考虑流水线配置:对于新项目,在初始 .gitlab-ci.yml 配置中包含安全扫描仪。

在应用合并请求批准策略之前验证安全扫描仪#

在应用合并请求批准策略之前,在新项目中实施安全扫描,确保安全扫描仪在依赖合并请求批准策略之前一致运行,这有助于避免由于缺少安全扫描而导致合并请求被阻止的情况。

要创建和验证安全扫描仪和合并请求批准策略,请使用以下推荐工作流程:

  1. 创建项目。
  2. 使用 .gitlab-ci.yml 配置、扫描执行策略或流水线执行策略配置安全扫描仪。
  3. 等待默认分支上的初始流水线完成。解决任何问题并重新运行流水线,以确保在继续之前成功完成。
  4. 使用配置了相同安全扫描仪的功能分支创建合并请求。再次确保安全扫描仪成功完成。
  5. 应用合并请求批准策略。

具有多个流水线的合并请求#

版本历史
  • 在极狐GitLab 16.2 中引入 带有一个标志名为 multi_pipeline_scan_result_policies。默认情况下禁用。
  • 在极狐GitLab 16.3 中普遍可用。特性标志 multi_pipeline_scan_result_policies 移除。
  • 在极狐GitLab 16.11 中引入对父子流水线的支持带有一个标志名为 approval_policy_parent_child_pipeline。默认情况下禁用。
  • 在极狐GitLab 17.0 中启用
  • 在极狐GitLab 17.1 中普遍可用。特性标志 approval_policy_parent_child_pipeline 移除。

一个项目可以配置多个流水线类型。单个提交可以启动多个流水线,每个流水线都可能包含一个安全扫描。

  1. 在极狐GitLab 16.3 及之后,评估并使用合并请求的源分支和目标分支中最新提交的所有已完成流水线的结果来强制执行合并请求批准策略。按需 DAST 流水线不被考虑。
  2. 在极狐GitLab 16.2 及之前,只有最新已完成流水线的结果在强制执行合并请求批准策略时被评估。

如果项目使用合并请求流水线,您必须使用最新安全模板以便安全扫描作业出现在流水线中。 有关更多信息,请参阅使用安全扫描工具与合并请求流水线

合并请求批准策略编辑器#

版本历史
只有项目**所有者**拥有[权限](../../permissions.md#project-members-permissions)选择安全策略项目。

一旦您的策略完成,通过在编辑器底部选择 Configure with a merge request 来保存它。这将您重定向到项目配置的安全策略项目上的合并请求。 如果安全策略项目没有链接到您的项目,极狐GitLab 会为您创建这样的项目。现有策略也可以通过在编辑器界面底部选择 Delete policy 来删除。

大多数策略更改在合并请求合并后立即生效。任何不通过合并请求并直接提交到默认分支的更改可能需要最多 10 分钟才能生效。

策略编辑器支持 YAML 模式和规则模式。

为具有大量项目的群组创建的合并请求批准策略的传播需要一段时间才能完成。

合并请求批准策略模式#

带有合并请求批准策略的 YAML 文件由一组与合并请求批准策略模式匹配的对象组成,这些对象嵌套在 approval_policy 键下。您最多可以在 approval_policy 键下配置五个策略。

合并请求批准策略在 `scan_result_policy` 键下定义。直到极狐GitLab 17.0,策略可以在两个键下定义。从极狐GitLab 17.0 开始,只支持 `approval_policy` 键。

当您保存新策略时,极狐GitLab 会根据此 JSON 模式验证其内容。 如果您不熟悉如何阅读JSON 模式,以下部分和表格提供了替代方案。

字段类型必需描述
approval_policy合并请求批准策略对象的数组true合并请求批准策略列表(最多 5 个)。

scan_finding 规则类型#

版本历史

该规则根据安全扫描结果强制执行定义的操作。

字段类型必需可能值描述
typestringtruescan_finding规则的类型。
branchesstring 的数组如果 branch_type 字段不存在,则为 true[] 或分支名称仅适用于受保护的目标分支。空数组 [] 将规则应用于所有受保护的目标分支。不能与 branch_type 字段一起使用。
branch_typestring如果 branches 字段不存在,则为 truedefaultprotected给定策略适用的受保护分支类型。不能与 branches 字段一起使用。默认分支也必须是 protected
branch_exceptionsstring 的数组false分支名称从此规则中排除的分支。
scannersstring 的数组truesast, secret_detection, dependency_scanning, container_scanning, dast, coverage_fuzzing, api_fuzzing要考虑的安全扫描仪。sast 包括来自 SAST 和 SAST IaC 扫描仪的结果。
vulnerabilities_allowedintegertrue大于或等于零在考虑此规则之前允许的漏洞数量。
severity_levelsstring 的数组trueinfo, unknown, low, medium, high, critical要考虑的严重性级别。
vulnerability_statesstring 的数组true[]detected, confirmed, resolved, dismissed, new_needs_triage, new_dismissed所有漏洞分为两类:

新检测到的漏洞 - 在合并请求分支本身中识别的漏洞,但在合并请求的目标分支中当前不存在。此策略选项需要流水线完成才能评估规则,以便知道漏洞是否是新检测到的。合并请求会被阻止,直到流水线和必要的安全扫描完成。new_needs_triage 选项考虑状态

• 检测到

new_dismissed 选项考虑状态

• 驳回

预先存在的漏洞 - 这些策略选项立即评估,不需要流水线完成,因为它们仅考虑在默认分支中之前检测到的漏洞。

Detected - 策略寻找检测到状态的漏洞。
Confirmed - 策略寻找已确认状态的漏洞。
Dismissed - 策略寻找被驳回状态的漏洞。
Resolved - 策略寻找已解决状态的漏洞。

空数组 [] 涵盖与 ['new_needs_triage', 'new_dismissed'] 相同的状态。
vulnerability_attributesobjectfalse{false_positive: boolean, fix_available: boolean}默认情况下,考虑所有漏洞发现。但可以应用过滤器以仅考虑具有以下属性的漏洞发现:

• 有可用修复(fix_available: true

• 无可用修复(fix_available: false
• 是假阳性(false_positive: true
• 不是假阳性(false_positive: false
• 或两者的组合。例如(fix_available: true, false_positive: false
vulnerability_ageobjectfalseN/A按年龄过滤预先存在的漏洞发现。漏洞的年龄计算为项目中检测到的时间。标准是 operatorvalueinterval
- operator 标准指定使用的年龄比较是大于(greater_than)还是小于(less_than)。
- value 标准指定表示漏洞年龄的数值。
- interval 标准指定漏洞年龄的单位:dayweekmonthyear

示例:operator: greater_thanvalue: 30interval: day

license_finding 规则类型#

版本历史

该规则根据许可证发现强制执行定义的操作。

字段类型必需可能值描述
typestringtruelicense_finding规则的类型。
branchesstring 的数组如果 branch_type 字段不存在,则为 true[] 或分支名称仅适用于受保护的目标分支。空数组 [] 将规则应用于所有受保护的目标分支。不能与 branch_type 字段一起使用。
branch_typestring如果 branches 字段不存在,则为 truedefaultprotected给定策略适用的受保护分支类型。不能与 branches 字段一起使用。默认分支也必须是 protected
branch_exceptionsstring 的数组false分支名称从此规则中排除的分支。
match_on_inclusion_licenseboolean如果 licenses 字段不存在则为 truetrue, false规则是否匹配 license_types 中列出的许可证的包含或排除。
license_typesstring 的数组如果 licenses 字段不存在则为 true许可证类型SPDX 许可证名称 要匹配,例如 Affero General Public License v1.0MIT License
license_statesstring 的数组truenewly_detected, detected是否匹配新检测到的和/或先前检测到的许可证。newly_detected 状态在引入新软件包或检测到现有软件包的新许可证时触发批准。
licensesobject如果 license_types 字段不存在则为 truelicenses objectSPDX 许可证名称 以包例外为匹配。

licenses 对象#

字段类型必需可能值描述
deniedobject如果 allowed 字段不存在则为 truelicenses_with_package_exclusion 对象的数组包括包例外在内的拒绝许可证列表。
allowedobject如果 denied 字段不存在则为 truelicenses_with_package_exclusion 对象的数组包括包例外在内的允许许可证列表。

licenses_with_package_exclusion 对象#

字段类型必需可能值描述
namestringtrueSPDX 许可证名称SPDX 许可证名称
packagesobjectfalsepackages 对象给定许可证的包例外列表。

packages 对象#

字段类型必需可能值描述
excludingobjecttrue{purls: string 的数组,使用 uri 格式}给定许可证的包例外列表。使用 purl 组件 scheme:type/name@version 定义包例外列表。scheme:type/name 组件是必需的。@version 是可选的。如果指定版本,则仅考虑该版本为例外。如果没有指定版本且在包名末尾添加了 @ 字符,则仅包名完全匹配的包被视为匹配。如果没有在包名末尾添加 @ 字符,则所有具有相同前缀的包被视为匹配。例如,pkg:gem/bundler 匹配 bundlerbundler-stats 包,因为两个包都使用相同的许可证。定义 purl pkg:gem/bundler@ 仅匹配 bundler 包。

any_merge_request 规则类型#

版本历史

此规则根据提交签名对任何合并请求强制执行定义的操作。

字段类型必需可能值描述
typestringtrueany_merge_request规则的类型。
branchesstring 的数组如果 branch_type 字段不存在则为 true[] 或分支名称仅适用于受保护的目标分支。空数组 [] 将规则应用于所有受保护的目标分支。不能与 branch_type 字段一起使用。
branch_typestring如果 branches 字段不存在则为 truedefaultprotected给定策略适用的受保护分支类型。不能与 branches 字段一起使用。默认分支也必须是 protected
branch_exceptionsstring 的数组false分支名称从此规则中排除的分支。
commitsstringtrueany, unsigned规则是否匹配任何提交,或仅在合并请求中检测到未签名提交时。

require_approval 操作类型#

此操作在策略中至少有一个规则满足条件时设置批准规则为必需。

版本历史
  • 在极狐GitLab 17.7 中添加对最多五个单独 require_approval 操作的支持带有一个标志名为 multiple_approval_actions
  • 在极狐GitLab 17.8 中普遍可用。特性标志 multiple_approval_actions 移除。
  • 在极狐GitLab 17.9 中引入支持在 YAML 模式中指定自定义角色作为 role_approvers 带有一个标志名为 security_policy_custom_roles。默认启用。
  • 在极狐GitLab 17.10 中普遍可用。特性标志 security_policy_custom_roles 移除。
字段类型必需可能值描述
typestringtruerequire_approval操作的类型。
approvals_requiredintegertrue大于或等于零所需的合并请求批准数量。
user_approversstring 的数组false一个或多个用户的用户名要考虑为批准者的用户。用户必须有访问项目的权限才能有资格批准。
user_approvers_idsinteger 的数组false一个或多个用户的 ID要考虑为批准者的用户 ID。用户必须有访问项目的权限才能有资格批准。
group_approversstring 的数组false一个或多个群组的路径要考虑为批准者的群组。具有群组直接成员资格的用户有资格批准。
group_approvers_idsinteger 的数组false一个或多个群组的 ID要考虑为批准者的群组 ID。具有群组直接成员资格的用户有资格批准。
role_approversstring 的数组false一个或多个角色(例如:owner, maintainer)。您还可以指定自定义角色(或 YAML 模式中的自定义角色标识符)作为 role_approvers,如果自定义角色有批准合并请求的权限。可以与用户和群组批准者一起选择自定义角色。有资格批准的角色。

send_bot_message 操作类型#

版本历史
  • 在极狐GitLab 16.11 中引入合并请求中的 send_bot_message 操作类型带有一个标志名为 approval_policy_disable_bot_comment。默认情况下禁用。
  • 在极狐GitLab 私有化部署和极狐GitLab Dedicated 中启用于极狐GitLab 17.0。
  • 在极狐GitLab 17.3 中普遍可用。特性标志 approval_policy_disable_bot_comment 移除。
  • 在极狐GitLab 17.2 中引入群组中的 send_bot_message 操作类型带有一个标志名为 approval_policy_disable_bot_comment_group。默认情况下禁用。
  • 在极狐GitLab 私有化部署和极狐GitLab Dedicated 中启用于极狐GitLab 17.2。
  • 在极狐GitLab 17.3 中普遍可用。特性标志 approval_policy_disable_bot_comment_group 移除。

此操作启用在检测到策略违规时配置合并请求中的机器人消息。 如果未指定操作,则默认启用机器人消息。如果定义了多个策略,只要至少一个策略启用了 send_bot_message 操作,机器人消息就会发送。

字段类型必需可能值描述
typestringtruesend_bot_message操作的类型。
enabledbooleantruetrue, false是否在检测到策略违规时创建机器人消息。默认值:true

机器人消息示例#

scan_results_example_bot_message_v17_0

scan_results_example_bot_message_v17_0

警告模式#

版本历史

启用警告模式时,如果合并请求触发不需要任何额外批准者的安全策略,会向合并请求添加一个机器人评论。该评论引导用户查看策略以获取更多信息。

approval_settings#

版本历史
  • 在极狐GitLab 16.8 中引入block_group_branch_modification 字段带有一个标志名为 scan_result_policy_block_group_branch_modification
  • 在极狐GitLab.com 和极狐GitLab 私有化部署中启用于极狐GitLab 17.6。
  • 在极狐GitLab 17.7 中普遍可用。特性标志 scan_result_policy_block_group_branch_modification 移除。
  • 在极狐GitLab 16.4 中引入block_unprotecting_branches 字段带有一个标志名为 scan_result_policy_settings。默认情况下禁用。
  • 在极狐GitLab 16.4 中 scan_result_policy_settings 特性标志被替换为 scan_result_policies_block_unprotecting_branches 特性标志。
  • 在极狐GitLab 16.7 中替换block_unprotecting_branches 字段为 block_branch_modification 字段。
  • 在极狐GitLab.com 和极狐GitLab 私有化部署中启用于极狐GitLab 16.7。
  • 在极狐GitLab 16.11 中普遍可用。特性标志 scan_result_policies_block_unprotecting_branches 移除。
  • 在极狐GitLab 16.4 中引入prevent_approval_by_authorprevent_approval_by_commit_authorremove_approvals_with_new_commitrequire_password_to_approve 字段带有一个标志名为 scan_result_any_merge_request。默认情况下禁用。
  • 在极狐GitLab.com 中启用于极狐GitLab 16.6。
  • 在极狐GitLab 私有化部署中启用于极狐GitLab 16.7。
  • 在极狐GitLab 16.8 中普遍可用。特性标志 scan_result_any_merge_request 移除。
  • 在极狐GitLab 16.4 中引入prevent_pushing_and_force_pushing 字段带有一个标志名为 scan_result_policies_block_force_push。默认情况下禁用。
  • 在极狐GitLab.com 中启用于极狐GitLab 16.6。
  • 在极狐GitLab 私有化部署中启用于极狐GitLab 16.7。
  • 在极狐GitLab 16.9 中普遍可用。特性标志 scan_result_policies_block_force_push 移除。

策略中设置的设置会覆盖项目中的设置。

字段类型必需可能值适用的规则类型描述
block_branch_modificationbooleanfalsetrue, falseAll启用时,阻止用户从受保护分支列表中删除分支、删除受保护分支或更改默认分支,如果该分支包含在安全策略中。这确保用户不能移除分支的保护状态以合并漏洞代码。根据 branchesbranch_typepolicy_scope 强制执行,并且不考虑检测到的漏洞。
block_group_branch_modificationbooleanobjectfalsetrue, false, { enabled: boolean, exceptions: [{ id: Integer}] }All启用时,阻止用户在策略适用的每个群组中删除群组级别受保护分支。如果 block_branch_modificationtrue,则隐式默认值为 true。将支持群组级别受保护分支的顶级群组添加为 exceptions
prevent_approval_by_authorbooleanfalsetrue, falseAny merge request启用时,合并请求作者不能批准自己的合并请求。这确保代码作者不能引入漏洞并批准代码合并。
prevent_approval_by_commit_authorbooleanfalsetrue, falseAny merge request启用时,向合并请求提交代码的用户没有资格获得批准。这确保代码提交者不能引入漏洞并批准代码合并。
remove_approvals_with_new_commitbooleanfalsetrue, falseAny merge request启用时,如果合并请求获得所有必要批准以合并,但随后添加了新提交,则需要新的批准。这确保新的提交可能会引入漏洞不能被引入。
require_password_to_approvebooleanfalsetrue, falseAny merge request启用时,批准时将进行密码确认。密码确认增加了一层额外的安全性。
prevent_pushing_and_force_pushingbooleanfalsetrue, falseAll启用时,阻止用户推送和强制推送到受保护分支,如果该分支包含在安全策略中。这确保用户不绕过合并请求流程以将漏洞代码添加到分支中。

fallback_behavior#

版本历史
  • 在极狐GitLab 17.0 中引入fallback_behavior 字段带有一个标志名为 security_scan_result_policies_unblock_fail_open_approval_rules。默认情况下禁用。
  • 在极狐GitLab.com、极狐GitLab 私有化部署和极狐GitLab Dedicated 中启用于极狐GitLab 17.0。
在极狐GitLab 私有化部署中,默认情况下 `fallback_behavior` 字段是可用的。要隐藏此功能,管理员可以[禁用特性标志](../../../administration/feature_flags.md)名为 `security_scan_result_policies_unblock_fail_open_approval_rules`。在极狐GitLab.com 和极狐GitLab Dedicated 中,此功能是可用的。
字段类型必需可能值描述
failstringfalseopenclosedclosed(默认):策略中无效或无法执行的规则需要批准。open:策略中无效或无法执行的规则不需要批准。

policy_tuning#

版本历史
  • 在极狐GitLab 17.10 中引入对在流水线执行策略中使用的支持带有一个标志名为 unblock_rules_using_pipeline_execution_policies。默认启用。
对流水线执行策略的支持可用性由特性标志控制。有关更多信息,请参阅历史记录。
字段类型必需可能值描述
unblock_rules_using_execution_policiesbooleanfalsetrue, false启用时,当扫描由扫描执行策略或流水线执行策略要求但目标分支缺少所需扫描产物时,批准规则不会阻止合并请求。此选项仅在项目或群组具有现有扫描执行策略或流水线执行策略且具有匹配的扫描仪时有效。

示例#

使用扫描执行策略的 policy_tuning 示例#

您可以在存储于安全策略项目中的 .gitlab/security-policies/policy.yml 文件中使用此示例:

yaml
1scan_execution_policy: 2- name: Enforce dependency scanning 3 description: '' 4 enabled: true 5 policy_scope: 6 projects: 7 excluding: [] 8 rules: 9 - type: pipeline 10 branch_type: all 11 actions: 12 - scan: dependency_scanning 13approval_policy: 14- name: Dependency scanning approvals 15 description: '' 16 enabled: true 17 policy_scope: 18 projects: 19 excluding: [] 20 rules: 21 - type: scan_finding 22 scanners: 23 - dependency_scanning 24 vulnerabilities_allowed: 0 25 severity_levels: [] 26 vulnerability_states: [] 27 branch_type: protected 28 actions: 29 - type: require_approval 30 approvals_required: 1 31 role_approvers: 32 - developer 33 - type: send_bot_message 34 enabled: true 35 fallback_behavior: 36 fail: closed 37 policy_tuning: 38 unblock_rules_using_execution_policies: true

使用流水线执行策略的 policy_tuning 示例#

此功能不适用于在极狐GitLab 17.10 之前创建的流水线执行策略。要在旧流水线执行策略中使用此功能,请复制、删除并重新创建策略。

您可以在存储于安全策略项目中的 .gitlab/security-policies/policy.yml 文件中使用此示例:

yaml
1--- 2pipeline_execution_policy: 3- name: Enforce dependency scanning 4 description: '' 5 enabled: true 6 pipeline_config_strategy: inject_policy 7 content: 8 include: 9 - project: my-group/pipeline-execution-ci-project 10 file: policy-ci.yml 11 ref: main # optional

关联的流水线执行政策 CI/CD 配置在 policy-ci.yml 文件中 {#the-linked-pipeline-execution-policy-ci/cd-configuration-in-policy-ci.yml}#

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

重新创建在 GitLab 17.10 之前创建的流水线执行政策#

在 GitLab 17.10 之前创建的流水线执行政策不包含使用 policy_tuning 功能所需的数据。要在较旧的流水线执行政策中使用此功能,需要复制并删除旧政策,然后重新创建它们。

有关视频演练,请参见 安全政策:重新创建流水线执行政策以用于 policy_tuning

重新创建流水线执行政策:

  1. 在左侧边栏中,选择 搜索或转到 并找到您的群组。
  2. 选择 安全 > 政策
  3. 选择要重新创建的流水线执行政策。
  4. 在右侧边栏中,选择 YAML 标签并复制整个政策文件的内容。
  5. 在政策表旁边,选择垂直省略号 (),然后选择 删除
  6. 合并生成的合并请求。
  7. 返回到 安全 > 政策 并选择 新建政策
  8. 流水线执行政策 部分,选择 选择政策
  9. YAML 模式 中,粘贴旧政策的内容。
  10. 选择 通过合并请求更新 并合并生成的合并请求。

政策范围架构#

为了自定义政策的执行,可以定义政策的范围以包含或排除指定的项目、群组或合规框架标签。有关详细信息,请参见 Scope

安全政策项目中的 policy.yml 示例 {#example-policy.yml-in-a-security-policy-project}#

您可以在存储于安全政策项目中的 .gitlab/security-policies/policy.yml 文件中使用此示例:

yaml
1--- 2approval_policy: 3- name: critical vulnerability CS approvals 4 description: critical severity level only for container scanning 5 enabled: true 6 rules: 7 - type: scan_finding 8 branches: 9 - main 10 scanners: 11 - container_scanning 12 vulnerabilities_allowed: 0 13 severity_levels: 14 - critical 15 vulnerability_states: [] 16 vulnerability_attributes: 17 false_positive: true 18 fix_available: true 19 actions: 20 - type: require_approval 21 approvals_required: 1 22 user_approvers: 23 - adalberto.dare 24- name: secondary CS approvals 25 description: secondary only for container scanning 26 enabled: true 27 rules: 28 - type: scan_finding 29 branches: 30 - main 31 scanners: 32 - container_scanning 33 vulnerabilities_allowed: 1 34 severity_levels: 35 - low 36 - unknown 37 vulnerability_states: 38 - detected 39 vulnerability_age: 40 operator: greater_than 41 value: 30 42 interval: day 43 actions: 44 - type: require_approval 45 approvals_required: 1 46 role_approvers: 47 - owner 48 - 1002816 # Example custom role identifier called "AppSec Engineer"

在此示例中:

  • 每个包含由容器扫描识别的新 critical 漏洞的合并请求需要 alberto.dare 的一个批准。
  • 每个包含超过一个现有 lowunknown 漏洞且超过 30 天的合并请求需要项目成员的一个批准,拥有 Owner 角色的成员和一个自定义角色为 "AppSec Engineer" 的用户批准。

合并请求批准政策编辑器示例#

您可以在 合并请求批准政策编辑器 的 YAML 模式中使用此示例。它对应于前一个示例中的单个对象:

yaml
1type: approval_policy 2name: critical vulnerability CS approvals 3description: critical severity level only for container scanning 4enabled: true 5rules: 6- type: scan_finding 7 branches: 8 - main 9 scanners: 10 - container_scanning 11 vulnerabilities_allowed: 1 12 severity_levels: 13 - critical 14 vulnerability_states: [] 15actions: 16- type: require_approval 17 approvals_required: 1 18 user_approvers: 19 - adalberto.dare

理解合并请求批准政策批准#

版本历史
  • 在极狐GitLab 16.11 中更改了 scan_finding 的分支比较逻辑,使用名为 scan_result_policy_sub_pipeline功能标志。默认禁用。
  • 在极狐GitLab 16.9 中 GA。功能标志 scan_result_policy_sub_pipeline 被移除。

合并请求批准政策比较的范围#

  • 为了确定何时需要在合并请求上进行批准,我们比较了源分支和目标分支的每个支持的流水线来源的已完成流水线(例如,feature/main)。这确保了对扫描结果的最全面评估。
  • 对于源分支,比较的流水线是源分支最新提交的每个支持的流水线来源的所有已完成流水线。
  • 如果合并请求批准政策仅寻找新检测到的状态 (new_needs_triagenew_dismissed),则比较是针对源分支和目标分支之间的共同祖先的所有支持的流水线来源进行的。例外情况是使用合并结果流水线的情况,此时比较是在合并请求目标分支的顶端进行。
  • 如果合并请求批准政策寻找现有状态 (detected, confirmed, resolved, dismissed),则比较始终针对默认分支的顶端进行(例如,main)。
  • 如果合并请求批准政策寻找新旧漏洞状态的组合,则比较是针对源分支和目标分支的共同祖先进行的。
  • 合并请求批准政策考虑所有支持的流水线来源(基于 CI_PIPELINE_SOURCE 变量)在比较来自源分支和目标分支的结果时以确定合并请求是否需要批准。来源为 webide 的流水线不被支持。
  • 在极狐GitLab 16.11 及更高版本中,所选流水线的子流水线也被考虑进行比较。

接受风险并在未来合并请求中忽略漏洞#

对于范围限定为新检测到的发现 (new_needs_triagenew_dismissed 状态) 的合并请求批准政策,理解此漏洞状态的影响非常重要。如果发现存在于合并请求的分支中但不存在于目标分支中,则认为这是新检测到的发现。当包含新检测到发现的分支的合并请求被批准并合并时,批准者正在“接受这些漏洞的风险”。如果在此之后检测到一个或多个相同的漏洞,状态将是 detected,因此在配置为考虑 new_needs_triagenew_dismissed 的政策中被忽略。例如:

  • 创建了一个合并请求批准政策以阻止严重的 SAST 发现。如果批准了 CVE-1234 的 SAST 发现,未来具有相同违规的合并请求在项目中将不需要批准。

当使用 new_needs_triagenew_dismissed 漏洞状态时,政策将阻止任何符合政策规则的新发现的合并请求,即使它们已被驳回。如果您想忽略在合并请求中新检测到并驳回的漏洞,您可以仅使用 new_needs_triage 状态。

使用许可批准政策时,在评估中考虑项目、组件(依赖项)和许可的组合。如果某个许可证被批准为例外,未来合并请求不需要对相同的项目、组件(依赖项)和许可证组合进行批准。在这种情况下不考虑组件的版本。如果先前批准的软件包更新到新版本,批准者将不需要重新批准。例如:

  • 创建了一个许可批准政策以阻止与 AGPL-1.0 匹配的新检测到许可证的合并请求。在项目 demo 中对组件 osframework 进行了更改,违反了政策。如果批准并合并,未来对项目 demo 中的 osframework 的合并请求与许可证 AGPL-1.0 不需要批准。

额外批准#

在某些情况下,合并请求批准政策需要额外的批准步骤。例如:

  • 工作分支中的安全作业数量减少,不再匹配目标分支中的安全作业数量。用户无法通过删除 CI/CD 配置中的扫描作业来跳过扫描结果政策。仅检查合并请求批准政策规则中配置的安全扫描的删除。

    例如,考虑一个情况,其中默认分支流水线有四个安全扫描:sastsecret_detectioncontainer_scanningdependency_scanning。合并请求批准政策执行两个扫描仪:container_scanningdependency_scanning。如果一个 MR 删除了合并请求批准政策中配置的扫描,例如 container_scanning,则需要额外的批准。

  • 某人停止了流水线安全作业,用户无法跳过安全扫描。

  • 合并请求中的作业失败,并配置了 allow_failure: false。结果,流水线处于阻塞状态。

  • 流水线有一个手动作业,必须成功运行才能使整个流水线通过。

管理用于评估批准要求的扫描结果#

合并请求批准政策评估扫描仪在流水线完成后生成的产物报告。合并请求批准政策专注于评估结果并根据扫描结果发现确定批准,以识别潜在风险、阻止合并请求并要求批准。

合并请求批准政策不会超出此范围去读取产物文件或扫描仪。相反,我们信任产物报告的结果。这使团队在管理其扫描执行和供应链时具有灵活性,并在需要时自定义产物报告中生成的扫描结果(例如,过滤掉假阳性)。

锁定文件篡改,例如,超出了安全政策管理的范围,但可以通过使用 代码所有者外部状态检查 进行缓解。

评估扫描结果发现

使用属性 "Fix Available" 或 "False Positive" 过滤掉政策违规#

为了避免不必要的批准要求,这些额外的筛选器有助于确保您仅在最可操作的发现上阻止 MR。

通过在 YAML 中设置 fix_availablefalse,或在政策编辑器中设置 不是可用修复,当发现有解决方案或修复可用时,发现不被视为政策违规。解决方案出现在漏洞对象的底部,标题为 解决方案。修复出现在漏洞对象中 通过合并请求解决 按钮。

只有在满足以下条件之一时,通过合并请求解决 按钮才会出现:

  1. 在一个极狐GitLab旗舰版的项目中发现容器扫描漏洞,该项目中的作业设置了 GIT_STRATEGY: fetch。此外,漏洞必须包含一个软件包,且该软件包的修复可用于为容器镜像启用的存储库。
  2. 在使用 yarn 管理的 Node.js 项目中发现依赖扫描漏洞,并且有修复可用。此外,项目必须为极狐GitLab旗舰版,且实例的 FIPS 模式必须被禁用。

可用修复 仅适用于依赖扫描和容器扫描。

通过使用 假阳性 属性,类似地,您可以通过在 YAML 中设置 false_positivefalse(或在政策编辑器中设置属性为 不是假阳性)来忽略政策检测到的发现。

假阳性 属性仅适用于我们的漏洞提取工具检测到的 SAST 结果发现。

故障排除#

合并请求规则小部件显示合并请求批准政策无效或重复#

Tier:旗舰版

Offering:私有化部署

在极狐GitLab 私有化部署从 15.0 到 16.4,最有可能的原因是项目被从一个群组导出并导入到另一个群组,并且具有合并请求批准政策规则。这些规则存储在与导出的项目分开的项目中。结果是项目包含引用不存在于导入项目群组中的实体的政策规则。结果是政策规则无效、重复或两者兼有。

要从极狐GitLab 实例中删除所有无效的合并请求批准政策规则,管理员可以在 Rails 控制台 中运行以下脚本。

ruby
1Project.joins(:approval_rules).where(approval_rules: { report_type: %i[scan_finding license_scanning] }).where.not(approval_rules: { security_orchestration_policy_configuration_id: nil }).find_in_batches.flat_map do |batch| 2 batch.map do |project| 3 # Get projects and their configuration_ids for applicable project rules 4 [project, project.approval_rules.where(report_type: %i[scan_finding license_scanning]).pluck(:security_orchestration_policy_configuration_id).uniq] 5 end.uniq.map do |project, configuration_ids| # We take only unique combinations of project + configuration_ids 6 # If we find more configurations than what is available for the project, we take records with the extra configurations 7 [project, configuration_ids - project.all_security_orchestration_policy_configurations.pluck(:id)] 8 end.select { |_project, configuration_ids| configuration_ids.any? } 9end.each do |project, configuration_ids| 10 # For each found pair project + ghost configuration, we remove these rules for a given project 11 Security::OrchestrationPolicyConfiguration.where(id: configuration_ids).each do |configuration| 12 configuration.delete_scan_finding_rules_for_project(project.id) 13 end 14 # Ensure we sync any potential rules from new group's policy 15 Security::ScanResultPolicies::SyncProjectWorker.perform_async(project.id) 16end

新检测到的 CVE#

当使用 new_needs_triagenew_dismissed 时,某些发现可能需要批准,而这些发现不是由合并请求引入的(例如相关依赖项上的新 CVE)。这些发现将不会在 MR 小部件中出现,但将在政策机器人评论和流水线报告中突出显示。

policy.yml 手动失效后政策仍然有效 {#policies-still-have-effect-after-policy.yml-was-manually-invalidated}#

在极狐GitLab 17.2 及更早版本中,您可能发现定义在 policy.yml 文件中的政策被强制执行,即使该文件被手动编辑且不再验证 政策架构。此问题是由于政策同步逻辑中的错误导致的。

潜在的症状包括:

  • approval_settings 仍然阻止删除分支保护,阻止强制推送或以其他方式影响打开的合并请求。
  • any_merge_request 政策仍然适用于打开的合并请求。

为了解决此问题,您可以:

  • 手动编辑定义政策的 policy.yml 文件,使其再次有效。
  • 取消分配并重新分配存储 policy.yml 文件的安全政策项目。

缺少安全扫描#

在使用合并请求批准政策时,您可能会遇到合并请求被阻止的情况,包括在新项目中或某些安全扫描未执行时。这种行为是设计的一部分,以减少将漏洞引入系统的风险。

示例场景:

  • 源或目标分支缺少扫描

    如果源或目标分支缺少安全扫描,极狐GitLab 无法有效评估合并请求是否引入了新漏洞。在这种情况下,作为预防措施需要批准。

  • 新项目

    对于新项目,在目标分支上尚未设置或执行安全扫描的所有合并请求均需要批准。这确保了从项目开始时就激活安全检查。

  • 没有要扫描文件的项目

    即使在不包含与选定安全扫描相关的文件的项目中,仍然强制执行批准要求。这在所有项目中保持一致的安全实践。

  • 第一个合并请求

    如果默认分支没有安全扫描,即使源分支没有漏洞,新项目的第一个合并请求可能会被阻止。

为了解决这些问题:

  • 确保所有必需的安全扫描都已配置并在源分支和目标分支上成功运行。
  • 对于新项目,在创建合并请求之前,在默认分支上设置并运行必要的安全扫描。
  • 考虑使用扫描执行政策或流水线执行政策以确保在所有分支上一致执行安全扫描。
  • 考虑使用 fallback_behavioropen 来防止政策中的无效或无法执行的规则需要批准。
  • 考虑使用 policy tuning 设置 unblock_rules_using_execution_policies 来处理缺少安全扫描产物且强制执行扫描执行政策的场景。启用后,此设置在目标分支缺少扫描产物且扫描执行政策要求扫描时,使批准规则可选。此功能仅在现有的扫描执行政策与匹配的扫描仪配合使用时有效。在某些安全扫描无法执行的情况下,在合并请求过程中提供灵活性。

安全机器人评论中的 Target: none {#target:-none-in-security-bot-comments}#

如果您在安全机器人评论中看到 Target: none,这意味着极狐GitLab 无法找到目标分支的安全报告。为了解决此问题:

  1. 在目标分支上运行包含所需安全扫描仪的流水线。
  2. 确保流水线成功完成并生成安全报告。
  3. 在源分支上重新运行流水线。创建新提交也会触发流水线重新运行。

安全机器人消息#

当目标分支没有安全扫描时:

  • 安全机器人可能会列出源分支中发现的所有漏洞。
  • 一些漏洞可能已经存在于目标分支中,但没有目标分支扫描,极狐GitLab 无法确定哪些是新的。

潜在解决方案:

  1. 手动批准:在新项目中暂时手动批准合并请求,直到建立安全扫描。
  2. 有针对性的政策:为新项目创建不同批准要求的单独政策。
  3. 回退行为:考虑对新项目使用 fail: open,但请注意这可能允许用户合并漏洞,即使扫描失败。

合并请求批准政策调试的支持请求#

JihuLab.com#

支持团队将调查 日志 (pubsub-sidekiq-inf-gprd*) 以识别失败 reason。以下是日志中响应片段的示例。您可以使用此查询来查找与批准相关的日志:json.event.keyword: "update_approvals"json.project_path: "group-path/project-path"。可选地,您可以进一步通过合并请求标识符使用 json.merge_request_iid 进行过滤:

json
1"json": { 2 "project_path": "group-path/project-path", 3 "merge_request_iid": 2, 4 "missing_scans": [ 5 "api_fuzzing" 6 ], 7 "reason": "Scanner removed by MR", 8 "event": "update_approvals", 9}

极狐GitLab 私有化部署#

搜索关键字,例如 project-pathapi_fuzzingmerge_request。示例:grep group-path/project-path,以及 grep merge_request。如果您知道相关 ID,您可以按相关 ID 搜索。例如,如果 correlation_id 的值为 01HWN2NFABCEDFG,搜索 01HWN2NFABCEDFG。 在以下文件中搜索:

  • /gitlab/gitlab-rails/production_json.log
  • /gitlab/sidekiq/current

常见失败原因:

  • 扫描仪被合并请求移除:合并请求批准政策期望在政策中定义的扫描仪存在,并且它们成功生成用于比较的产物。

来自合并请求批准政策的不一致批准#

如果您注意到合并请求批准规则中的任何不一致,可以采取以下步骤之一来重新同步您的政策:

  • 取消分配,然后重新分配安全政策项目到受影响的群组或项目。
  • 或者,您可以更新政策以触发该政策对受影响的群组或项目重新同步。
  • 确认安全政策项目中的 YAML 文件语法有效。

这些操作有助于确保您的合并请求批准政策正确应用并在所有合并请求中保持一致。

如果在采取这些步骤后您仍然遇到合并请求批准政策的问题,请联系极狐GitLab 支持以获取帮助。

修复检测到漏洞的合并请求需要批准#

如果您的政策配置包括 detected 状态,修复先前检测到漏洞的合并请求仍然需要批准。合并请求批准政策根据在合并请求中的更改之前存在的漏洞进行评估,这为任何影响已知漏洞的更改增加了额外的审核层。

如果您希望允许修复漏洞的合并请求在不需要任何额外批准的情况下继续进行,请考虑从您的政策配置中删除 detected 状态。