diff --git a/docs/changelog/127321.yaml b/docs/changelog/127321.yaml new file mode 100644 index 0000000000000..16191d9c34442 --- /dev/null +++ b/docs/changelog/127321.yaml @@ -0,0 +1,6 @@ +pr: 127321 +summary: Granting `kibana_system` reserved role access to "all" privileges to `.adhoc.alerts*` + and `.internal.adhoc.alerts*` indices +area: Authorization +type: enhancement +issues: [] 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 b01a3da98b02e..ef1940681c3bd 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; @@ -256,6 +257,23 @@ static RoleDescriptor kibanaSystem(String name) { RoleDescriptor.IndicesPrivileges.builder().indices(ReservedRolesStore.ALERTS_INDEX_ALIAS).privileges("all").build(), // "Alerts as data" public index alias used in Security Solution // Kibana system user uses them to read / write alerts. + RoleDescriptor.IndicesPrivileges.builder() + .indices(ReservedRolesStore.ADHOC_ALERTS_BACKING_INDEX, ReservedRolesStore.ADHOC_ALERTS_INDEX_ALIAS) + .privileges( + "create_index", + "read", + "write", + "view_index_metadata", + "maintenance", + RolloverAction.NAME, + TransportIndicesAliasesAction.NAME, + TransportPutMappingAction.TYPE.name(), + TransportAutoPutMappingAction.TYPE.name(), + TransportUpdateSettingsAction.TYPE.name() + ) + .build(), + // "Alerts as data" public index alias used in Security Solution + // Kibana system user uses them to read / write alerts. RoleDescriptor.IndicesPrivileges.builder().indices(ReservedRolesStore.PREVIEW_ALERTS_INDEX_ALIAS).privileges("all").build(), // "Alerts as data" internal backing indices used in Security Solution // Kibana system user creates these indices; reads / writes to them via the diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java index 475268dab28c8..bb6c457f30095 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java @@ -60,6 +60,10 @@ public class ReservedRolesStore implements BiConsumer, ActionListene public static final String PREVIEW_ALERTS_BACKING_INDEX = ".internal.preview.alerts*"; public static final String PREVIEW_ALERTS_BACKING_INDEX_REINDEXED = ".reindexed-v8-internal.preview.alerts*"; + /** "Attack Discovery" ad-hoc alerts index */ + public static final String ADHOC_ALERTS_INDEX_ALIAS = ".adhoc.alerts*"; + public static final String ADHOC_ALERTS_BACKING_INDEX = ".internal.adhoc.alerts*"; + /** "Security Solutions" only lists index for value lists for detections */ public static final String LISTS_INDEX = ".lists-*"; public static final String LISTS_INDEX_REINDEXED_V8 = ".reindexed-v8-lists-*"; @@ -894,7 +898,11 @@ private static RoleDescriptor buildViewerRoleDescriptor() { .build(), // Alerts-as-data RoleDescriptor.IndicesPrivileges.builder() - .indices(ReservedRolesStore.ALERTS_INDEX_ALIAS, ReservedRolesStore.PREVIEW_ALERTS_INDEX_ALIAS) + .indices( + ReservedRolesStore.ALERTS_INDEX_ALIAS, + ReservedRolesStore.PREVIEW_ALERTS_INDEX_ALIAS, + ReservedRolesStore.ADHOC_ALERTS_INDEX_ALIAS + ) .privileges("read", "view_index_metadata") .build(), // Universal Profiling @@ -958,7 +966,9 @@ private static RoleDescriptor buildEditorRoleDescriptor() { ReservedRolesStore.ALERTS_INDEX_ALIAS, ReservedRolesStore.PREVIEW_ALERTS_BACKING_INDEX, ReservedRolesStore.PREVIEW_ALERTS_BACKING_INDEX_REINDEXED, - ReservedRolesStore.PREVIEW_ALERTS_INDEX_ALIAS + ReservedRolesStore.PREVIEW_ALERTS_INDEX_ALIAS, + ReservedRolesStore.ADHOC_ALERTS_BACKING_INDEX, + ReservedRolesStore.ADHOC_ALERTS_INDEX_ALIAS ) .privileges("read", "view_index_metadata", "write", "maintenance") .build(), 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 c37fc7670fbb7..4ea6a7db3c268 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 @@ -626,6 +626,31 @@ public void testKibanaSystemRole() { ".slo-observability." + randomAlphaOfLength(randomIntBetween(0, 13)) ).forEach(index -> assertAllIndicesAccessAllowed(kibanaRole, index)); + Arrays.asList( + ReservedRolesStore.ADHOC_ALERTS_INDEX_ALIAS + randomAlphaOfLength(randomIntBetween(0, 13)), + ReservedRolesStore.ADHOC_ALERTS_BACKING_INDEX + randomAlphaOfLength(randomIntBetween(0, 13)) + ).forEach(index -> { + final IndexAbstraction indexAbstraction = mockIndexAbstraction(index); + assertThat(kibanaRole.indices().allowedIndicesMatcher(RolloverAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportCreateIndexAction.TYPE.name()).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportIndicesAliasesAction.NAME).test(indexAbstraction), is(true)); + assertThat(kibanaRole.indices().allowedIndicesMatcher(TransportPutMappingAction.TYPE.name()).test(indexAbstraction), is(true)); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportAutoPutMappingAction.TYPE.name()).test(indexAbstraction), + is(true) + ); + assertThat( + kibanaRole.indices().allowedIndicesMatcher(TransportUpdateSettingsAction.TYPE.name()).test(indexAbstraction), + is(true) + ); + + // Check view_index_metadata privilege + assertViewIndexMetadata(kibanaRole, index); + + // Check read, write and maintenance privileges + assertReadWriteDocsAndMaintenanceButNotDeleteIndexAllowed(kibanaRole, index + randomIntBetween(0, 5)); + }); + // read-only index access, including cross cluster Arrays.asList(".monitoring-" + randomAlphaOfLength(randomIntBetween(0, 13))).forEach((index) -> { logger.info("index name [{}]", index);