[DRAFT] - MR blocked by security approval policy when project has no .gitlab-ci.yml on default branch
Summary
Merge requests are incorrectly blocked by security approval policies when the target project does not contain a .gitlab-ci.yml file on the default branch and has no Dockerfile. This creates a deadlock situation where teams cannot merge their first CI configuration without first having a CI configuration in place.
Steps to reproduce
- Create a project without a
.gitlab-ci.ymlfile on the default branch (e.g.,main) - Ensure the project has no Dockerfile
- Configure a security approval policy (scan result policy) that enforces container scanning on the protected default branch
- Enable the
unblock_rules_using_execution_policiespolicy tuning setting - Create a merge request targeting the protected default branch (
main) - Observe that the merge request is blocked
Example Project
Please provide a link to a minimal reproduction project if possible
What is the current bug behavior?
When a merge request is opened against the protected default branch, the approval policy enforces various security scanners (especially container scanning). Because the target branch lacks a .gitlab-ci.yml file, the corresponding Container Scanning scanner job is missing. GitLab incorrectly interprets this missing scanner as a failure, and the merge request becomes blocked.
This creates a deadlock:
- Projects without a
.gitlab-ci.ymlfile on the target branch will have all MRs blocked - Teams operating under compliance policies cannot bypass enforcement by first merging potentially non-compliant changes into main
- Disabling policies is not an option for compliance-governed teams
- The only workaround is to add a dummy
.gitlab-ci.ymlfile to the protected branch, which should not be required
What is the expected correct behavior?
When a project does not have a .gitlab-ci.yml file on the default branch:
-
Option A (Preferred): Security approval policies should recognize that container scanning is not applicable to projects without containers/Dockerfiles, and should not block the merge request based on missing scanner jobs that are irrelevant to the project type.
-
Option B: When using
unblock_rules_using_execution_policies, the policy should allow the first.gitlab-ci.ymlto be merged without requiring scanner jobs that cannot exist yet. -
Option C: Provide a clear mechanism for bootstrapping CI configuration in compliance-governed projects without creating a deadlock situation.
The expected behavior is that teams can merge their initial CI configuration without being blocked by policies that require scanners which cannot run without that CI configuration.
Relevant logs and/or screenshots
Please provide screenshots of the blocked MR, policy configuration, and any error messages
Output of checks
Environment Information
GitLab Version: Please specify (e.g., 17.5.1)
Deployment Type:
-
GitLab.com (SaaS) -
GitLab Self-Managed -
GitLab Dedicated
Policy Configuration:
- Using
unblock_rules_using_execution_policiespolicy tuning: Yes - Security scanners enforced: Container Scanning (and possibly others)
- Branch type: Protected default branch (
main)
Results of GitLab environment info
Expand for output related to GitLab environment info
(For installations with omnibus-gitlab package run and paste the output of: `sudo gitlab-rake gitlab:env:info`) (For installations from source run and paste the output of: `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)
Results of GitLab application Check
Expand for output related to the GitLab application check
(For installations with omnibus-gitlab package run and paste the output of: `sudo gitlab-rake gitlab:check SANITIZE=true`) (For installations from source run and paste the output of: `sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true`) (we will only investigate if the tests are passing)
Possible fixes
The issue appears to be in how security approval policies evaluate missing scanner jobs when unblock_rules_using_execution_policies is enabled. Potential areas to investigate:
-
Policy evaluation logic: The policy engine should distinguish between:
- Scanner jobs that failed (actual security concern)
- Scanner jobs that are missing because no CI configuration exists yet (bootstrap scenario)
- Scanner jobs that are missing because they're not applicable to the project type
-
Bootstrap detection: Implement logic to detect when a project is in a "bootstrap" state (no
.gitlab-ci.ymlon default branch) and adjust policy enforcement accordingly. -
Scanner applicability: Improve detection of whether specific scanners (like container scanning) are applicable to a given project based on project contents (presence of Dockerfile, container images, etc.).
Related Issues
- #389873 - Security Scanning Observations (general security policy issues)
- #560563 (closed) - MR Approval Policy does not get re-evaluated after vulnerability state is changed
Additional Context
Workaround: Adding a dummy .gitlab-ci.yml file to the protected branch allows subsequent merge requests to succeed, but this workaround:
- Requires bypassing compliance policies temporarily
- Creates a chicken-and-egg problem for new projects
- Is not acceptable for compliance-governed teams who cannot disable policies
Impact: This issue prevents teams from:
- Bootstrapping CI/CD in new projects under compliance governance
- Migrating existing projects to security policies without manual intervention
- Following security best practices while maintaining operational efficiency