From e0f6a89b0a433d67d4df2f2978e7ab0c2b282ae8 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 6 Nov 2025 16:34:13 -0500 Subject: [PATCH 1/3] Optimize getFieldFilter to only return a predicate when index has FLS restrictions for user Signed-off-by: Craig Perkins --- .../security/OpenSearchSecurityPlugin.java | 13 ++++++++++++- .../security/configuration/DlsFlsRequestValve.java | 7 +++++++ .../security/configuration/DlsFlsValveImpl.java | 9 +++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index c392d41a8f..ebed66a9d4 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -2328,13 +2328,24 @@ public Collection> getGuiceServiceClasses() public Function> getFieldFilter() { return index -> { if (threadPool == null || dlsFlsValve == null) { - return field -> true; + return NOOP_FIELD_PREDICATE; } PrivilegesEvaluationContext ctx = this.dlsFlsBaseContext != null ? this.dlsFlsBaseContext.getPrivilegesEvaluationContext() : null; + boolean indexHasRestrictions = false; + try { + indexHasRestrictions = dlsFlsValve.indexHasFlsRestrictions(index, ctx); + } catch (PrivilegesEvaluationException e) { + log.error("Error while evaluating FLS restrictions for {}", index, e); + } + + if (!indexHasRestrictions) { + return NOOP_FIELD_PREDICATE; + } + return field -> { try { return dlsFlsValve.isFieldAllowed(index, field, ctx); diff --git a/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java b/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java index a0fc4137fd..471465ae42 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java +++ b/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java @@ -51,6 +51,8 @@ public interface DlsFlsRequestValve { boolean isFieldAllowed(String index, String field, PrivilegesEvaluationContext ctx) throws PrivilegesEvaluationException; + boolean indexHasFlsRestrictions(String index, PrivilegesEvaluationContext ctx) throws PrivilegesEvaluationException; + public static class NoopDlsFlsRequestValve implements DlsFlsRequestValve { @Override @@ -87,6 +89,11 @@ public boolean hasFieldMasking(String index) { public boolean isFieldAllowed(String index, String field, PrivilegesEvaluationContext ctx) { return true; } + + @Override + public boolean indexHasFlsRestrictions(String index, PrivilegesEvaluationContext ctx) { + return false; + } } } diff --git a/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java b/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java index bba86ada1e..22509f8a80 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java +++ b/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java @@ -538,6 +538,15 @@ public boolean isFieldAllowed(String index, String field, PrivilegesEvaluationCo return config.getFieldPrivileges().getRestriction(ctx, index).isAllowedRecursive(field); } + @Override + public boolean indexHasFlsRestrictions(String index, PrivilegesEvaluationContext ctx) throws PrivilegesEvaluationException { + if (ctx == null) { + return false; + } + DlsFlsProcessedConfig config = this.dlsFlsProcessedConfig.get(); + return !config.getFieldPrivileges().getRestriction(ctx, index).isUnrestricted(); + } + private static InternalAggregation aggregateBuckets(InternalAggregation aggregation) { if (aggregation instanceof StringTerms) { StringTerms stringTerms = (StringTerms) aggregation; From 51121e627912ddf24088f6648d5e1b1419e8d255 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 6 Nov 2025 16:37:08 -0500 Subject: [PATCH 2/3] Add CHANGELOG entry Signed-off-by: Craig Perkins --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1228880cf9..192cd3de27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Adding Alerting V2 roles to roles.yml ([#5747](https://github.com/opensearch-project/security/pull/5747)) - add suggest api to ad read access role ([#5754](https://github.com/opensearch-project/security/pull/5754)) - Get list of headersToCopy from core and use getHeader(String headerName) instead of getHeaders() ([#5769](https://github.com/opensearch-project/security/pull/5769)) +- Optimize getFieldFilter to only return a predicate when index has FLS restrictions for user ([#5777](https://github.com/opensearch-project/security/pull/5777)) ### Bug Fixes - Create a WildcardMatcher.NONE when creating a WildcardMatcher with an empty string ([#5694](https://github.com/opensearch-project/security/pull/5694)) From ef785852467b1d093fa5dcf59aaf0cff8de5700e Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Mon, 1 Dec 2025 09:44:14 -0500 Subject: [PATCH 3/3] Move check Signed-off-by: Craig Perkins --- .../org/opensearch/security/OpenSearchSecurityPlugin.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index d1962abc77..e0df50df8b 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -2351,14 +2351,14 @@ public Function> getFieldFilter() { boolean indexHasRestrictions = false; try { indexHasRestrictions = dlsFlsValve.indexHasFlsRestrictions(index, ctx); + + if (!indexHasRestrictions) { + return NOOP_FIELD_PREDICATE; + } } catch (PrivilegesEvaluationException e) { log.error("Error while evaluating FLS restrictions for {}", index, e); } - if (!indexHasRestrictions) { - return NOOP_FIELD_PREDICATE; - } - return field -> { try { return dlsFlsValve.isFieldAllowed(index, field, ctx);