From 2f5e82f412d70b52e7ea2f24bc32d08584503ed8 Mon Sep 17 00:00:00 2001 From: Abdul Muneer Kolarkunnu Date: Tue, 4 Nov 2025 14:12:05 +0530 Subject: [PATCH 1/3] [FEATURE] Add an option to turn on and off the certificate validation in ML Commons Resolves #4371 Signed-off-by: Abdul Muneer Kolarkunnu --- .../ml/common/httpclient/MLHttpClientFactory.java | 9 +++++++-- .../opensearch/ml/common/settings/MLCommonsSettings.java | 4 ++++ .../ml/common/settings/MLFeatureEnabledSetting.java | 9 +++++++++ .../ml/common/httpclient/MLHttpClientFactoryTests.java | 4 +++- .../ml/common/settings/MLCommonsSettingsTests.java | 5 +++++ .../ml/common/settings/MLFeatureEnabledSettingTests.java | 7 ++++++- .../engine/algorithms/remote/AwsConnectorExecutor.java | 5 ++++- .../algorithms/remote/HttpJsonConnectorExecutor.java | 4 +++- .../algorithms/remote/RemoteConnectorExecutor.java | 2 ++ .../ml/engine/algorithms/remote/RemoteModel.java | 2 ++ .../connector/ExecuteConnectorTransportAction.java | 1 + .../java/org/opensearch/ml/model/MLModelManager.java | 2 ++ .../org/opensearch/ml/plugin/MachineLearningPlugin.java | 3 ++- .../ml/settings/MLFeatureEnabledSettingTests.java | 4 +++- 14 files changed, 53 insertions(+), 8 deletions(-) diff --git a/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java b/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java index 59831f4ae5..7fcfd1e6ad 100644 --- a/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java +++ b/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java @@ -10,8 +10,10 @@ import java.time.Duration; import lombok.extern.log4j.Log4j2; +import software.amazon.awssdk.http.SdkHttpConfigurationOption; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient; +import software.amazon.awssdk.utils.AttributeMap; @Log4j2 public class MLHttpClientFactory { @@ -20,7 +22,8 @@ public static SdkAsyncHttpClient getAsyncHttpClient( Duration connectionTimeout, Duration readTimeout, int maxConnections, - boolean connectorPrivateIpEnabled + boolean connectorPrivateIpEnabled, + boolean connectorSslVerificationEnabled ) { return doPrivileged(() -> { log @@ -35,7 +38,9 @@ public static SdkAsyncHttpClient getAsyncHttpClient( .connectionTimeout(connectionTimeout) .readTimeout(readTimeout) .maxConcurrency(maxConnections) - .build(); + .buildWithDefaults(AttributeMap.builder() + .put(SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES, !connectorSslVerificationEnabled) + .build()); return new MLValidatableAsyncHttpClient(delegate, connectorPrivateIpEnabled); }); } diff --git a/common/src/main/java/org/opensearch/ml/common/settings/MLCommonsSettings.java b/common/src/main/java/org/opensearch/ml/common/settings/MLCommonsSettings.java index c139ea4b68..f9af60a147 100644 --- a/common/src/main/java/org/opensearch/ml/common/settings/MLCommonsSettings.java +++ b/common/src/main/java/org/opensearch/ml/common/settings/MLCommonsSettings.java @@ -483,4 +483,8 @@ private MLCommonsSettings() {} // Feature flag for streaming feature public static final Setting ML_COMMONS_STREAM_ENABLED = Setting .boolSetting(ML_PLUGIN_SETTING_PREFIX + "stream_enabled", false, Setting.Property.NodeScope, Setting.Property.Dynamic); + + // Feature flag to enable or disable SSL verification of remote llm connectors + public static final Setting ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED = Setting + .boolSetting(ML_PLUGIN_SETTING_PREFIX + "connector.ssl_verification_enabled", true, Setting.Property.NodeScope, Setting.Property.Dynamic); } diff --git a/common/src/main/java/org/opensearch/ml/common/settings/MLFeatureEnabledSetting.java b/common/src/main/java/org/opensearch/ml/common/settings/MLFeatureEnabledSetting.java index 2642a12db6..2364c84c55 100644 --- a/common/src/main/java/org/opensearch/ml/common/settings/MLFeatureEnabledSetting.java +++ b/common/src/main/java/org/opensearch/ml/common/settings/MLFeatureEnabledSetting.java @@ -22,6 +22,7 @@ import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_REMOTE_INFERENCE_ENABLED; import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_STATIC_METRIC_COLLECTION_ENABLED; import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_STREAM_ENABLED; +import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED; import java.util.ArrayList; import java.util.List; @@ -63,6 +64,8 @@ public class MLFeatureEnabledSetting { private volatile Boolean isStreamEnabled; + private volatile Boolean isConnectorSslVerificationEnabled; + private final List listeners = new ArrayList<>(); public MLFeatureEnabledSetting(ClusterService clusterService, Settings settings) { @@ -83,6 +86,7 @@ public MLFeatureEnabledSetting(ClusterService clusterService, Settings settings) isAgenticMemoryEnabled = ML_COMMONS_AGENTIC_MEMORY_ENABLED.get(settings); isIndexInsightEnabled = ML_COMMONS_INDEX_INSIGHT_FEATURE_ENABLED.get(settings); isStreamEnabled = ML_COMMONS_STREAM_ENABLED.get(settings); + isConnectorSslVerificationEnabled = ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED.get(settings); clusterService .getClusterSettings() @@ -109,6 +113,7 @@ public MLFeatureEnabledSetting(ClusterService clusterService, Settings settings) clusterService.getClusterSettings().addSettingsUpdateConsumer(ML_COMMONS_MCP_CONNECTOR_ENABLED, it -> isMcpConnectorEnabled = it); clusterService.getClusterSettings().addSettingsUpdateConsumer(ML_COMMONS_AGENTIC_MEMORY_ENABLED, it -> isAgenticMemoryEnabled = it); clusterService.getClusterSettings().addSettingsUpdateConsumer(ML_COMMONS_STREAM_ENABLED, it -> isStreamEnabled = it); + clusterService.getClusterSettings().addSettingsUpdateConsumer(ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED, it -> isConnectorSslVerificationEnabled = it); clusterService .getClusterSettings() .addSettingsUpdateConsumer(ML_COMMONS_INDEX_INSIGHT_FEATURE_ENABLED, it -> isIndexInsightEnabled = it); @@ -245,4 +250,8 @@ public boolean isIndexInsightEnabled() { public boolean isStreamEnabled() { return isStreamEnabled; } + + public boolean isConnectorSslVerificationEnabled() { + return isConnectorSslVerificationEnabled; + } } diff --git a/common/src/test/java/org/opensearch/ml/common/httpclient/MLHttpClientFactoryTests.java b/common/src/test/java/org/opensearch/ml/common/httpclient/MLHttpClientFactoryTests.java index d0664cca3a..7fbffdb88d 100644 --- a/common/src/test/java/org/opensearch/ml/common/httpclient/MLHttpClientFactoryTests.java +++ b/common/src/test/java/org/opensearch/ml/common/httpclient/MLHttpClientFactoryTests.java @@ -17,7 +17,9 @@ public class MLHttpClientFactoryTests { @Test public void test_getSdkAsyncHttpClient_success() { - SdkAsyncHttpClient client = MLHttpClientFactory.getAsyncHttpClient(Duration.ofSeconds(100), Duration.ofSeconds(100), 100, false); + SdkAsyncHttpClient client = MLHttpClientFactory.getAsyncHttpClient(Duration.ofSeconds(100), Duration.ofSeconds(100), 100, false, true); + assertNotNull(client); + client = MLHttpClientFactory.getAsyncHttpClient(Duration.ofSeconds(100), Duration.ofSeconds(100), 100, false, false); assertNotNull(client); } diff --git a/common/src/test/java/org/opensearch/ml/common/settings/MLCommonsSettingsTests.java b/common/src/test/java/org/opensearch/ml/common/settings/MLCommonsSettingsTests.java index cd4437b57a..496a8689ad 100644 --- a/common/src/test/java/org/opensearch/ml/common/settings/MLCommonsSettingsTests.java +++ b/common/src/test/java/org/opensearch/ml/common/settings/MLCommonsSettingsTests.java @@ -107,4 +107,9 @@ public void testAgenticMemoryDisabledMessage() { public void testStreamDisabledByDefault() { assertFalse(MLCommonsSettings.ML_COMMONS_STREAM_ENABLED.getDefault(null)); } + + @Test + public void testConnectorSSLVerificationByDefault() { + assertTrue(MLCommonsSettings.ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED.getDefault(null)); + } } diff --git a/common/src/test/java/org/opensearch/ml/common/settings/MLFeatureEnabledSettingTests.java b/common/src/test/java/org/opensearch/ml/common/settings/MLFeatureEnabledSettingTests.java index f6a7daad1d..ff11de8aac 100644 --- a/common/src/test/java/org/opensearch/ml/common/settings/MLFeatureEnabledSettingTests.java +++ b/common/src/test/java/org/opensearch/ml/common/settings/MLFeatureEnabledSettingTests.java @@ -48,7 +48,8 @@ public void setUp() { MLCommonsSettings.ML_COMMONS_MCP_CONNECTOR_ENABLED, MLCommonsSettings.ML_COMMONS_AGENTIC_MEMORY_ENABLED, MLCommonsSettings.ML_COMMONS_INDEX_INSIGHT_FEATURE_ENABLED, - MLCommonsSettings.ML_COMMONS_STREAM_ENABLED + MLCommonsSettings.ML_COMMONS_STREAM_ENABLED, + MLCommonsSettings.ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED ) ); when(mockClusterService.getClusterSettings()).thenReturn(mockClusterSettings); @@ -74,6 +75,7 @@ public void testDefaults_allFeaturesEnabled() { .put("plugins.ml_commons.agentic_search_enabled", true) .put("plugins.ml_commons.agentic_memory_enabled", true) .put("plugins.ml_commons.stream_enabled", true) + .put("plugins.ml_commons.connector.ssl_verification_enabled", true) .build(); MLFeatureEnabledSetting setting = new MLFeatureEnabledSetting(mockClusterService, settings); @@ -93,6 +95,7 @@ public void testDefaults_allFeaturesEnabled() { assertTrue(setting.isMcpConnectorEnabled()); assertTrue(setting.isAgenticMemoryEnabled()); assertTrue(setting.isStreamEnabled()); + assertTrue(setting.isConnectorSslVerificationEnabled()); } @Test @@ -115,6 +118,7 @@ public void testDefaults_someFeaturesDisabled() { .put("plugins.ml_commons.agentic_search_enabled", false) .put("plugins.ml_commons.agentic_memory_enabled", false) .put("plugins.ml_commons.stream_enabled", false) + .put("plugins.ml_commons.connector.ssl_verification_enabled", false) .build(); MLFeatureEnabledSetting setting = new MLFeatureEnabledSetting(mockClusterService, settings); @@ -134,6 +138,7 @@ public void testDefaults_someFeaturesDisabled() { assertFalse(setting.isMcpConnectorEnabled()); assertFalse(setting.isAgenticMemoryEnabled()); assertFalse(setting.isStreamEnabled()); + assertFalse(setting.isConnectorSslVerificationEnabled()); } @Test diff --git a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/AwsConnectorExecutor.java b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/AwsConnectorExecutor.java index 3b53935aaf..86947a0f93 100644 --- a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/AwsConnectorExecutor.java +++ b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/AwsConnectorExecutor.java @@ -82,6 +82,9 @@ public class AwsConnectorExecutor extends AbstractConnectorExecutor { @Setter private boolean connectorPrivateIpEnabled; + @Setter + private boolean connectorSslVerificationEnabled; + public AwsConnectorExecutor(Connector connector) { super.initialize(connector); this.connector = (AwsConnector) connector; @@ -193,7 +196,7 @@ protected SdkAsyncHttpClient getHttpClient() { this.httpClientRef .compareAndSet( null, - MLHttpClientFactory.getAsyncHttpClient(connectionTimeout, readTimeout, maxConnection, connectorPrivateIpEnabled) + MLHttpClientFactory.getAsyncHttpClient(connectionTimeout, readTimeout, maxConnection, connectorPrivateIpEnabled, connectorSslVerificationEnabled) ); } return httpClientRef.get(); diff --git a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/HttpJsonConnectorExecutor.java b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/HttpJsonConnectorExecutor.java index 7804770258..adbf84019e 100644 --- a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/HttpJsonConnectorExecutor.java +++ b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/HttpJsonConnectorExecutor.java @@ -74,6 +74,8 @@ public class HttpJsonConnectorExecutor extends AbstractConnectorExecutor { private MLGuard mlGuard; @Setter private volatile boolean connectorPrivateIpEnabled; + @Setter + private boolean connectorSslVerificationEnabled; private final AtomicReference httpClientRef = new AtomicReference<>(); @@ -183,7 +185,7 @@ protected SdkAsyncHttpClient getHttpClient() { this.httpClientRef .compareAndSet( null, - MLHttpClientFactory.getAsyncHttpClient(connectionTimeout, readTimeout, maxConnection, connectorPrivateIpEnabled) + MLHttpClientFactory.getAsyncHttpClient(connectionTimeout, readTimeout, maxConnection, connectorPrivateIpEnabled, connectorSslVerificationEnabled) ); } return httpClientRef.get(); diff --git a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteConnectorExecutor.java b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteConnectorExecutor.java index 5181e8d087..396db5cbbd 100644 --- a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteConnectorExecutor.java +++ b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteConnectorExecutor.java @@ -184,6 +184,8 @@ default void setClient(Client client) {} default void setConnectorPrivateIpEnabled(boolean connectorPrivateIpEnabled) {} + default void setConnectorSslVerificationEnabled(boolean connectorSslVerificationEnabled) {} + default void setXContentRegistry(NamedXContentRegistry xContentRegistry) {} default void setClusterService(ClusterService clusterService) {} diff --git a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteModel.java b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteModel.java index a000989ee6..58a08b0f87 100644 --- a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteModel.java +++ b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteModel.java @@ -53,6 +53,7 @@ public class RemoteModel implements Predictable { public static final String USER_RATE_LIMITER_MAP = "user_rate_limiter_map"; public static final String GUARDRAILS = "guardrails"; public static final String CONNECTOR_PRIVATE_IP_ENABLED = "connectorPrivateIpEnabled"; + public static final String CONNECTOR_SSL_VERIFICATION_ENABLED = "connectorSslVerificationEnabled"; public static final String SDK_CLIENT = "sdk_client"; public static final String SETTINGS = "settings"; @@ -127,6 +128,7 @@ public CompletionStage initModelAsync(MLModel model, Map) params.get(USER_RATE_LIMITER_MAP)); this.connectorExecutor.setMlGuard((MLGuard) params.get(GUARDRAILS)); this.connectorExecutor.setConnectorPrivateIpEnabled((boolean) params.getOrDefault(CONNECTOR_PRIVATE_IP_ENABLED, false)); + this.connectorExecutor.setConnectorSslVerificationEnabled((boolean) params.getOrDefault(CONNECTOR_SSL_VERIFICATION_ENABLED, true)); return CompletableFuture.completedStage(true); }).exceptionally(e -> { log.error("Failed to init remote model.", e); diff --git a/plugin/src/main/java/org/opensearch/ml/action/connector/ExecuteConnectorTransportAction.java b/plugin/src/main/java/org/opensearch/ml/action/connector/ExecuteConnectorTransportAction.java index c1b5db1778..9ecab7e506 100644 --- a/plugin/src/main/java/org/opensearch/ml/action/connector/ExecuteConnectorTransportAction.java +++ b/plugin/src/main/java/org/opensearch/ml/action/connector/ExecuteConnectorTransportAction.java @@ -84,6 +84,7 @@ protected void doExecute(Task task, ActionRequest request, ActionListener setUpParameterMap(String modelId, String tenantId) { log.info("Setting up ML guard parameter for ML predictor."); } params.put(CONNECTOR_PRIVATE_IP_ENABLED, mlFeatureEnabledSetting.isConnectorPrivateIpEnabled()); + params.put(CONNECTOR_SSL_VERIFICATION_ENABLED, mlFeatureEnabledSetting.isConnectorSslVerificationEnabled()); params.put(SDK_CLIENT, sdkClient); params.put(SETTINGS, settings); return Collections.unmodifiableMap(params); diff --git a/plugin/src/main/java/org/opensearch/ml/plugin/MachineLearningPlugin.java b/plugin/src/main/java/org/opensearch/ml/plugin/MachineLearningPlugin.java index 62de34961e..0dd85ec0ae 100644 --- a/plugin/src/main/java/org/opensearch/ml/plugin/MachineLearningPlugin.java +++ b/plugin/src/main/java/org/opensearch/ml/plugin/MachineLearningPlugin.java @@ -1364,7 +1364,8 @@ public List> getSettings() { MLCommonsSettings.ML_COMMONS_INDEX_INSIGHT_FEATURE_ENABLED, MLCommonsSettings.REMOTE_METADATA_GLOBAL_TENANT_ID, MLCommonsSettings.REMOTE_METADATA_GLOBAL_RESOURCE_CACHE_TTL, - MLCommonsSettings.ML_COMMONS_STREAM_ENABLED + MLCommonsSettings.ML_COMMONS_STREAM_ENABLED, + MLCommonsSettings.ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED ); return settings; } diff --git a/plugin/src/test/java/org/opensearch/ml/settings/MLFeatureEnabledSettingTests.java b/plugin/src/test/java/org/opensearch/ml/settings/MLFeatureEnabledSettingTests.java index f27e71e8bc..bd7ab01549 100644 --- a/plugin/src/test/java/org/opensearch/ml/settings/MLFeatureEnabledSettingTests.java +++ b/plugin/src/test/java/org/opensearch/ml/settings/MLFeatureEnabledSettingTests.java @@ -28,6 +28,7 @@ import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_REMOTE_INFERENCE_ENABLED; import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_STATIC_METRIC_COLLECTION_ENABLED; import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_STREAM_ENABLED; +import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED; import java.util.Set; @@ -80,7 +81,8 @@ public void setUp() { ML_COMMONS_AGENTIC_MEMORY_ENABLED, ML_COMMONS_MCP_CONNECTOR_ENABLED, ML_COMMONS_INDEX_INSIGHT_FEATURE_ENABLED, - ML_COMMONS_STREAM_ENABLED + ML_COMMONS_STREAM_ENABLED, + ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED ) ) ); From 564d4013abc72d49fc1c109efac52c185bd42a95 Mon Sep 17 00:00:00 2001 From: Abdul Muneer Kolarkunnu Date: Sun, 7 Dec 2025 17:18:39 +0530 Subject: [PATCH 2/3] [FEATURE] Add an option to turn on and off the certificate validation in ML Commons Resolves #4371 Signed-off-by: Abdul Muneer Kolarkunnu --- .../ml/common/httpclient/MLHttpClientFactory.java | 8 ++++---- .../ml/common/settings/MLCommonsSettings.java | 12 ++++-------- .../ml/common/settings/MLFeatureEnabledSetting.java | 9 --------- .../common/httpclient/MLHttpClientFactoryTests.java | 5 +++-- .../ml/common/settings/MLCommonsSettingsTests.java | 5 ----- .../settings/MLFeatureEnabledSettingTests.java | 7 +------ .../algorithms/remote/AwsConnectorExecutor.java | 10 ++++++---- .../algorithms/remote/HttpJsonConnectorExecutor.java | 9 ++++++--- .../algorithms/remote/RemoteConnectorExecutor.java | 3 +-- .../ml/engine/algorithms/remote/RemoteModel.java | 2 -- .../connector/ExecuteConnectorTransportAction.java | 1 - .../java/org/opensearch/ml/model/MLModelManager.java | 2 -- .../opensearch/ml/plugin/MachineLearningPlugin.java | 3 +-- .../ml/settings/MLFeatureEnabledSettingTests.java | 4 +--- 14 files changed, 27 insertions(+), 53 deletions(-) diff --git a/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java b/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java index 7fcfd1e6ad..873ebd6750 100644 --- a/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java +++ b/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java @@ -23,7 +23,7 @@ public static SdkAsyncHttpClient getAsyncHttpClient( Duration readTimeout, int maxConnections, boolean connectorPrivateIpEnabled, - boolean connectorSslVerificationEnabled + boolean skipSslVerification ) { return doPrivileged(() -> { log @@ -38,9 +38,9 @@ public static SdkAsyncHttpClient getAsyncHttpClient( .connectionTimeout(connectionTimeout) .readTimeout(readTimeout) .maxConcurrency(maxConnections) - .buildWithDefaults(AttributeMap.builder() - .put(SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES, !connectorSslVerificationEnabled) - .build()); + .buildWithDefaults( + AttributeMap.builder().put(SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES, skipSslVerification).build() + ); return new MLValidatableAsyncHttpClient(delegate, connectorPrivateIpEnabled); }); } diff --git a/common/src/main/java/org/opensearch/ml/common/settings/MLCommonsSettings.java b/common/src/main/java/org/opensearch/ml/common/settings/MLCommonsSettings.java index f9af60a147..e0350374f7 100644 --- a/common/src/main/java/org/opensearch/ml/common/settings/MLCommonsSettings.java +++ b/common/src/main/java/org/opensearch/ml/common/settings/MLCommonsSettings.java @@ -50,9 +50,9 @@ private MLCommonsSettings() {} public static final Setting ML_COMMONS_MAX_BATCH_INFERENCE_TASKS = Setting .intSetting( ML_PLUGIN_SETTING_PREFIX + "max_batch_inference_tasks", - 10, + 100, 0, - 500, + 10000, Setting.Property.NodeScope, Setting.Property.Dynamic ); @@ -60,9 +60,9 @@ private MLCommonsSettings() {} public static final Setting ML_COMMONS_MAX_BATCH_INGESTION_TASKS = Setting .intSetting( ML_PLUGIN_SETTING_PREFIX + "max_batch_ingestion_tasks", - 10, + 100, 0, - 500, + 10000, Setting.Property.NodeScope, Setting.Property.Dynamic ); @@ -483,8 +483,4 @@ private MLCommonsSettings() {} // Feature flag for streaming feature public static final Setting ML_COMMONS_STREAM_ENABLED = Setting .boolSetting(ML_PLUGIN_SETTING_PREFIX + "stream_enabled", false, Setting.Property.NodeScope, Setting.Property.Dynamic); - - // Feature flag to enable or disable SSL verification of remote llm connectors - public static final Setting ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED = Setting - .boolSetting(ML_PLUGIN_SETTING_PREFIX + "connector.ssl_verification_enabled", true, Setting.Property.NodeScope, Setting.Property.Dynamic); } diff --git a/common/src/main/java/org/opensearch/ml/common/settings/MLFeatureEnabledSetting.java b/common/src/main/java/org/opensearch/ml/common/settings/MLFeatureEnabledSetting.java index 2364c84c55..2642a12db6 100644 --- a/common/src/main/java/org/opensearch/ml/common/settings/MLFeatureEnabledSetting.java +++ b/common/src/main/java/org/opensearch/ml/common/settings/MLFeatureEnabledSetting.java @@ -22,7 +22,6 @@ import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_REMOTE_INFERENCE_ENABLED; import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_STATIC_METRIC_COLLECTION_ENABLED; import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_STREAM_ENABLED; -import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED; import java.util.ArrayList; import java.util.List; @@ -64,8 +63,6 @@ public class MLFeatureEnabledSetting { private volatile Boolean isStreamEnabled; - private volatile Boolean isConnectorSslVerificationEnabled; - private final List listeners = new ArrayList<>(); public MLFeatureEnabledSetting(ClusterService clusterService, Settings settings) { @@ -86,7 +83,6 @@ public MLFeatureEnabledSetting(ClusterService clusterService, Settings settings) isAgenticMemoryEnabled = ML_COMMONS_AGENTIC_MEMORY_ENABLED.get(settings); isIndexInsightEnabled = ML_COMMONS_INDEX_INSIGHT_FEATURE_ENABLED.get(settings); isStreamEnabled = ML_COMMONS_STREAM_ENABLED.get(settings); - isConnectorSslVerificationEnabled = ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED.get(settings); clusterService .getClusterSettings() @@ -113,7 +109,6 @@ public MLFeatureEnabledSetting(ClusterService clusterService, Settings settings) clusterService.getClusterSettings().addSettingsUpdateConsumer(ML_COMMONS_MCP_CONNECTOR_ENABLED, it -> isMcpConnectorEnabled = it); clusterService.getClusterSettings().addSettingsUpdateConsumer(ML_COMMONS_AGENTIC_MEMORY_ENABLED, it -> isAgenticMemoryEnabled = it); clusterService.getClusterSettings().addSettingsUpdateConsumer(ML_COMMONS_STREAM_ENABLED, it -> isStreamEnabled = it); - clusterService.getClusterSettings().addSettingsUpdateConsumer(ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED, it -> isConnectorSslVerificationEnabled = it); clusterService .getClusterSettings() .addSettingsUpdateConsumer(ML_COMMONS_INDEX_INSIGHT_FEATURE_ENABLED, it -> isIndexInsightEnabled = it); @@ -250,8 +245,4 @@ public boolean isIndexInsightEnabled() { public boolean isStreamEnabled() { return isStreamEnabled; } - - public boolean isConnectorSslVerificationEnabled() { - return isConnectorSslVerificationEnabled; - } } diff --git a/common/src/test/java/org/opensearch/ml/common/httpclient/MLHttpClientFactoryTests.java b/common/src/test/java/org/opensearch/ml/common/httpclient/MLHttpClientFactoryTests.java index 7fbffdb88d..75c3e9846d 100644 --- a/common/src/test/java/org/opensearch/ml/common/httpclient/MLHttpClientFactoryTests.java +++ b/common/src/test/java/org/opensearch/ml/common/httpclient/MLHttpClientFactoryTests.java @@ -17,9 +17,10 @@ public class MLHttpClientFactoryTests { @Test public void test_getSdkAsyncHttpClient_success() { - SdkAsyncHttpClient client = MLHttpClientFactory.getAsyncHttpClient(Duration.ofSeconds(100), Duration.ofSeconds(100), 100, false, true); + SdkAsyncHttpClient client = MLHttpClientFactory + .getAsyncHttpClient(Duration.ofSeconds(100), Duration.ofSeconds(100), 100, false, false); assertNotNull(client); - client = MLHttpClientFactory.getAsyncHttpClient(Duration.ofSeconds(100), Duration.ofSeconds(100), 100, false, false); + client = MLHttpClientFactory.getAsyncHttpClient(Duration.ofSeconds(100), Duration.ofSeconds(100), 100, false, true); assertNotNull(client); } diff --git a/common/src/test/java/org/opensearch/ml/common/settings/MLCommonsSettingsTests.java b/common/src/test/java/org/opensearch/ml/common/settings/MLCommonsSettingsTests.java index 496a8689ad..cd4437b57a 100644 --- a/common/src/test/java/org/opensearch/ml/common/settings/MLCommonsSettingsTests.java +++ b/common/src/test/java/org/opensearch/ml/common/settings/MLCommonsSettingsTests.java @@ -107,9 +107,4 @@ public void testAgenticMemoryDisabledMessage() { public void testStreamDisabledByDefault() { assertFalse(MLCommonsSettings.ML_COMMONS_STREAM_ENABLED.getDefault(null)); } - - @Test - public void testConnectorSSLVerificationByDefault() { - assertTrue(MLCommonsSettings.ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED.getDefault(null)); - } } diff --git a/common/src/test/java/org/opensearch/ml/common/settings/MLFeatureEnabledSettingTests.java b/common/src/test/java/org/opensearch/ml/common/settings/MLFeatureEnabledSettingTests.java index ff11de8aac..f6a7daad1d 100644 --- a/common/src/test/java/org/opensearch/ml/common/settings/MLFeatureEnabledSettingTests.java +++ b/common/src/test/java/org/opensearch/ml/common/settings/MLFeatureEnabledSettingTests.java @@ -48,8 +48,7 @@ public void setUp() { MLCommonsSettings.ML_COMMONS_MCP_CONNECTOR_ENABLED, MLCommonsSettings.ML_COMMONS_AGENTIC_MEMORY_ENABLED, MLCommonsSettings.ML_COMMONS_INDEX_INSIGHT_FEATURE_ENABLED, - MLCommonsSettings.ML_COMMONS_STREAM_ENABLED, - MLCommonsSettings.ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED + MLCommonsSettings.ML_COMMONS_STREAM_ENABLED ) ); when(mockClusterService.getClusterSettings()).thenReturn(mockClusterSettings); @@ -75,7 +74,6 @@ public void testDefaults_allFeaturesEnabled() { .put("plugins.ml_commons.agentic_search_enabled", true) .put("plugins.ml_commons.agentic_memory_enabled", true) .put("plugins.ml_commons.stream_enabled", true) - .put("plugins.ml_commons.connector.ssl_verification_enabled", true) .build(); MLFeatureEnabledSetting setting = new MLFeatureEnabledSetting(mockClusterService, settings); @@ -95,7 +93,6 @@ public void testDefaults_allFeaturesEnabled() { assertTrue(setting.isMcpConnectorEnabled()); assertTrue(setting.isAgenticMemoryEnabled()); assertTrue(setting.isStreamEnabled()); - assertTrue(setting.isConnectorSslVerificationEnabled()); } @Test @@ -118,7 +115,6 @@ public void testDefaults_someFeaturesDisabled() { .put("plugins.ml_commons.agentic_search_enabled", false) .put("plugins.ml_commons.agentic_memory_enabled", false) .put("plugins.ml_commons.stream_enabled", false) - .put("plugins.ml_commons.connector.ssl_verification_enabled", false) .build(); MLFeatureEnabledSetting setting = new MLFeatureEnabledSetting(mockClusterService, settings); @@ -138,7 +134,6 @@ public void testDefaults_someFeaturesDisabled() { assertFalse(setting.isMcpConnectorEnabled()); assertFalse(setting.isAgenticMemoryEnabled()); assertFalse(setting.isStreamEnabled()); - assertFalse(setting.isConnectorSslVerificationEnabled()); } @Test diff --git a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/AwsConnectorExecutor.java b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/AwsConnectorExecutor.java index 86947a0f93..11911f18a2 100644 --- a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/AwsConnectorExecutor.java +++ b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/AwsConnectorExecutor.java @@ -82,9 +82,6 @@ public class AwsConnectorExecutor extends AbstractConnectorExecutor { @Setter private boolean connectorPrivateIpEnabled; - @Setter - private boolean connectorSslVerificationEnabled; - public AwsConnectorExecutor(Connector connector) { super.initialize(connector); this.connector = (AwsConnector) connector; @@ -193,10 +190,15 @@ protected SdkAsyncHttpClient getHttpClient() { Duration connectionTimeout = Duration.ofSeconds(super.getConnectorClientConfig().getConnectionTimeout()); Duration readTimeout = Duration.ofSeconds(super.getConnectorClientConfig().getReadTimeout()); Integer maxConnection = super.getConnectorClientConfig().getMaxConnections(); + boolean skipSslVerification = false; + if (connector.getParameters() != null && connector.getParameters().containsKey(SKIP_SSL_VERIFICATION)) { + skipSslVerification = Boolean.parseBoolean(connector.getParameters().get(SKIP_SSL_VERIFICATION)); + } this.httpClientRef .compareAndSet( null, - MLHttpClientFactory.getAsyncHttpClient(connectionTimeout, readTimeout, maxConnection, connectorPrivateIpEnabled, connectorSslVerificationEnabled) + MLHttpClientFactory + .getAsyncHttpClient(connectionTimeout, readTimeout, maxConnection, connectorPrivateIpEnabled, skipSslVerification) ); } return httpClientRef.get(); diff --git a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/HttpJsonConnectorExecutor.java b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/HttpJsonConnectorExecutor.java index adbf84019e..7e796afc70 100644 --- a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/HttpJsonConnectorExecutor.java +++ b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/HttpJsonConnectorExecutor.java @@ -74,8 +74,6 @@ public class HttpJsonConnectorExecutor extends AbstractConnectorExecutor { private MLGuard mlGuard; @Setter private volatile boolean connectorPrivateIpEnabled; - @Setter - private boolean connectorSslVerificationEnabled; private final AtomicReference httpClientRef = new AtomicReference<>(); @@ -182,10 +180,15 @@ protected SdkAsyncHttpClient getHttpClient() { Duration connectionTimeout = Duration.ofSeconds(super.getConnectorClientConfig().getConnectionTimeout()); Duration readTimeout = Duration.ofSeconds(super.getConnectorClientConfig().getReadTimeout()); Integer maxConnection = super.getConnectorClientConfig().getMaxConnections(); + boolean skipSslVerification = false; + if (connector.getParameters() != null && connector.getParameters().containsKey(SKIP_SSL_VERIFICATION)) { + skipSslVerification = Boolean.parseBoolean(connector.getParameters().get(SKIP_SSL_VERIFICATION)); + } this.httpClientRef .compareAndSet( null, - MLHttpClientFactory.getAsyncHttpClient(connectionTimeout, readTimeout, maxConnection, connectorPrivateIpEnabled, connectorSslVerificationEnabled) + MLHttpClientFactory + .getAsyncHttpClient(connectionTimeout, readTimeout, maxConnection, connectorPrivateIpEnabled, skipSslVerification) ); } return httpClientRef.get(); diff --git a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteConnectorExecutor.java b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteConnectorExecutor.java index 396db5cbbd..6fb1fb62ad 100644 --- a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteConnectorExecutor.java +++ b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteConnectorExecutor.java @@ -65,6 +65,7 @@ public interface RemoteConnectorExecutor { public String RETRY_EXECUTOR = "opensearch_ml_predict_remote"; + String SKIP_SSL_VERIFICATION = "skip_ssl_verification"; default void executeAction(String action, MLInput mlInput, ActionListener actionListener) { executeAction(action, mlInput, actionListener, null); @@ -184,8 +185,6 @@ default void setClient(Client client) {} default void setConnectorPrivateIpEnabled(boolean connectorPrivateIpEnabled) {} - default void setConnectorSslVerificationEnabled(boolean connectorSslVerificationEnabled) {} - default void setXContentRegistry(NamedXContentRegistry xContentRegistry) {} default void setClusterService(ClusterService clusterService) {} diff --git a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteModel.java b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteModel.java index 58a08b0f87..a000989ee6 100644 --- a/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteModel.java +++ b/ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/remote/RemoteModel.java @@ -53,7 +53,6 @@ public class RemoteModel implements Predictable { public static final String USER_RATE_LIMITER_MAP = "user_rate_limiter_map"; public static final String GUARDRAILS = "guardrails"; public static final String CONNECTOR_PRIVATE_IP_ENABLED = "connectorPrivateIpEnabled"; - public static final String CONNECTOR_SSL_VERIFICATION_ENABLED = "connectorSslVerificationEnabled"; public static final String SDK_CLIENT = "sdk_client"; public static final String SETTINGS = "settings"; @@ -128,7 +127,6 @@ public CompletionStage initModelAsync(MLModel model, Map) params.get(USER_RATE_LIMITER_MAP)); this.connectorExecutor.setMlGuard((MLGuard) params.get(GUARDRAILS)); this.connectorExecutor.setConnectorPrivateIpEnabled((boolean) params.getOrDefault(CONNECTOR_PRIVATE_IP_ENABLED, false)); - this.connectorExecutor.setConnectorSslVerificationEnabled((boolean) params.getOrDefault(CONNECTOR_SSL_VERIFICATION_ENABLED, true)); return CompletableFuture.completedStage(true); }).exceptionally(e -> { log.error("Failed to init remote model.", e); diff --git a/plugin/src/main/java/org/opensearch/ml/action/connector/ExecuteConnectorTransportAction.java b/plugin/src/main/java/org/opensearch/ml/action/connector/ExecuteConnectorTransportAction.java index 9ecab7e506..c1b5db1778 100644 --- a/plugin/src/main/java/org/opensearch/ml/action/connector/ExecuteConnectorTransportAction.java +++ b/plugin/src/main/java/org/opensearch/ml/action/connector/ExecuteConnectorTransportAction.java @@ -84,7 +84,6 @@ protected void doExecute(Task task, ActionRequest request, ActionListener setUpParameterMap(String modelId, String tenantId) { log.info("Setting up ML guard parameter for ML predictor."); } params.put(CONNECTOR_PRIVATE_IP_ENABLED, mlFeatureEnabledSetting.isConnectorPrivateIpEnabled()); - params.put(CONNECTOR_SSL_VERIFICATION_ENABLED, mlFeatureEnabledSetting.isConnectorSslVerificationEnabled()); params.put(SDK_CLIENT, sdkClient); params.put(SETTINGS, settings); return Collections.unmodifiableMap(params); diff --git a/plugin/src/main/java/org/opensearch/ml/plugin/MachineLearningPlugin.java b/plugin/src/main/java/org/opensearch/ml/plugin/MachineLearningPlugin.java index 0dd85ec0ae..62de34961e 100644 --- a/plugin/src/main/java/org/opensearch/ml/plugin/MachineLearningPlugin.java +++ b/plugin/src/main/java/org/opensearch/ml/plugin/MachineLearningPlugin.java @@ -1364,8 +1364,7 @@ public List> getSettings() { MLCommonsSettings.ML_COMMONS_INDEX_INSIGHT_FEATURE_ENABLED, MLCommonsSettings.REMOTE_METADATA_GLOBAL_TENANT_ID, MLCommonsSettings.REMOTE_METADATA_GLOBAL_RESOURCE_CACHE_TTL, - MLCommonsSettings.ML_COMMONS_STREAM_ENABLED, - MLCommonsSettings.ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED + MLCommonsSettings.ML_COMMONS_STREAM_ENABLED ); return settings; } diff --git a/plugin/src/test/java/org/opensearch/ml/settings/MLFeatureEnabledSettingTests.java b/plugin/src/test/java/org/opensearch/ml/settings/MLFeatureEnabledSettingTests.java index bd7ab01549..f27e71e8bc 100644 --- a/plugin/src/test/java/org/opensearch/ml/settings/MLFeatureEnabledSettingTests.java +++ b/plugin/src/test/java/org/opensearch/ml/settings/MLFeatureEnabledSettingTests.java @@ -28,7 +28,6 @@ import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_REMOTE_INFERENCE_ENABLED; import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_STATIC_METRIC_COLLECTION_ENABLED; import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_STREAM_ENABLED; -import static org.opensearch.ml.common.settings.MLCommonsSettings.ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED; import java.util.Set; @@ -81,8 +80,7 @@ public void setUp() { ML_COMMONS_AGENTIC_MEMORY_ENABLED, ML_COMMONS_MCP_CONNECTOR_ENABLED, ML_COMMONS_INDEX_INSIGHT_FEATURE_ENABLED, - ML_COMMONS_STREAM_ENABLED, - ML_COMMONS_CONNECTOR_SSL_VERIFICATION_ENABLED + ML_COMMONS_STREAM_ENABLED ) ) ); From 2d657e938ca4bb0aafcec707f3e88839c20583c8 Mon Sep 17 00:00:00 2001 From: Abdul Muneer Kolarkunnu Date: Mon, 8 Dec 2025 07:42:39 +0530 Subject: [PATCH 3/3] Fixed coderabbitai comments Resolves #4371 Signed-off-by: Abdul Muneer Kolarkunnu --- .../ml/common/httpclient/MLHttpClientFactory.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java b/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java index 873ebd6750..4a6fe53520 100644 --- a/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java +++ b/common/src/main/java/org/opensearch/ml/common/httpclient/MLHttpClientFactory.java @@ -26,12 +26,20 @@ public static SdkAsyncHttpClient getAsyncHttpClient( boolean skipSslVerification ) { return doPrivileged(() -> { + if (skipSslVerification) { + log + .warn( + "SSL certificate verification is DISABLED. This connection is vulnerable to man-in-the-middle" + + " attacks. Only use this setting in trusted environments." + ); + } log .debug( - "Creating MLHttpClient with connectionTimeout: {}, readTimeout: {}, maxConnections: {}", + "Creating MLHttpClient with connectionTimeout: {}, readTimeout: {}, maxConnections: {}," + " skipSslVerification: {}", connectionTimeout, readTimeout, - maxConnections + maxConnections, + skipSslVerification ); SdkAsyncHttpClient delegate = NettyNioAsyncHttpClient .builder()