diff --git a/CHANGELOG.md b/CHANGELOG.md index 00917a56bbb5c..c560d7168e4ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Support pull-based ingestion message mappers and raw payload support ([#19765](https://github.com/opensearch-project/OpenSearch/pull/19765)) - Add search API tracker ([#18601](https://github.com/opensearch-project/OpenSearch/pull/18601)) - Support dynamic consumer configuration update in pull-based ingestion ([#19963](https://github.com/opensearch-project/OpenSearch/pull/19963)) +- Add validation to make crypto store settings immutable ([#20123](https://github.com/opensearch-project/OpenSearch/pull/20123)) - Cache the `StoredFieldsReader` for scroll query optimization ([#20112](https://github.com/opensearch-project/OpenSearch/pull/20112)) ### Changed diff --git a/server/src/main/java/org/opensearch/cluster/metadata/MetadataUpdateSettingsService.java b/server/src/main/java/org/opensearch/cluster/metadata/MetadataUpdateSettingsService.java index fb512a0f7ea13..e57a2635b8a68 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/MetadataUpdateSettingsService.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/MetadataUpdateSettingsService.java @@ -142,6 +142,7 @@ public void updateSettings( validateRefreshIntervalSettings(normalizedSettings, clusterService.getClusterSettings()); validateTranslogDurabilitySettings(normalizedSettings, clusterService.getClusterSettings(), clusterService.getSettings()); validateIndexTotalPrimaryShardsPerNodeSetting(normalizedSettings, clusterService); + validateCryptoStoreSettings(normalizedSettings, request.indices(), clusterService.state()); final int defaultReplicaCount = clusterService.getClusterSettings().get(Metadata.DEFAULT_REPLICA_COUNT_SETTING); Settings.Builder settingsForClosedIndices = Settings.builder(); @@ -589,4 +590,33 @@ public static void validateIndexTotalPrimaryShardsPerNodeSetting(Settings indexS ); } } + + /** + * Validates crypto store settings are immutable after index creation. + */ + public static void validateCryptoStoreSettings(Settings indexSettings, Index[] indices, ClusterState clusterState) { + final String storeTypeKey = "index.store.type"; + + // Only validate if store.type is being explicitly modified + if (!indexSettings.keySet().contains(storeTypeKey)) { + return; + } + + for (Index index : indices) { + String currentStoreType = clusterState.metadata().getIndexSafe(index).getSettings().get(storeTypeKey, ""); + String newStoreType = indexSettings.get(storeTypeKey); + + // Prevent changing FROM cryptofs to anything else (including null) + if ("cryptofs".equals(currentStoreType) && !"cryptofs".equals(newStoreType)) { + throw new IllegalArgumentException( + "Cannot change store type from 'cryptofs' for index [" + index.getName() + "] - cryptofs store type is immutable" + ); + } + + // Prevent changing TO cryptofs from any other type + if (!"cryptofs".equals(currentStoreType) && "cryptofs".equals(newStoreType)) { + throw new IllegalArgumentException("Cannot change store type to 'cryptofs' for index [" + index.getName() + "]"); + } + } + } }