Browse Source

[Failure Store] Access for internal users (#125660) (#125780)

This PR grants `manage_failure_store` to the internal user
`_data_stream_lifecycle` to enable life-cycle management for the failure
indices of data stream, which includes rollovers using the failures
selector.

I'm only unit testing this but we also need to add DLM tests for the
failure store with security enabled. 

Relates: ES-11355

Co-authored-by: Slobodan Adamović <slobodanadamovic@users.noreply.github.com>
Nikolaj Volgushev 7 months ago
parent
commit
34c24dfae2

+ 42 - 35
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/InternalUsers.java

@@ -36,9 +36,11 @@ import org.elasticsearch.xpack.core.ilm.action.ILMActions;
 import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
 import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
 import org.elasticsearch.xpack.core.security.support.MetadataUtils;
 import org.elasticsearch.xpack.core.security.support.MetadataUtils;
 
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.Function;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.stream.Stream;
@@ -158,14 +160,18 @@ public class InternalUsers {
                 RoleDescriptor.IndicesPrivileges.builder()
                 RoleDescriptor.IndicesPrivileges.builder()
                     .indices("*")
                     .indices("*")
                     .privileges(
                     .privileges(
-                        "delete_index",
-                        RolloverAction.NAME,
-                        ForceMergeAction.NAME + "*",
-                        // indices stats is used by rollover, so we need to grant it here
-                        IndicesStatsAction.NAME + "*",
-                        TransportUpdateSettingsAction.TYPE.name(),
-                        DownsampleAction.NAME,
-                        TransportAddIndexBlockAction.TYPE.name()
+                        filterNonNull(
+                            // needed to rollover failure store
+                            DataStream.isFailureStoreFeatureFlagEnabled() ? "manage_failure_store" : null,
+                            "delete_index",
+                            RolloverAction.NAME,
+                            ForceMergeAction.NAME + "*",
+                            // indices stats is used by rollover, so we need to grant it here
+                            IndicesStatsAction.NAME + "*",
+                            TransportUpdateSettingsAction.TYPE.name(),
+                            DownsampleAction.NAME,
+                            TransportAddIndexBlockAction.TYPE.name()
+                        )
                     )
                     )
                     .allowRestrictedIndices(false)
                     .allowRestrictedIndices(false)
                     .build(),
                     .build(),
@@ -177,14 +183,18 @@ public class InternalUsers {
                         ".fleet-fileds*"
                         ".fleet-fileds*"
                     )
                     )
                     .privileges(
                     .privileges(
-                        "delete_index",
-                        RolloverAction.NAME,
-                        ForceMergeAction.NAME + "*",
-                        // indices stats is used by rollover, so we need to grant it here
-                        IndicesStatsAction.NAME + "*",
-                        TransportUpdateSettingsAction.TYPE.name(),
-                        DownsampleAction.NAME,
-                        TransportAddIndexBlockAction.TYPE.name()
+                        filterNonNull(
+                            // needed to rollover failure store
+                            DataStream.isFailureStoreFeatureFlagEnabled() ? "manage_failure_store" : null,
+                            "delete_index",
+                            RolloverAction.NAME,
+                            ForceMergeAction.NAME + "*",
+                            // indices stats is used by rollover, so we need to grant it here
+                            IndicesStatsAction.NAME + "*",
+                            TransportUpdateSettingsAction.TYPE.name(),
+                            DownsampleAction.NAME,
+                            TransportAddIndexBlockAction.TYPE.name()
+                        )
                     )
                     )
                     .allowRestrictedIndices(true)
                     .allowRestrictedIndices(true)
                     .build() },
                     .build() },
@@ -248,25 +258,18 @@ public class InternalUsers {
         new RoleDescriptor(
         new RoleDescriptor(
             UsernamesField.LAZY_ROLLOVER_ROLE,
             UsernamesField.LAZY_ROLLOVER_ROLE,
             new String[] {},
             new String[] {},
-            DataStream.isFailureStoreFeatureFlagEnabled()
-                ? new RoleDescriptor.IndicesPrivileges[] {
-                    RoleDescriptor.IndicesPrivileges.builder()
-                        .indices("*")
-                        .privileges(LazyRolloverAction.NAME)
-                        .allowRestrictedIndices(true)
-                        .build(),
-                    RoleDescriptor.IndicesPrivileges.builder()
-                        .indices("*")
-                        // needed to rollover failure store
-                        .privileges("manage_failure_store")
-                        .allowRestrictedIndices(true)
-                        .build() }
-                : new RoleDescriptor.IndicesPrivileges[] {
-                    RoleDescriptor.IndicesPrivileges.builder()
-                        .indices("*")
-                        .privileges(LazyRolloverAction.NAME)
-                        .allowRestrictedIndices(true)
-                        .build(), },
+            new RoleDescriptor.IndicesPrivileges[] {
+                RoleDescriptor.IndicesPrivileges.builder()
+                    .indices("*")
+                    .privileges(
+                        filterNonNull(
+                            // needed to rollover failure store
+                            DataStream.isFailureStoreFeatureFlagEnabled() ? "manage_failure_store" : null,
+                            LazyRolloverAction.NAME
+                        )
+                    )
+                    .allowRestrictedIndices(true)
+                    .build() },
             null,
             null,
             null,
             null,
             new String[] {},
             new String[] {},
@@ -324,4 +327,8 @@ public class InternalUsers {
         }
         }
         return instance;
         return instance;
     }
     }
+
+    private static String[] filterNonNull(String... privileges) {
+        return Arrays.stream(privileges).filter(Objects::nonNull).toArray(String[]::new);
+    }
 }
 }

+ 18 - 0
x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/user/InternalUsersTests.java

@@ -271,6 +271,7 @@ public class InternalUsersTests extends ESTestCase {
             TransportAddIndexBlockAction.TYPE.name()
             TransportAddIndexBlockAction.TYPE.name()
         );
         );
         final String dataStream = randomAlphaOfLengthBetween(3, 12);
         final String dataStream = randomAlphaOfLengthBetween(3, 12);
+
         checkIndexAccess(role, randomFrom(sampleIndexActions), dataStream, true);
         checkIndexAccess(role, randomFrom(sampleIndexActions), dataStream, true);
         // Also check backing index access
         // Also check backing index access
         checkIndexAccess(
         checkIndexAccess(
@@ -280,6 +281,15 @@ public class InternalUsersTests extends ESTestCase {
             true
             true
         );
         );
 
 
+        checkIndexAccess(role, randomFrom(sampleIndexActions), dataStream + "::failures", true);
+        // Also check failure index access
+        checkIndexAccess(
+            role,
+            randomFrom(sampleIndexActions),
+            DataStream.FAILURE_STORE_PREFIX + dataStream + randomAlphaOfLengthBetween(4, 8),
+            true
+        );
+
         allowedSystemDataStreams.forEach(allowedSystemDataStream -> {
         allowedSystemDataStreams.forEach(allowedSystemDataStream -> {
             checkIndexAccess(role, randomFrom(sampleSystemDataStreamActions), allowedSystemDataStream, true);
             checkIndexAccess(role, randomFrom(sampleSystemDataStreamActions), allowedSystemDataStream, true);
             checkIndexAccess(
             checkIndexAccess(
@@ -288,6 +298,14 @@ public class InternalUsersTests extends ESTestCase {
                 DataStream.BACKING_INDEX_PREFIX + allowedSystemDataStream + randomAlphaOfLengthBetween(4, 8),
                 DataStream.BACKING_INDEX_PREFIX + allowedSystemDataStream + randomAlphaOfLengthBetween(4, 8),
                 true
                 true
             );
             );
+
+            checkIndexAccess(role, randomFrom(sampleSystemDataStreamActions), allowedSystemDataStream + "::failures", true);
+            checkIndexAccess(
+                role,
+                randomFrom(sampleSystemDataStreamActions),
+                DataStream.FAILURE_STORE_PREFIX + allowedSystemDataStream + randomAlphaOfLengthBetween(4, 8),
+                true
+            );
         });
         });
 
 
         checkIndexAccess(role, randomFrom(sampleSystemDataStreamActions), randomFrom(TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES), false);
         checkIndexAccess(role, randomFrom(sampleSystemDataStreamActions), randomFrom(TestRestrictedIndices.SAMPLE_RESTRICTED_NAMES), false);