Skip to content

added filter to both pagination strategies#20616

Open
ThyTran1402 wants to merge 4 commits intoopensearch-project:mainfrom
ThyTran1402:fix/_list_indices_api_in_3.2
Open

added filter to both pagination strategies#20616
ThyTran1402 wants to merge 4 commits intoopensearch-project:mainfrom
ThyTran1402:fix/_list_indices_api_in_3.2

Conversation

@ThyTran1402
Copy link

@ThyTran1402 ThyTran1402 commented Feb 12, 2026

Description

  • The _list/indices API fails with permission errors when system indices exist in the cluster, even for users with all_access role. The _cat/indices API works fine for the same user.
  • Fixed by using the security-filtered GetSettingsResponse (which only contains indices the user is authorized to access) as an authorization filter when building the pagination strategy. This ensures IndexPaginationStrategy only selects indices the user has permission to view, so the downstream IndicesStatsRequest and ClusterHealthRequest sub-requests never reference unauthorized system indices.

Related Issues

Resolves #20291

Check List

  • Functionality includes testing.
  • API changes companion pull request created, if applicable.
  • Public documentation issue/PR created, if applicable.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Signed-off-by: Thy Tran <58045538+ThyTran1402@users.noreply.github.com>
@ThyTran1402 ThyTran1402 requested a review from a team as a code owner February 12, 2026 20:49
@github-actions github-actions bot added API Issues with external APIs bug Something isn't working labels Feb 12, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The changes introduce authorization filtering to the pagination strategy for indices listing APIs. A new constructor and method signature variations add support for an authorization filter predicate, enabling pagination to respect authorized indices. REST action implementations now extract authorization information from settings responses and pass it to the pagination strategy.

Changes

Cohort / File(s) Summary
Core Pagination Logic
server/src/main/java/org/opensearch/action/pagination/IndexPaginationStrategy.java
New constructor added accepting authorizationFilter predicate; existing constructor delegates to it with permissive filter. getEligibleIndices updated to compose pagination and authorization filters. getMetadataFilter adjusted to return permissive filter when pagination tokens are absent.
REST Endpoint Updates
server/src/main/java/org/opensearch/rest/action/cat/RestIndicesAction.java, server/src/main/java/org/opensearch/rest/action/list/RestIndicesListAction.java
Both update getPaginationStrategy signature to accept GetSettingsResponse. RestIndicesListAction additionally extracts authorized indices from settings and constructs authorization filter, whereas RestIndicesAction passes parameter without modification.
Pagination Tests
server/src/test/java/org/opensearch/action/pagination/IndexPaginationStrategyTests.java
Tests added for filtered pagination scenarios with authorization predicates. Validates excluded unauthorized indices, correct ordering under filters, and pagination token behavior across filtered result sets.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 3
❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (50 files):

⚔️ .github/benchmark-configs.json (content)
⚔️ .github/workflows/benchmark-pull-request.yml (content)
⚔️ .github/workflows/gradle-check.yml (content)
⚔️ .github/workflows/lucene-snapshots.yml (content)
⚔️ .github/workflows/publish-maven-snapshots.yml (content)
⚔️ README.md (content)
⚔️ gradle/libs.versions.toml (content)
⚔️ libs/netty4/build.gradle (content)
⚔️ modules/transport-netty4/build.gradle (content)
⚔️ plugins/arrow-flight-rpc/build.gradle (content)
⚔️ plugins/arrow-flight-rpc/src/main/java/org/opensearch/arrow/flight/bootstrap/ServerConfig.java (content)
⚔️ plugins/arrow-flight-rpc/src/main/java/org/opensearch/arrow/flight/transport/FlightStreamPlugin.java (content)
⚔️ plugins/arrow-flight-rpc/src/main/java/org/opensearch/arrow/flight/transport/FlightTransport.java (content)
⚔️ plugins/arrow-flight-rpc/src/test/java/org/opensearch/arrow/flight/bootstrap/ServerConfigTests.java (content)
⚔️ plugins/ingestion-kinesis/build.gradle (content)
⚔️ plugins/repository-s3/build.gradle (content)
⚔️ plugins/transport-reactor-netty4/build.gradle (content)
⚔️ plugins/workload-management/src/internalClusterTest/java/org/opensearch/plugin/wlm/WlmAutoTaggingIT.java (content)
⚔️ plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/AutoTaggingActionFilter.java (content)
⚔️ plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/AutoTaggingActionFilterTests.java (content)
⚔️ server/src/main/java/org/opensearch/action/pagination/IndexPaginationStrategy.java (content)
⚔️ server/src/main/java/org/opensearch/action/search/AbstractSearchAsyncAction.java (content)
⚔️ server/src/main/java/org/opensearch/action/search/ParsedScrollId.java (content)
⚔️ server/src/main/java/org/opensearch/action/search/SearchRequestSlowLog.java (content)
⚔️ server/src/main/java/org/opensearch/action/search/SearchScrollRequest.java (content)
⚔️ server/src/main/java/org/opensearch/action/search/TransportSearchHelper.java (content)
⚔️ server/src/main/java/org/opensearch/action/search/TransportSearchScrollAction.java (content)
⚔️ server/src/main/java/org/opensearch/cluster/metadata/WorkloadGroup.java (content)
⚔️ server/src/main/java/org/opensearch/common/settings/FeatureFlagSettings.java (content)
⚔️ server/src/main/java/org/opensearch/common/util/FeatureFlags.java (content)
⚔️ server/src/main/java/org/opensearch/index/CriteriaBasedMergePolicy.java (content)
⚔️ server/src/main/java/org/opensearch/index/codec/CriteriaBasedCodec.java (content)
⚔️ server/src/main/java/org/opensearch/index/mapper/RangeFieldMapper.java (content)
⚔️ server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java (content)
⚔️ server/src/main/java/org/opensearch/index/shard/IndexShard.java (content)
⚔️ server/src/main/java/org/opensearch/node/Node.java (content)
⚔️ server/src/main/java/org/opensearch/rest/action/cat/RestIndicesAction.java (content)
⚔️ server/src/main/java/org/opensearch/rest/action/list/RestIndicesListAction.java (content)
⚔️ server/src/main/resources/META-INF/services/org.apache.lucene.codecs.Codec (content)
⚔️ server/src/main/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat (content)
⚔️ server/src/test/java/org/opensearch/action/pagination/IndexPaginationStrategyTests.java (content)
⚔️ server/src/test/java/org/opensearch/action/search/ParsedScrollIdTests.java (content)
⚔️ server/src/test/java/org/opensearch/action/search/SearchRequestSlowLogTests.java (content)
⚔️ server/src/test/java/org/opensearch/action/search/SearchScrollAsyncActionTests.java (content)
⚔️ server/src/test/java/org/opensearch/cluster/metadata/WorkloadGroupTests.java (content)
⚔️ server/src/test/java/org/opensearch/index/CriteriaBasedMergePolicyTests.java (content)
⚔️ server/src/test/java/org/opensearch/index/engine/InternalEngineTests.java (content)
⚔️ server/src/test/java/org/opensearch/index/mapper/RangeFieldMapperTests.java (content)
⚔️ server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java (content)
⚔️ test/fixtures/hdfs-fixture/build.gradle (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
Title check ❓ Inconclusive The title is vague and generic, using non-descriptive phrasing that doesn't convey the specific security or authorization context of the changes. Revise the title to be more specific, such as 'Add authorization filtering to pagination strategies' or 'Fix _list/indices API with authorization-aware pagination filters'.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The code changes fully address issue #20291 by implementing authorization filtering in both pagination strategies to prevent unauthorized index access.
Out of Scope Changes check ✅ Passed All changes directly support the authorization filtering objective: IndexPaginationStrategy adds authorization parameter, both RestIndicesAction and RestIndicesListAction integrate GetSettingsResponse filtering, and tests validate the new behavior.
Description check ✅ Passed The pull request description comprehensively addresses the issue, provides clear context about the problem and solution, includes a related issue reference, and confirms testing and DCO compliance.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/src/main/java/org/opensearch/action/pagination/IndexPaginationStrategy.java (1)

76-86: ⚠️ Potential issue | 🟡 Minor

Filter composition is correct but consider null-safety for the authorizationFilter parameter.

The paginationFilter.and(authorizationFilter) composition at Line 85 correctly applies both filters. However, if a caller passes null for authorizationFilter, this will throw a NullPointerException at the .and() call. The 2-arg constructor always passes metadata -> true, but the public 3-arg constructor at Line 51 doesn't guard against null.

🛡️ Proposed fix to add null guard
 public IndexPaginationStrategy(PageParams pageParams, ClusterState clusterState, Predicate<IndexMetadata> authorizationFilter) {
+    Objects.requireNonNull(authorizationFilter, "authorizationFilter should not be null");
 
     IndexStrategyToken requestedToken = Objects.isNull(pageParams.getRequestedToken()) || pageParams.getRequestedToken().isEmpty()
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd144de and 77e29eb.

📒 Files selected for processing (4)
  • server/src/main/java/org/opensearch/action/pagination/IndexPaginationStrategy.java
  • server/src/main/java/org/opensearch/rest/action/cat/RestIndicesAction.java
  • server/src/main/java/org/opensearch/rest/action/list/RestIndicesListAction.java
  • server/src/test/java/org/opensearch/action/pagination/IndexPaginationStrategyTests.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-13T17:40:27.167Z
Learnt from: reta
Repo: opensearch-project/OpenSearch PR: 20411
File: server/src/main/java/org/opensearch/index/codec/CodecService.java:112-133
Timestamp: 2026-01-13T17:40:27.167Z
Learning: Avoid capturing or evaluating a supplier (e.g., this::defaultCodec) upfront when passing it to a registry during object construction. If registries may replace defaults during iteration (as in EnginePlugin.getAdditionalCodecs), pass the supplier itself and only resolve it at use time. This ensures dynamic behavior is preserved during initialization and prevents premature binding of defaults in codecs/registry setup. This pattern should apply to similar initialization paths in Java server code where registries may mutate defaults during construction.

Applied to files:

  • server/src/main/java/org/opensearch/rest/action/cat/RestIndicesAction.java
  • server/src/main/java/org/opensearch/rest/action/list/RestIndicesListAction.java
  • server/src/main/java/org/opensearch/action/pagination/IndexPaginationStrategy.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Code-Diff-Analyzer / Code-Diff-Analyzer
🔇 Additional comments (7)
server/src/test/java/org/opensearch/action/pagination/IndexPaginationStrategyTests.java (3)

357-388: Good test coverage for the filtered pagination in ascending order.

The test properly validates that system indices are excluded from pagination results and that the pagination token correctly chains across pages when an authorization filter is applied.

Consider adding a test for the edge case where the authorization filter matches no indices (empty authorizedIndices set), to verify the strategy returns an empty list and a null token.


390-410: Descending order test with auth filter looks good.

Correctly validates that the auth filter works with descending sort order and that the .security-index is excluded.


427-444: Non-deterministic creation timestamps may cause flaky token assertions.

Instant.now() is called per-index creation, so two indices added in the same test can receive different now() base values. This is unlikely to cause issues given the plus(creationOrder, ChronoUnit.SECONDS) offset, but if the clock ticks between calls (e.g., across a second boundary), two indices with consecutive creationOrder values could theoretically have their relative ordering affected. The existing tests already used this pattern, so this is not a new concern — just noting it for awareness.

server/src/main/java/org/opensearch/rest/action/cat/RestIndicesAction.java (2)

199-202: LGTM — call site correctly passes getSettingsResponse to the pagination strategy.


1245-1250: Base class properly accepts the new parameter while maintaining existing behavior.

The getSettingsResponse parameter is unused here (returns null) since _cat/indices is non-paginated, but the signature must include it so that RestIndicesListAction can override with authorization-filtered logic. This is a clean approach.

server/src/main/java/org/opensearch/action/pagination/IndexPaginationStrategy.java (1)

47-49: Clean delegation pattern for backward compatibility.

The existing 2-arg constructor delegates to the new 3-arg constructor with a permissive metadata -> true filter, ensuring all existing call sites continue to work without changes.

server/src/main/java/org/opensearch/rest/action/list/RestIndicesListAction.java (1)

91-98: Authorization filter correctly derives from security-filtered GetSettingsResponse.

The approach of using getSettingsResponse.getIndexToSettings().keySet() is consistent with the existing pattern documented in RestIndicesAction.sendGetSettingsRequest (Lines 271-277), which explains that Get Settings is used specifically because it respects index-level privileges. The implementation is sound—getIndexToSettings() always returns a non-null Map, and the filter safely checks authorization based on the indices returned by the security-filtered response.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@github-actions
Copy link
Contributor

✅ Gradle check result for 77e29eb: SUCCESS

@codecov
Copy link

codecov bot commented Feb 12, 2026

Codecov Report

❌ Patch coverage is 91.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 73.38%. Comparing base (8134f12) to head (4d39cd8).
⚠️ Report is 17 commits behind head on main.

Files with missing lines Patch % Lines
.../opensearch/rest/action/cat/RestIndicesAction.java 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #20616      +/-   ##
============================================
+ Coverage     73.34%   73.38%   +0.03%     
- Complexity    72173    72230      +57     
============================================
  Files          5798     5798              
  Lines        329753   329755       +2     
  Branches      47524    47522       -2     
============================================
+ Hits         241859   241989     +130     
+ Misses        68564    68444     -120     
+ Partials      19330    19322       -8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Signed-off-by: Thy Tran <58045538+ThyTran1402@users.noreply.github.com>
@github-actions
Copy link
Contributor

❌ Gradle check result for 2a002e9: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: Thy Tran <58045538+ThyTran1402@users.noreply.github.com>
@github-actions
Copy link
Contributor

✅ Gradle check result for 4d39cd8: SUCCESS

@ThyTran1402
Copy link
Author

Hi @cwperks

Can you review it please?

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API Issues with external APIs bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] _list/indices API not working in 3.2

1 participant