[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

  1. Create a project without a .gitlab-ci.yml file on the default branch (e.g., main)
  2. Ensure the project has no Dockerfile
  3. Configure a security approval policy (scan result policy) that enforces container scanning on the protected default branch
  4. Enable the unblock_rules_using_execution_policies policy tuning setting
  5. Create a merge request targeting the protected default branch (main)
  6. 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.yml file 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.yml file 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:

  1. 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.

  2. Option B: When using unblock_rules_using_execution_policies, the policy should allow the first .gitlab-ci.yml to be merged without requiring scanner jobs that cannot exist yet.

  3. 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_policies policy 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:

  1. 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
  2. Bootstrap detection: Implement logic to detect when a project is in a "bootstrap" state (no .gitlab-ci.yml on default branch) and adjust policy enforcement accordingly.

  3. 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
Edited by 🤖 GitLab Bot 🤖