Add PEP/SEP mergeability check for security policy pipeline status

What does this MR do and why?

Adds a new PEP/SEP-scoped mergeability check (security_policy_pipeline_check) that ensures all pipelines for the latest commit must succeed before a merge request can be merged when security policies are enforced.

image

Problem

When Pipeline Execution Policies (PEP) or Scan Execution Policies (SEP) inject security scans into MR pipelines, projects with existing branch pipelines end up with duplicate pipelines. The existing mergeability check only evaluates the MR pipeline (which includes the security scans), completely ignoring the branch pipeline where functional tests may be failing. This allows broken code to be merged even when branch pipelines are red.

Solution

Introduces a new CheckSecurityPolicyPipelineStatusService mergeability check that:

  • Activates only when the project has security_orchestration_policies license, has PEP/SEP policy configurations (scoped to type_scan_execution_policy or type_pipeline_execution_policy to avoid activating for projects with only approval or vulnerability management policies), and at least one internal pipeline exists for the latest MR commit
  • Excludes external pipelines (created via the Commit Status API) to prevent bypassing the security policy check by setting a commit status to success (see #535437)
  • Evaluates both the latest MR pipeline (merge_request_event source) and the latest branch pipeline (all other sources) for the HEAD SHA
  • Supports merged results pipelines by using for_sha_or_source_sha to match pipelines where the SHA is a merge commit but source_sha is the branch HEAD
  • Blocks or warns based on the project's "Pipelines must succeed" setting:
    • Setting enabled: hard block (failure) if any evaluated pipeline fails
    • Setting disabled: soft warning if any evaluated pipeline fails, user can still merge
  • Respects the "Skipped pipelines are considered successful" setting (allow_merge_on_skipped_pipeline), consistent with CheckCiStatusService
  • Waits (returns checking) if any evaluated pipeline is still active
  • Is non-cacheable since pipeline statuses change dynamically
  • Is skipped during auto-merge flows via skip_security_policy_pipeline_check
  • Is gated behind a feature flag security_policy_pipeline_check (disabled by default)

Changes

  • New service: ee/app/services/merge_requests/mergeability/check_security_policy_pipeline_status_service.rb - core mergeability check logic
  • New scope: with_security_policy_jobs on Ci::Pipeline to efficiently query pipelines that have policy-injected builds
  • MR model: registers the new check in mergeable_state_checks and adds skip_security_policy_pipeline_check to auto-merge skip options
  • GraphQL: new SECURITY_POLICY_PIPELINE_CHECK enum value in DetailedMergeStatusEnum and MergeabilityCheckIdentifier
  • Feature flag: security_policy_pipeline_check (gitlab_com_derisk, disabled by default)
  • Docs & schema: updated GraphQL reference docs and introspection JSON

Note: Frontend changes (merge check component, contextual pipeline note, CSS, and frontend constants) have been removed from this MR and will be handled separately.

References

Closes #589650

How to set up and validate locally

  1. Enable the security_orchestration_policies license feature
  2. Enable the security_policy_pipeline_check feature flag
  3. Create a project with a PEP or SEP policy configuration
  4. Open a merge request and trigger a pipeline that has policy-injected jobs
  5. Observe the new SECURITY_POLICY_PIPELINE_CHECK mergeability check identifier via the GraphQL API
  6. Verify that a failing branch pipeline blocks (or warns on) the merge, even when the MR pipeline succeeds

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Alan (Maciej) Paruszewski

Merge request reports

Loading