Allow MRAP bypass_settings to override protected branch restrictions

What does this MR do and why?

This MR extends the bypass_settings functionality in Merge Request Approval Policies (MRAP) to allow authorized users, groups, roles, or access tokens to bypass both security policy push protection and protected branch restrictions.

Problem

Currently, bypass_settings only bypasses push protection enforced by the security policy itself (via prevent_pushing_and_force_pushing: true), but cannot bypass restrictions configured at the protected branch level (e.g., "Allowed to push and merge" set to "No One"). This creates a confusing user experience where bypass_settings appears to be partially functional.

Solution

When bypass_settings is configured, authorized users/tokens can now push directly to protected branches regardless of the branch's "Allowed to push and merge" configuration, provided they supply a valid security_policy.bypass_reason. This behavior is automatic when bypass_settings is present - no additional configuration is required.

Example configuration:

approval_policy:
  - name: Strict Approval Policy
    enabled: true
    rules:
      - type: any_merge_request
        branch_type: protected
    actions:
      - type: require_approval
        approvals_required: 2
    approval_settings:
      prevent_pushing_and_force_pushing: true
    bypass_settings:
      users:
        - id: 123
      access_tokens:
        - id: 456

Key changes

  1. BypassSettings class: Updated to support protected branch restriction bypass
  2. ProtectedBranchBypassChecker: New service that checks if a user is authorized to bypass protected branch restrictions based on security policies
  3. ProtectedBranchBypassAuditor: New service that logs audit events when protected branch restrictions are bypassed
  4. BranchCheck override: Extended Gitlab::Checks::BranchCheck to skip protected branch checks when bypass is allowed

Security safeguards

  • Audit logging: All bypass events are logged with full details including project, user, branch, policy name, and bypass reason
  • Bypass reason required: Users must provide a security_policy.bypass_reason push option
  • Input sanitization: Bypass reasons are sanitized to prevent XSS

How to test

Setup

  1. Create a project with a protected branch (e.g., main)
  2. Enable security_policy_protected_branch_bypass feature flag
  3. Set the protected branch's "Allowed to push and merge" to "No One"
  4. Create a security policy project and link it to your test project
  5. Create an approval policy with bypass_settings that includes your test user:
    approval_policy:
      - name: Test Bypass Policy
        enabled: true
        rules:
          - type: any_merge_request
            branch_type: protected
        actions:
          - type: require_approval
            approvals_required: 1
        approval_settings:
          prevent_pushing_and_force_pushing: true
        bypass_settings:
          users:
            - id: <your_user_id>

Test cases

1. Authorized user can bypass with valid reason

git commit --allow-empty -m "Test bypass"
git push -o security_policy.bypass_reason="Emergency hotfix for production issue" origin HEAD:main

Expected: Push succeeds, audit event is logged

2. Authorized user cannot bypass without reason

git commit --allow-empty -m "Test bypass"
git push origin HEAD:main

Expected: Push is rejected with error message requiring bypass reason

3. Unauthorized user cannot bypass even with reason

# As a user NOT listed in bypass_settings
git push -o security_policy.bypass_reason="Trying to bypass" origin HEAD:main

Expected: Push is rejected due to protected branch restrictions

4. Verify audit logging

  • Navigate to the security policy project's Secure > Audit events
  • Confirm bypass events are logged with user, branch, policy name, and bypass reason

References

Closes #585040

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.

Merge request reports

Loading