From 11fc00dbb09e0e680e12f8fbbae0031b743c6c58 Mon Sep 17 00:00:00 2001 From: Shourie Ganguly Date: Thu, 7 Aug 2025 13:31:39 +0530 Subject: [PATCH 1/3] [ExtraHop][Qualys GAV] - Fix Cannot execute ILM policy delete step (#132387) This PR focuses on the short term solution which add the logs-extrahop.investigation-* and logs-qualys_gav.asset-* indices under the kibana_system role with deletion privileges to prevent a failed deletion error when the index enters the deletion phase for the ILM lifecycle, in upcoming PRs. (cherry picked from commit 0d7a2cc2e618ef54429f432913c47d30bf13a270) --- docs/changelog/132387.yaml | 6 +++ .../KibanaOwnedReservedRoleDescriptors.java | 17 ++++++++ .../authz/store/ReservedRolesStoreTests.java | 41 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 docs/changelog/132387.yaml diff --git a/docs/changelog/132387.yaml b/docs/changelog/132387.yaml new file mode 100644 index 0000000000000..c1e9c110af1a6 --- /dev/null +++ b/docs/changelog/132387.yaml @@ -0,0 +1,6 @@ +pr: 132387 +summary: "[ExtraHop & QualysGAV] Add `manage`, `create_index`, `read`, `index`, `write`, `delete`, permission for third party agent indices `kibana_system`" +area: Authorization +type: enhancement +issues: + - 131825 diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java index 5c9c9b640c6da..1417b4bc2340e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java @@ -460,6 +460,23 @@ static RoleDescriptor kibanaSystem(String name) { ) .privileges("read", "view_index_metadata") .build(), + // For ExtraHop and QualysGAV specific actions. Kibana reads, writes and manages this index + // for configured ILM policies. + RoleDescriptor.IndicesPrivileges.builder() + .indices("logs-extrahop.investigation-*", "logs-qualys_gav.asset-*") + .privileges( + "manage", + "create_index", + "read", + "index", + "write", + "delete", + // Require "delete_index" to perform ILM policy actions + TransportDeleteIndexAction.TYPE.name(), + TransportIndicesAliasesAction.NAME, + TransportAutoPutMappingAction.TYPE.name() + ) + .build(), // For alias indices of the Cloud Detection & Response (CDR) packages that ships a // transform RoleDescriptor.IndicesPrivileges.builder() diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java index bcb71f76101c8..25d2400f17262 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java @@ -1825,6 +1825,47 @@ public void testKibanaSystemRole() { assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportPutMappingAction.TYPE.name()).test(indexAbstraction), is(true)); assertThat(kibanaRole.indices().allowedIndicesMatcher(RolloverAction.NAME).test(indexAbstraction), is(true)); }); + + // Tests for third-party agent indices (ExtraHop, QualysGAV) that `kibana_system` has full management access to + // This includes read, write, create, delete, and all ILM-related management actions. + Arrays.asList( + "logs-extrahop.investigation-" + randomAlphaOfLength(randomIntBetween(1, 10)), + "logs-qualys_gav.asset-" + randomAlphaOfLength(randomIntBetween(1, 10)) + ).forEach((index_qualys_extra_hop) -> { + final IndexAbstraction indexAbstraction = mockIndexAbstraction(index_qualys_extra_hop); + + // Assert Read Actions (Allowed by "read") + assertThat(kibanaRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportGetAction.TYPE.name()).test(indexAbstraction), is(true)); + + // Assert Write & Delete Document Actions (Allowed by "write", "index", "delete") + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndexAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteAction.NAME).test(indexAbstraction), is(true)); + // The "update" action is also implicitly part of "write" + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportUpdateAction.NAME).test(indexAbstraction), is(true)); + + // Assert Index Management Actions (Allowed by "create_index", "delete_index", and "manage") + // Allowed by the explicit "create_index" privilege + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportCreateIndexAction.TYPE.name()).test(indexAbstraction), is(true)); + // Allowed by the explicit TransportDeleteIndexAction + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportDeleteIndexAction.TYPE.name()).test(indexAbstraction), is(true)); + + // Allowed due to the "manage" privilege and explicit TransportAutoPutMappingAction + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportPutMappingAction.TYPE.name()).test(indexAbstraction), is(true)); + // Allowed due to the explicit TransportIndicesAliasesAction + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndicesAliasesAction.NAME).test(indexAbstraction), is(true)); + // Rollover requires 'manage' on the alias and 'create_index', both of which are granted. + assertThat(kibanaRole.indices().allowedIndicesMatcher(RolloverAction.NAME).test(indexAbstraction), is(true)); + + // Assert Denied Actions + // This role should not have cross-cluster permissions on these indices + assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(indexAbstraction), is(false)); + + // A check against a completely different index should fail + final IndexAbstraction otherIndex = mockIndexAbstraction("some-unrelated-index"); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportSearchAction.TYPE.name()).test(otherIndex), is(false)); + }); } public void testKibanaAdminRole() { From 3d14dbd0246ebda8270f1b70b6ca83d58fec6fed Mon Sep 17 00:00:00 2001 From: Shourie Ganguly Date: Mon, 11 Aug 2025 11:58:52 +0530 Subject: [PATCH 2/3] Update KibanaOwnedReservedRoleDescriptors.java added missing imports in KibanaOwnedReservedRoleDescriptors --- .../security/authz/store/KibanaOwnedReservedRoleDescriptors.java | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java index 1417b4bc2340e..e59ce73a3ade8 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java @@ -26,6 +26,7 @@ import org.elasticsearch.xpack.core.security.authz.privilege.ConfigurableClusterPrivilege; import org.elasticsearch.xpack.core.security.authz.privilege.ConfigurableClusterPrivileges; import org.elasticsearch.xpack.core.security.support.MetadataUtils; +import org.elasticsearch.action.admin.indices.mapping.put.TransportAutoPutMappingAction; import java.util.Map; import java.util.Set; From 13d6a8effc58db2a96720f302aa3ede0e14a3223 Mon Sep 17 00:00:00 2001 From: elasticsearchmachine Date: Mon, 11 Aug 2025 06:34:43 +0000 Subject: [PATCH 3/3] [CI] Auto commit changes from spotless --- .../authz/store/KibanaOwnedReservedRoleDescriptors.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java index e59ce73a3ade8..c085423e441a3 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/KibanaOwnedReservedRoleDescriptors.java @@ -9,6 +9,7 @@ import org.elasticsearch.action.admin.indices.alias.TransportIndicesAliasesAction; import org.elasticsearch.action.admin.indices.delete.TransportDeleteIndexAction; +import org.elasticsearch.action.admin.indices.mapping.put.TransportAutoPutMappingAction; import org.elasticsearch.action.admin.indices.mapping.put.TransportPutMappingAction; import org.elasticsearch.action.admin.indices.rollover.RolloverAction; import org.elasticsearch.action.admin.indices.settings.put.TransportUpdateSettingsAction; @@ -26,7 +27,6 @@ import org.elasticsearch.xpack.core.security.authz.privilege.ConfigurableClusterPrivilege; import org.elasticsearch.xpack.core.security.authz.privilege.ConfigurableClusterPrivileges; import org.elasticsearch.xpack.core.security.support.MetadataUtils; -import org.elasticsearch.action.admin.indices.mapping.put.TransportAutoPutMappingAction; import java.util.Map; import java.util.Set;