扫描执行策略
- Tier: Ultimate
- Offering: GitLab.com, GitLab 自托管版, GitLab 专属版
使用扫描执行策略,可根据默认或最新的安全 CI/CD 模板强制执行 GitLab 安全扫描,作为流水线的一部分或在指定计划时间运行。
扫描执行策略在链接到安全策略项目且处于策略范围内的所有项目中强制执行。对于没有 .gitlab-ci.yml 文件或禁用 AutoDevOps 的项目,安全策略会隐式创建 .gitlab-ci.yml 文件。这确保了启用密钥检测、静态分析或其他不需要在项目中构建的扫描器的策略仍能运行并强制执行。
与流水线执行策略相比,扫描执行策略为在多个项目中配置 GitLab 安全扫描以管理安全和合规性提供了更快的路径。
如果满足以下任一情况,请改用流水线执行策略:
-
您需要高级配置设置。
-
您希望强制执行自定义 CI/CD 作业或脚本。
-
您希望通过强制执行的 CI/CD 作业启用第三方安全扫描。
-
视频演示,请参阅 如何在 GitLab 中设置安全扫描策略。
-
了解有关对无 GitLab CI/CD 配置的项目强制执行扫描执行策略的更多信息。
限制
- 每个策略最多可分配五个规则。
- 每个安全策略项目最多可分配五个扫描执行策略。
- 本地项目 YAML 文件不能覆盖扫描执行策略。这些策略优先于为流水线定义的任何配置,即使您在项目的 CI/CD 配置中使用相同的作业名称。
作业
扫描的策略作业(DAST 扫描除外)在流水线的 test 阶段创建。如果您从默认流水线中移除 test 阶段,作业将在 scan-policies 阶段运行。如果该阶段不存在,它会在评估时注入 CI/CD 流水线。如果存在 build 阶段,它会在 build 阶段之后注入,否则在流水线开头注入。DAST 扫描始终在 dast 阶段运行。如果此阶段不存在,则会在流水线末尾注入一个 dast 阶段。
为避免作业名称冲突,会在作业名称后附加连字符和数字。该数字对每个策略操作是唯一的。例如 secret-detection 变为 secret-detection-1。
扫描执行策略编辑器
使用扫描执行策略编辑器创建或编辑扫描执行策略。
先决条件:
- 默认情况下,只有组、子组或项目所有者拥有创建或分配安全策略项目所需的权限。或者,您可以创建具有管理安全策略链接权限的自定义角色。
创建第一个扫描执行策略时,我们会为您提供模板,以便快速开始处理最常见的用例:
-
Merge Request Security Template(合并请求安全模板)
- 用例:“我希望安全扫描仅在创建合并请求时运行,而不是每次提交都运行。”
- 适用场景:使用合并请求流水线且需要在目标默认分支或受保护分支上运行安全扫描的项目。
- 最适合:希望与合并请求审批策略保持一致,并通过避免在每个分支上扫描来降低基础设施成本的团队。
- 流水线来源:主要是合并请求流水线。
-
Scheduled Scanning Template(定时扫描模板)
- 用例:“我希望安全扫描按计划自动运行(如每天或每周),无论代码是否更改。”
- 适用场景:定期进行安全扫描,独立于开发活动。
- 最适合:合规要求、基线安全监控或提交频率低的项目。
- 流水线来源:定时流水线。
-
Merge Release Security Template(合并发布安全模板)
- 用例:“我希望安全扫描对我的
main或发布分支的所有更改运行。” - 适用场景:需要在发布前或受保护分支上进行全面扫描的项目。
- 最适合:发布门控工作流、生产部署或高安全环境。
- 流水线来源:推送到受保护分支的流水线、发布流水线。
- 用例:“我希望安全扫描对我的
如果可用模板不满足您的需求,或者您需要更定制的扫描执行策略,您可以:
- 选择 Custom(自定义) 选项,使用自定义要求创建您自己的扫描执行策略。
- 使用流水线执行策略访问更多可定制的安全扫描和 CI 强制执行选项。
策略完成后,在编辑器底部选择 Configure with a merge request(通过合并请求配置) 进行保存。您将被重定向到项目配置的安全策略项目的合并请求。如果没有链接到您的项目,将自动创建一个安全策略项目。也可以通过在编辑器底部选择 Delete policy(删除策略) 从编辑器界面删除现有策略,这将引入一个合并请求以从您的 policy.yml 文件中移除该策略。
大多数策略更改在合并请求合并后立即生效。任何不通过合并请求直接提交到默认分支的更改可能需要最多 10 分钟才能生效。
使用 DAST 执行策略的规则模式编辑器选择站点和扫描器配置文件,取决于策略是在项目级别还是组级别创建。对于项目级策略,规则模式编辑器提供已在项目中定义的配置文件列表供选择。对于组级策略,您需要输入要使用的配置文件名称,为防止流水线错误,组中所有项目必须存在匹配名称的配置文件。
扫描执行策略架构
包含扫描执行策略的 YAML 文件是一个对象数组,这些对象匹配嵌套在 scan_execution_policy 键下的扫描执行策略架构。您可以在 scan_execution_policy 键下配置最多 5 个策略。配置的前 5 个策略之外的任何其他策略都不会被应用。
保存新策略时,GitLab 会根据此 JSON 架构验证其内容。如果您不熟悉如何阅读 JSON 架构,以下章节和表格提供了替代方案。
| 字段 | 类型 | 必需 | 可能值 | 描述 |
|---|---|---|---|---|
scan_execution_policy |
扫描执行策略的 array |
true | 扫描执行策略列表(最多 5 个) |
扫描执行策略架构
每个策略操作限制的可用性由功能标志控制。有关更多信息,请参阅历史记录。
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
name |
string |
true | 策略名称。最多 255 个字符。 |
description |
string |
false | 策略描述。 |
enabled |
boolean |
true | 启用 (true) 或禁用 (false) 策略的标志。 |
rules |
array of rules |
true | 策略应用的规则列表。 |
actions |
array of actions |
true | 策略强制执行的操作列表。在 GitLab 18.0 及更高版本中限制为最多 10 个。 |
policy_scope |
policy_scope 的 object |
false | 根据您指定的项目、组或合规框架标签定义策略范围。 |
skip_ci |
skip_ci 的 object |
false | 定义用户是否可以应用 skip-ci 指令。 |
skip_ci 类型
扫描执行策略提供对谁可以使用 [skip ci] 指令的控制。您可以指定某些用户或服务账户允许使用 [skip ci],同时仍确保执行关键安全和合规检查。
使用 skip_ci 关键字指定用户是否允许应用 skip_ci 指令来跳过流水线。
当未指定关键字时,skip_ci 指令将被忽略,防止所有用户绕过流水线执行策略。
| 字段 | 类型 | 可能值 | 描述 |
|---|---|---|---|
allowed |
boolean |
true, false |
允许 (true) 或阻止 (false) 对具有强制流水线执行策略的流水线使用 skip-ci 指令的标志。 |
allowlist |
object |
users |
指定始终允许使用 skip-ci 指令的用户,无论 allowed 标志如何。使用 users: 后跟一个对象数组,其中 id 键代表用户 ID。 |
具有规则类型 schedule 的扫描执行策略始终忽略 skip_ci 选项。定时扫描在其配置的时间运行,无论最后一条提交消息中是否出现 [skip ci](或其任何变体)。这确保了安全扫描在可预测的时间运行,即使 CI/CD 流水线被跳过。
pipeline 规则类型
此功能的可用性由功能标志控制。有关更多信息,请参阅历史记录。
此规则在所选分支的流水线运行时强制执行定义的操作。
| 字段 | 类型 | 必需 | 可能值 | 描述 |
|---|---|---|---|---|
type |
string |
true | pipeline |
规则类型。 |
branches 1 |
string 的 array |
如果 branch_type 字段不存在则为必需 |
* 或分支名称 |
策略适用的分支(支持通配符)。为兼容合并请求审批策略,您应定位所有分支以包含功能分支和默认分支中的扫描 |
branch_type 1 |
string |
如果 branches 字段不存在则为必需 |
default, protected, all, target_default 2, 或 target_protected 2 |
策略适用的分支类型。 |
branch_exceptions |
string 的 array |
false | 分支名称 | 要从此规则中排除的分支。 |
pipeline_sources 2 |
string 的 array |
false | api, chat, external, external_pull_request_event, merge_request_event 3, pipeline, push 3, schedule, trigger, unknown, web |
触发扫描执行作业的流水线来源。更多信息请参阅文档。 |
- 您必须指定
branches或branch_type,但不能同时指定两者。 - 某些选项仅在启用
flexible_scan_execution功能标志时可用。详细信息请参阅历史记录。 - 当指定
branch_type选项target_default或target_protected时,pipeline_sources字段仅支持merge_request_event和push字段。
schedule 规则类型
在 GitLab 16.1 及更早版本中,您不应将直接传输与定时扫描执行策略一起使用。如果使用直接传输,请先升级到 GitLab 16.2 并确保在您强制执行的项目中启用安全策略机器人。
使用 schedule 规则类型按计划运行安全扫描器。
定时流水线:
- 仅运行策略中定义的扫描器,而不是项目
.gitlab-ci.yml文件中定义的作业。 - 根据
cadence字段中定义的计划运行。 - 在项目中的
security_policy_bot用户账户下运行,具有 Guest 角色和从 CI/CD 作业创建流水线及读取存储库内容的权限。该账户在策略链接到组或项目时创建。 - 在 GitLab.com 上,扫描执行策略中仅强制执行前 10 个
schedule规则。超出限制的规则无效。
| 字段 | 类型 | 必需 | 可能值 | 描述 |
|---|---|---|---|---|
type |
string |
true | schedule |
规则类型。 |
branches 1 |
string 的 array |
如果 branch_type 或 agents 字段不存在则为必需 |
* 或分支名称 |
策略适用的分支(支持通配符)。 |
branch_type 1 |
string |
如果 branches 或 agents 字段不存在则为必需 |
default, protected 或 all |
策略适用的分支类型。 |
branch_exceptions |
string 的 array |
false | 分支名称 | 要从此规则中排除的分支。 |
cadence |
string |
true | 选项受限的 Cron 表达式。例如,0 0 * * * 创建一个计划在每天午夜(12:00 AM)运行的定时任务。 |
包含五个字段(用空格分隔)的字符串,表示计划时间。 |
timezone |
string |
false | 时区标识符(例如 America/New_York) |
应用于 cadence 的时区。值必须是 IANA 时区数据库标识符。 |
time_window |
object |
false | 定时安全扫描的分布和持续时间设置。 | |
agents 1 |
object |
如果 branch_type 或 branches 字段不存在则为必需 |
GitLab agents for Kubernetes 的名称,用于运行运行时容器扫描。对象键是您在 GitLab 中为项目配置的 Kubernetes 代理的名称。 |
- 您只能指定
branches、branch_type或agents中的一个。
Cadence(计划)
使用 cadence 字段安排您希望策略操作运行的时间。cadence 字段使用 cron 语法,但有一些限制:
- 仅支持以下类型的 cron 语法:
- 每天在指定时间每小时运行一次,例如:
0 18 * * * - 每周在指定日期和时间运行一次,例如:
0 13 * * 0
- 每天在指定时间每小时运行一次,例如:
- 分钟和小时不支持使用逗号 (,)、连字符 (-) 或步进运算符 (/)。使用这些字符的任何定时流水线都将被跳过。
选择 cadence 字段的值时,请考虑以下因素:
- 时间基于 GitLab SaaS 的 UTC 和 GitLab 自托管版的主机系统时间。测试新策略时,流水线可能看起来运行不正常,但实际上它们是在您服务器的时间计划中运行的。
- 定时流水线在策略中提到的时间(当资源可用时)开始创建。换句话说,流水线可能不会在策略中指定的精确时间开始。
当使用带有 agents 字段的 schedule 规则类型时:
- GitLab Kubernetes 代理每 30 秒检查一次是否有适用的策略。找到策略后,根据定义的
cadence执行扫描。 - Cron 表达式使用 Kubernetes-agent pod 的系统时间进行评估。
当使用带有 branches 字段的 schedule 规则类型时:
- Cron 工作器以 15 分钟为间隔运行,并启动计划在之前 15 分钟内运行的任何流水线。因此,定时流水线可能延迟最多 15 分钟运行。
- 如果策略在大量项目或分支上强制执行,策略将分批处理,创建所有流水线可能需要一些时间。
agent 架构
使用此架构在 schedule 规则类型中定义 agents 对象。
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
namespaces |
string 的 array |
true | 要扫描的命名空间。如果为空,则扫描所有命名空间。 |
agent 示例
- name: Enforce Container Scanning in cluster connected through my-gitlab-agent for default and kube-system namespaces
enabled: true
rules:
- type: schedule
cadence: '0 10 * * *'
agents:
<agent-name>:
namespaces:
- 'default'
- 'kube-system'
actions:
- scan: container_scanning定时规则的键为:
cadence(必需):扫描运行的 Cron 表达式。agents:<agent-name>(必需):用于扫描的代理名称。agents:<agent-name>:namespaces(可选):要扫描的 Kubernetes 命名空间。如果省略,则扫描所有命名空间。
time_window 架构
使用 schedule 规则类型中的 time_window 对象定义定时扫描如何在时间上分布。您只能在策略编辑器的 YAML 模式下配置 time_window。
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
distribution |
string |
true | 定时扫描的分布模式。目前仅支持 random,扫描将在 time_window 的 value 键定义的间隔内随机分布。 |
value |
integer |
true | 定时扫描应运行的时间窗口(秒)。输入 3600(1 小时)到 86400(24 小时)之间的值。 |
time_window 示例
- name: Enforce Container Scanning with a time window of 1 hour
enabled: true
rules:
- type: schedule
cadence: '0 10 * * *'
time_window:
value: 3600
distribution: random
actions:
- scan: container_scanning优化大规模项目的定时流水线
在许多项目中启用定时扫描时,请考虑性能。
如果未启用 scan_execution_pipeline_concurrency_control 功能标志:
- 定时流水线同时在策略强制执行的所有项目和分支上运行。
- 每个项目中的第一个定时流水线执行创建一个安全机器人用户,负责在每个项目内执行计划。
为优化大规模项目的性能:
- 逐步推出定时扫描执行策略,从项目子集开始。您可以使用安全策略范围来定位特定的组、项目或包含给定合规框架标签的项目。
- 您可以将策略配置为在具有指定
tag的 runner 上运行计划。考虑在每个项目中设置专用的 runner 来处理从策略强制执行的计划,以减少对其他 runner 的影响。 - 在部署到生产环境之前,在暂存或较低环境中测试您的实现。监控性能并根据结果调整您的推出计划。
管理高容量定时流水线的额外改进计划在 Epic 13977 中。
并发控制
当满足以下条件时,GitLab 应用并发控制:
- 启用了
scan_execution_pipeline_concurrency_control功能标志 - 您设置了
time_window属性
并发控制根据策略中定义的 time_window 设置分配定时流水线。
scan 操作类型
此操作在满足定义策略中至少一个规则的条件时,执行选定的 scan 并附加参数。
| 字段 | 类型 | 可能值 | 描述 |
|---|---|---|---|
scan |
string |
sast, sast_iac, dast, secret_detection, container_scanning, dependency_scanning |
操作类型。 |
site_profile |
string |
选定的 DAST 站点配置文件 的名称。 | 要执行 DAST 扫描的 DAST 站点配置文件。仅当 scan 类型为 dast 时才应设置此字段。 |
scanner_profile |
string 或 null |
选定的 DAST 扫描器配置文件 的名称。 | 要执行 DAST 扫描的 DAST 扫描器配置文件。仅当 scan 类型为 dast 时才应设置此字段。 |
variables |
object |
要应用于并强制执行所选扫描的一组 CI/CD 变量,作为 key: value 对的数组提供。key 是变量名,其 value 作为字符串提供。此参数支持指定扫描的 GitLab CI/CD 作业支持的任何变量。 |
|
tags |
string 的 array |
策略的 runner 标签列表。策略作业由具有指定标签的 runner 运行。 | |
template |
string |
default, latest |
要强制执行的 CI/CD 模板版本。latest 版本可能引入破坏性更改。latest 版本仅支持与合并请求相关的 pipeline_sources;请参阅安全扫描文档。请参阅 stable 和 latest 安全模板。 |
scan_settings |
object |
要应用于并强制执行所选扫描的一组扫描设置,作为 key: value 对的数组提供。key 是设置名称,其 value 作为布尔值或字符串提供。此参数支持 scan settings 中定义的设置。 |
如果您的项目启用了合并请求流水线,您必须在每个强制执行的扫描策略中设置 AST_ENABLE_MR_PIPELINES CI/CD 变量为 "true"。有关使用合并请求流水线使用安全扫描工具的更多信息,请参阅安全扫描文档。
扫描器行为
某些扫描器在 scan 操作中的行为与在常规 CI/CD 流水线扫描中的行为不同。
- 静态应用程序安全测试 (SAST):仅当存储库包含受 SAST 支持的文件时才运行。
- 密钥检测:
- 默认情况下仅支持默认规则集中的规则。
- 要自定义规则集配置,可以:
- 修改默认规则集。使用扫描执行策略指定
SECRET_DETECTION_RULESET_GIT_REFERENCECI/CD 变量。默认情况下,这指向一个远程配置文件,它仅覆盖或禁用默认规则集中的规则。仅使用此变量不支持扩展或替换默认规则集。 - 扩展或替换默认规则集。使用扫描执行策略指定
SECRET_DETECTION_RULESET_GIT_REFERENCECI/CD 变量和使用Git 透传来扩展或替换默认规则集的远程配置文件。有关详细指南,请参阅如何设置集中管理的流水线密钥检测配置。
- 修改默认规则集。使用扫描执行策略指定
- 对于
scheduled扫描执行策略,密钥检测默认首先以historic模式运行(SECRET_DETECTION_HISTORIC_SCAN=true)。所有后续定时扫描以默认模式运行,SECRET_DETECTION_LOG_OPTIONS设置为上次运行和当前 SHA 之间的提交范围。您可以通过在扫描执行策略中指定 CI/CD 变量来覆盖此行为。有关更多信息,请参阅完整历史流水线密钥检测。 - 对于
triggered扫描执行策略,密钥检测的工作方式与在.gitlab-ci.yml中手动配置的常规扫描相同。
- 容器扫描:为
pipeline规则类型配置的扫描会忽略agents对象中定义的代理。agents对象仅考虑schedule规则类型。必须在项目中创建并配置名称在agents对象中提供的代理。
DAST 配置文件
强制执行动态应用程序安全测试 (DAST) 时,适用以下要求:
- 对于策略范围内的每个项目,指定的站点配置文件和扫描器配置文件必须存在。如果这些不可用,则不应用策略,而是创建一个带有错误消息的作业。
- 当在启用的扫描执行策略中命名 DAST 站点配置文件或扫描器配置文件时,无法修改或删除该配置文件。要编辑或删除配置文件,您必须首先在策略编辑器中将策略设置为 Disabled,或在 YAML 模式下设置
enabled: false。 - 配置具有定时 DAST 扫描的策略时,安全策略项目存储库中提交的作者必须有权访问扫描器和站点配置文件。否则,扫描将无法成功计划。
扫描设置
scan_settings 参数支持以下设置:
| 设置 | 类型 | 必需 | 可能值 | 默认 | 描述 |
|---|---|---|---|---|---|
ignore_default_before_after_script |
boolean |
false | true, false |
false |
指定是否从扫描作业中排除流水线配置中的任何默认 before_script 和 after_script 定义。 |
CI/CD 变量
不要将敏感信息或凭据存储在变量中,因为它们作为纯文本策略配置存储在 Git 存储库中。
扫描执行策略中定义的变量遵循标准 CI/CD 变量优先级。
在任何应用了扫描执行策略的项目上,以下 CI/CD 变量使用预配置值。它们的值可以被覆盖,但仅当它们在策略中声明时。它们不能被组或项目 CI/CD 变量覆盖:
DS_EXCLUDED_PATHS: spec, test, tests, tmp
SAST_EXCLUDED_PATHS: spec, test, tests, tmp
SECRET_DETECTION_EXCLUDED_PATHS: ''
SECRET_DETECTION_HISTORIC_SCAN: false
SAST_EXCLUDED_ANALYZERS: ''
DEFAULT_SAST_EXCLUDED_PATHS: spec, test, tests, tmp
DS_EXCLUDED_ANALYZERS: ''
SECURE_ENABLE_LOCAL_CONFIGURATION: true在 GitLab 16.9 及更早版本中:
- 如果在策略中声明了后缀为
_EXCLUDED_PATHS的 CI/CD 变量,它们的值可以被组或项目 CI/CD 变量覆盖。 - 如果在策略中声明了后缀为
_EXCLUDED_ANALYZERS的 CI/CD 变量,无论它们在何处定义(策略、组或项目),它们的值都会被忽略。
策略范围架构
要自定义策略强制执行,您可以定义策略的范围以包含或排除指定的项目、组或合规框架标签。更多详细信息,请参阅范围。
示例安全策略项目
您可以在存储在安全策略项目中的 .gitlab/security-policies/policy.yml 文件中使用此示例:
---
scan_execution_policy:
- name: Enforce DAST in every release pipeline
description: This policy enforces pipeline configuration to have a job with DAST scan for release branches
enabled: true
rules:
- type: pipeline
branches:
- release/*
actions:
- scan: dast
scanner_profile: Scanner Profile A
site_profile: Site Profile B
- name: Enforce DAST and secret detection scans every 10 minutes
description: This policy enforces DAST and secret detection scans to run every 10 minutes
enabled: true
rules:
- type: schedule
branches:
- main
cadence: "*/10 * * * *"
actions:
- scan: dast
scanner_profile: Scanner Profile C
site_profile: Site Profile D
- scan: secret_detection
scan_settings:
ignore_default_before_after_script: true
- name: Enforce Secret Detection and Container Scanning in every default branch pipeline
description: This policy enforces pipeline configuration to have a job with Secret Detection and Container Scanning scans for the default branch
enabled: true
rules:
- type: pipeline
branches:
- main
actions:
- scan: secret_detection
- scan: sast
variables:
SAST_EXCLUDED_ANALYZERS: brakeman
- scan: container_scanning在此示例中:
- 对于在匹配
release/*通配符的分支(例如分支release/v1.2.1)上执行的每个流水线- DAST 扫描使用
Scanner Profile A和Site Profile B运行。
- DAST 扫描使用
- DAST 和密钥检测扫描每 10 分钟运行一次。DAST 扫描使用
Scanner Profile C和Site Profile D运行。 - Secret detection、容器扫描和 SAST 扫描为在
main分支上执行的每个流水线运行。SAST 扫描以SAST_EXCLUDED_ANALYZER变量设置为"brakeman"运行。
扫描执行策略编辑器示例
您可以在扫描执行策略编辑器的 YAML 模式下使用此示例。它对应于前一个示例中的单个对象。
name: Enforce Secret Detection and Container Scanning in every default branch pipeline
description: This policy enforces pipeline configuration to have a job with Secret Detection and Container Scanning scans for the default branch
enabled: true
rules:
- type: pipeline
branches:
- main
actions:
- scan: secret_detection
- scan: container_scanning避免重复扫描
如果开发人员在项目的 .gitlab-ci.yml 文件中包含扫描作业,扫描执行策略可能导致同一类型的扫描器运行多次。此行为是故意的,因为扫描器可以多次运行,具有不同的变量和设置。例如,开发人员可能希望尝试使用不同于安全和合规团队强制执行的变量运行 SAST 扫描。在这种情况下,两个 SAST 作业在流水线中运行,一个使用开发人员的变量,一个使用安全和合规团队的变量。
如果您想避免运行重复扫描,可以删除项目 .gitlab-ci.yml 文件中的扫描,或使用变量跳过本地作业。跳过作业不会阻止扫描执行策略定义的任何安全作业运行。
要使用变量跳过扫描作业,您可以使用:
SAST_DISABLED: "true"跳过 SAST 作业。DAST_DISABLED: "true"跳过 DAST 作业。CONTAINER_SCANNING_DISABLED: "true"跳过容器扫描作业。SECRET_DETECTION_DISABLED: "true"跳过密钥检测作业。DEPENDENCY_SCANNING_DISABLED: "true"跳过依赖项扫描作业。
有关可以跳过作业的所有变量的概述,请参阅 CI/CD 变量文档。