Support `fallback_behavior` for MR approval policies
What does this MR do and why?
Introduces the fallback_behavior
property to merge request approvals (&10816 (closed)):
The idea for MVC is quite simple:
- we add toggle to YAML mode only,
- with the toggle enabled (potentially something like
fallback_behavior: { fail: closed }
) we will behave as we are right now,- with the toggle disabled (potentially something like
fallback_behavior: { fail: open }
) we will not require approvals when policy or project is misconfigured,- we use
fallback_behavior: { fail: open }
format to allow for further extensions in the future, potentially we could have a list of scenarios where we want to have different scenarios or some exceptions, like we had for many previous features
From the description of this Epic we want to support these scenarios:
- Required scanners defined in the condition did not run or produce any artifacts.
- For scanners that require builds, when a project does not have a build pipeline.
- Required number of approvals became higher than available, valid approvers.
- When a security policy fails for an unspecified reason.
See &10816 (comment 1797964157)
Database queries
UPDATE
"approval_merge_request_rules"
SET
"approvals_required" = 0
WHERE
"approval_merge_request_rules"."id" IN (121649063, 121649062);
https://console.postgres.ai/gitlab/gitlab-production-main/sessions/27347/commands/85114
SELECT "approval_merge_request_rules".* FROM "approval_merge_request_rules" WHERE "approval_merge_request_rules"."merge_request_id" = 260129972;
https://console.postgres.ai/gitlab/gitlab-production-main/sessions/27374/commands/85192
DELETE FROM "scan_result_policy_violations"
WHERE "scan_result_policy_violations"."merge_request_id" = 260129972
AND "scan_result_policy_violations"."scan_result_policy_id" = 6686754;
https://console.postgres.ai/gitlab/gitlab-production-main/sessions/27347/commands/85119
SELECT
"approval_merge_request_rules".*
FROM
"approval_merge_request_rules"
WHERE
"approval_merge_request_rules"."merge_request_id" = 260129972
AND "approval_merge_request_rules"."report_type" = 4;
https://console.postgres.ai/gitlab/gitlab-production-main/sessions/27347/commands/85121
How to set up and validate locally
- Create a new project and enable the feature flag:
Feature.enable(:merge_request_approval_policies_fallback_behavior, Project.last)
-
Navigate to
Settings > CI/CD
and disableDefault to Auto DevOps pipeline
. -
Add a second
Owner
member to the project.
scan_finding
rules
Validating - Navigate to
Secure > Policies
and create the following approval policy:
type: approval_policy
name: Container Scanning Fail Closed
enabled: true
rules:
- type: scan_finding
scanners:
- container_scanning
vulnerabilities_allowed: 0
severity_levels: []
vulnerability_states: []
branch_type: protected
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- owner
-
Open a new MR that adds a new unrelated file.
-
Verify the
Container Scanning Fail Closed
rule requires approval (compare with bot comment). -
Navigate to
Secure > Policies
and create the following approval policy:
type: approval_policy
name: Container Scanning Fail Open
enabled: true
fallback_behavior:
fail: open
rules:
- type: scan_finding
scanners:
- container_scanning
vulnerabilities_allowed: 0
severity_levels: []
vulnerability_states: []
branch_type: protected
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- owner
-
Verify that:
-
Container Scanning Fail Closed
rule requires approval. -
Container Scanning Fail Open
rule doesn't require approval.
-
-
Commit the following
.gitlab-ci.yml
to the MR source branch:
container_scanning:
image: alpine
stage: test
allow_failure: true
artifacts:
reports:
container_scanning: gl-container-scanning-report.json
paths: [gl-container-scanning-report.json]
script:
- apk add curl
- curl -o gl-container-scanning-report.json https://gitlab.com/-/snippets/3690310/raw/main/gl-container-scanning-report-with-findings.json
-
Verify that both
Container Scanning Fail Closed
andContainer Scanning Fail Open
rules require approval. -
Navigate to
Secure > Policies
and edit the existingContainer Scanning Fail Open
to make it invalid:
type: approval_policy
name: Container Scanning Fail Open
enabled: true
fallback_behavior:
fail: open
rules:
- type: scan_finding
scanners:
- container_scanning
vulnerabilities_allowed: 0
severity_levels: []
vulnerability_states: []
branch_type: protected
actions:
- type: require_approval
- approvals_required: 1
+ approvals_required: 2
role_approvers:
- owner
-
Verify that:
-
Container Scanning Fail Closed
rule requires approval. -
Container Scanning Fail Open
rule doesn't require approval.
-
-
Update the existing
.gitlab-ci.yml
on the MR source branch so that there are no Container Scanning findings:
container_scanning:
image: alpine
stage: test
allow_failure: true
artifacts:
reports:
container_scanning: gl-container-scanning-report.json
paths: [gl-container-scanning-report.json]
script:
- apk add curl
- - curl -o gl-container-scanning-report.json https://gitlab.com/-/snippets/3690310/raw/main/gl-container-scanning-report-with-findings.json
+ - curl -o gl-container-scanning-report.json https://gitlab.com/-/snippets/3690310/raw/main/gl-container-scanning-report-without-findings.json
- Verify that:
- both
Container Scanning Fail Closed
andContainer Scanning Fail Open
rules don't require approval. - the bot comment notes that all policy violations were resolved.
- both
license_finding
rules
Validating - In the same project, navigate to
Secure > Policies
and create the following approval policy:
type: approval_policy
name: Deny MIT Fail Closed
enabled: true
rules:
- type: license_finding
match_on_inclusion: true
license_types:
- MIT
license_states:
- newly_detected
branch_type: protected
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- owner
-
Verify that:
- Only the
Deny MIT Fail Closed
rule requires approval. - the bot comment notes the policy violation.
- Only the
-
Navigate to
Secure > Policies
and create the following approval policy:
type: approval_policy
name: Deny MIT Fail Open
enabled: true
fallback_behavior:
fail: open
rules:
- type: license_finding
match_on_inclusion: true
license_types:
- MIT
license_states:
- newly_detected
branch_type: protected
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- owner
-
Verify that only the
Deny MIT Fail Closed
rule requires approval. -
Commit the following
Gemfile.lock
:
GEM
remote: https://rubygems.org/
specs:
rack (3.0.10)
PLATFORMS
arm64-darwin-22
ruby
DEPENDENCIES
rack
BUNDLED WITH
2.5.4
- Update the existing
.gitlab-ci.yml
and add Dependency Scanning:
+include:
+ - template: Jobs/Dependency-Scanning.gitlab-ci.yml
-
Verify that both the
Deny MIT Fail Closed
andDeny MIT Fail Open
rules require approval. -
Navigate to
Secure > Policies
and edit the existingDeny MIT Fail Open
rule to make it invalid::
type: approval_policy
name: Deny MIT Fail Open
enabled: true
fallback_behavior:
fail: open
rules:
- type: license_finding
match_on_inclusion: true
license_types:
- MIT
license_states:
- newly_detected
branch_type: protected
actions:
- type: require_approval
- approvals_required: 1
+ approvals_required: 2
role_approvers:
- owner
-
Verify that only the
Deny MIT Fail Closed
rule requires approval. -
Update the existing
Gemfile.lock
:
GEM
remote: https://rubygems.org/
specs:
PLATFORMS
arm64-darwin-22
ruby
DEPENDENCIES
BUNDLED WITH
2.5.4
- Verify that:
- No rule requires approval.
- the bot comment notes that all policy violations were resolved.
Validating MRs without pipelines
-
In the same project, open a new MR that adds a new unrelated file.
-
Verify that:
- Only the
Container Scanning Fail Closed
andDeny MIT Fail Closed
rules require approval. - the bot comment notes the policy violation.
- Only the
-
Navigate to
Secure > Policies
and disable both these policies. -
Verify that:
- No rule requires approval.
- the bot comment notes that all policy violations were resolved.
Related to #451784 (closed)