Use new auth filter in merge requests

Description

The merge request query builder uses the legacy authorization filter by_project_authorization. This is known to produce large, inefficient global and group Elasticsearch queries.

Proposal

Change the query builder to use by_search_level_and_membership filter and update specs accordingly. This should be introduced behind a feature flag.


Technical Implementation Details

Current Implementation

The merge request query builder is located at ee/lib/search/elastic/merge_request_query_builder.rb and currently uses the deprecated by_project_authorization filter on line 18:

query_hash = ::Search::Elastic::Filters.by_project_authorization(query_hash: query_hash, options: options)

Required Changes

1. Replace Authorization Filter

Replace the deprecated by_project_authorization call with the new by_search_level_and_membership filter:

Before:

query_hash = ::Search::Elastic::Filters.by_project_authorization(query_hash: query_hash, options: options)

After:

query_hash = ::Search::Elastic::Filters.by_search_level_and_membership(query_hash: query_hash, options: options)

2. Feature Flag Implementation

Create an EE feature flag following the GitLab feature flag process:

  • Flag name: search_advanced_merge_requests_new_auth_filter
  • Type: gitlab_com_derisk (for de-risking the rollout of this authorization filter replacement)
  • Default state: disabled
  • Group: group::global search
  • EE: true (this is an EE-only feature flag for Advanced Search)

Use bin/feature-flag to generate the feature flag definition and specify it as an EE flag:

bin/feature-flag search_advanced_merge_requests_new_auth_filter --ee

3. Conditional Logic

Wrap the authorization filter call with feature flag logic:

if Feature.enabled?(:search_advanced_merge_requests_new_auth_filter, options[:current_user])
  query_hash = ::Search::Elastic::Filters.by_search_level_and_membership(query_hash: query_hash, options: options)
else
  query_hash = ::Search::Elastic::Filters.by_project_authorization(query_hash: query_hash, options: options)
end

4. Update Specs

Update the corresponding spec file at ee/spec/lib/search/elastic/merge_request_query_builder_spec.rb to:

  • Test both code paths (feature flag enabled and disabled)
  • Verify that the new filter produces correct authorization queries
  • Ensure backward compatibility when the feature flag is disabled
  • Add test cases for different search levels (global, group, project)

Reference existing specs for by_search_level_and_membership at ee/spec/lib/search/elastic/filters_spec.rb (starting around line 3049) for test patterns.

Context

The by_search_level_and_membership filter (defined in ee/lib/search/elastic/filters.rb starting at line 48) is the modern replacement for by_project_authorization (marked as deprecated at line 976). The new filter:

  • Produces more efficient Elasticsearch queries
  • Properly handles search levels (global, group, project)
  • Uses traversal IDs for better performance
  • Includes proper visibility and membership checks

Acceptance Criteria

  • EE feature flag search_advanced_merge_requests_new_auth_filter is created with proper metadata
  • Authorization filter is replaced with conditional logic based on feature flag
  • Specs are updated to test both code paths
  • All existing merge request search functionality works with the new filter
  • Performance improvements are measurable (reduced query size/complexity)
  • Documentation is updated if needed
Edited by 🤖 GitLab Bot 🤖