Add wildcard-to-wildcard pattern matching for MRAP
Summary
Implements wildcard-to-wildcard (pattern-to-pattern) matching for Merge Request Approval Policies (MRAP) branch targeting, behind the wildcard_pattern_overlap_for_mrap feature flag.
Problem: When an MRAP policy specifies branches: ["production-v1*"] and a project has a wildcard protected branch rule production-*, the system fails to associate them because it only matches patterns against literal branch names — never pattern-to-pattern. This means the policy won't generate approval rules for the matching protected branch unless literal branches happen to exist as intermediaries.
Solution: Added RefMatcher#overlaps? — a recursive algorithm with memoization that detects whether two *-glob patterns have overlapping match sets. Integrated into the MRAP sync pipeline so protected_branch_ids resolution directly compares policy patterns against protected branch rule patterns.
Related issue: #586351
Changes
| File | What |
|---|---|
app/models/ref_matcher.rb |
Added #overlaps? public method + private patterns_overlap? algorithm |
ee/app/services/security/scan_result_policies/approval_rules/base_service.rb |
Overlap check in protected_branch_ids, behind feature flag |
ee/app/services/security/security_orchestration_policies/base_project_policy_service.rb |
Same overlap check in approval_policy_protected_branch_ids |
config/feature_flags/development/wildcard_pattern_overlap_for_mrap.yml |
Feature flag definition |
spec/models/ref_matcher_spec.rb |
#overlaps? describe block |
spec/support/shared_examples/ref_matcher_shared_examples.rb |
24 shared examples (16 core + 8 symmetry) |
ee/spec/services/security/scan_result_policies/approval_rules/create_service_spec.rb |
4 integration tests |
How to test locally
Prerequisites
- GDK running with a project that has a security policy management project configured
- Enable the feature flag:
Feature.enable(:wildcard_pattern_overlap_for_mrap)
Test scenario 1: Pattern overlap (superset policy pattern)
- Create a new project
- Go to Code > Branches
- Click on New branch
- Add a branch called production-v1
- Go to Settings > Repository
- Expand the Protected branches section
- Click on Add protected branch
- Create a wildcard protected branch rule
production-* - Go to Secure > Policies
- Click on New policy
- Select Merge Request Approval Policy
- Create a policy like:
approval_policy:
- name: Wildcard test policy
description: ''
enabled: true
enforcement_type: enforce
rules:
- type: scan_finding
branches:
- "prod*"
scanners:
- container_scanning
vulnerabilities_allowed: 0
severity_levels:
- critical
vulnerability_states:
- detected
actions:
- type: require_approval
approvals_required: 1
role_approvers:
- developer
- type: send_bot_message
enabled: true - Click on Create a new project with the new policy
- Merge the MR to create the policy
- Wait for the policy to sync (or trigger manually via
Security::SyncScanPoliciesWorker.new.perform(project.id)) - Expected: An
ApprovalProjectRuleis created and linked to theproduction-*protected branch - Verify in Rails console:
project = Project.second_to_last
rule = project.approval_rules.last
rule.protected_branches.map(&:name)
# => ["production-*"]Test scenario 2: Subset policy pattern
- Same setup but use
branches: ["production-v1*"]in the policy - Expected: Still matches
production-*protected branch (becauseproduction-v1*is a subset ofproduction-*)
Test scenario 3: Non-overlapping patterns
- Same setup but use
branches: ["release/*"]in the policy - Expected: Does NOT match
production-*protected branch (different character at position 7:/vsu)
Test scenario 4: Feature flag disabled (regression)
- Disable the feature flag:
Feature.disable(:wildcard_pattern_overlap_for_mrap) - Repeat scenario 1
- Expected: Falls back to existing behavior — only matches if literal branches exist as intermediaries
Running specs
# Unit tests for the overlap algorithm
bundle exec rspec spec/models/ref_matcher_spec.rb
# Integration tests for the sync pipeline
bundle exec rspec ee/spec/services/security/scan_result_policies/approval_rules/create_service_spec.rb
# Existing service specs (regression)
bundle exec rspec ee/spec/services/security/security_orchestration_policies/base_project_policy_service_spec.rbFeature flag
wildcard_pattern_overlap_for_mrap — disabled by default. Enable to activate pattern-to-pattern overlap matching in MRAP branch targeting.