From 468fd898c6714c8ddff2b351086cf11454ca90d1 Mon Sep 17 00:00:00 2001 From: jimczi Date: Mon, 8 Feb 2021 17:08:16 +0100 Subject: [PATCH 1/3] Add a cluster privilege to cancel tasks and delete async searches This change adds a new cluster privilege that allows to: * Cancel running tasks (_tasks/_cancel). * Cancel and delete async searches. Today the 'manage' cluster privilege is required to cancel tasks and to delete async searches when security features are enabled. This new focused privilege allows to handle tasks and searches only. The change also adds the privilege to the internal 'kibana_system' and '_async_search' roles. They both need to be able to cancel tasks and delete async searches. Relates #67965 --- docs/reference/search/async-search.asciidoc | 5 ++++ .../security/get-builtin-privileges.asciidoc | 1 + .../authorization/privileges.asciidoc | 4 ++++ .../async-search/qa/security/build.gradle | 3 ++- .../plugin/async-search/qa/security/roles.yml | 4 ++-- .../xpack/search/AsyncSearchSecurityIT.java | 23 +++++++++++-------- .../core/async/DeleteAsyncResultsService.java | 14 +++++------ .../privilege/ClusterPrivilegeResolver.java | 6 ++++- .../authz/store/ReservedRolesStore.java | 4 +++- .../core/security/user/AsyncSearchUser.java | 2 +- .../authz/privilege/PrivilegeTests.java | 5 ++++ 11 files changed, 49 insertions(+), 22 deletions(-) diff --git a/docs/reference/search/async-search.asciidoc b/docs/reference/search/async-search.asciidoc index 91afbf334e188..fbefe5f43c104 100644 --- a/docs/reference/search/async-search.asciidoc +++ b/docs/reference/search/async-search.asciidoc @@ -315,3 +315,8 @@ Otherwise, the saved search results are deleted. DELETE /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc= -------------------------------------------------- // TEST[continued s/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=/\${body.id}/] + +If the {es} {security-features} are enabled, the deletion of a specific async +search is restricted to: + * The authenticated user that submitted the original search request. + * Users that have the `cancel_tasks` cluster privilege. diff --git a/x-pack/docs/en/rest-api/security/get-builtin-privileges.asciidoc b/x-pack/docs/en/rest-api/security/get-builtin-privileges.asciidoc index 757e639d85435..85b1f1bb3c0c4 100644 --- a/x-pack/docs/en/rest-api/security/get-builtin-privileges.asciidoc +++ b/x-pack/docs/en/rest-api/security/get-builtin-privileges.asciidoc @@ -62,6 +62,7 @@ A successful call returns an object with "cluster" and "index" fields. { "cluster" : [ "all", + "cancel_tasks", "create_snapshot", "delegate_pki", "grant_api_key", diff --git a/x-pack/docs/en/security/authorization/privileges.asciidoc b/x-pack/docs/en/security/authorization/privileges.asciidoc index 066bccdd57f91..d4575ea2d1108 100644 --- a/x-pack/docs/en/security/authorization/privileges.asciidoc +++ b/x-pack/docs/en/security/authorization/privileges.asciidoc @@ -12,6 +12,10 @@ This section lists the privileges that you can assign to a role. All cluster administration operations, like snapshotting, node shutdown/restart, settings update, rerouting, or managing users and roles. +`cancel_tasks`:: +Privileges to cancel tasks and delete async searches. +See <> API for more informations. + `create_snapshot`:: Privileges to create snapshots for existing repositories. Can also list and view details on existing repositories and snapshots. diff --git a/x-pack/plugin/async-search/qa/security/build.gradle b/x-pack/plugin/async-search/qa/security/build.gradle index 8ccaca3c4b3f5..5f9a991e03f93 100644 --- a/x-pack/plugin/async-search/qa/security/build.gradle +++ b/x-pack/plugin/async-search/qa/security/build.gradle @@ -12,9 +12,10 @@ testClusters.all { setting 'xpack.license.self_generated.type', 'trial' setting 'xpack.security.enabled', 'true' extraConfigFile 'roles.yml', file('roles.yml') + user username: "test_kibana_user", password: "x-pack-test-password", role: "kibana_system" user username: "test-admin", password: 'x-pack-test-password', role: "test-admin" user username: "user1", password: 'x-pack-test-password', role: "user1" user username: "user2", password: 'x-pack-test-password', role: "user2" user username: "user-dls", password: 'x-pack-test-password', role: "user-dls" - user username: "user-manage", password: 'x-pack-test-password', role: "user-manage" + user username: "user-cancel", password: 'x-pack-test-password', role: "user-cancel" } diff --git a/x-pack/plugin/async-search/qa/security/roles.yml b/x-pack/plugin/async-search/qa/security/roles.yml index 52c247505afc6..2e1e6325cae3c 100644 --- a/x-pack/plugin/async-search/qa/security/roles.yml +++ b/x-pack/plugin/async-search/qa/security/roles.yml @@ -56,6 +56,6 @@ user-dls: } } -user-manage: +user-cancel: cluster: - - manage + - cancel_tasks diff --git a/x-pack/plugin/async-search/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/search/AsyncSearchSecurityIT.java b/x-pack/plugin/async-search/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/search/AsyncSearchSecurityIT.java index d4ededb584ae5..4c29e1cce19e8 100644 --- a/x-pack/plugin/async-search/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/search/AsyncSearchSecurityIT.java +++ b/x-pack/plugin/async-search/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/search/AsyncSearchSecurityIT.java @@ -44,6 +44,7 @@ import static org.hamcrest.Matchers.arrayWithSize; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; public class AsyncSearchSecurityIT extends ESRestTestCase { /** @@ -126,8 +127,8 @@ private void testCase(String user, String other) throws Exception { ResponseException exc = expectThrows(ResponseException.class, () -> getAsyncSearch(id, other)); assertThat(exc.getResponse().getStatusLine().getStatusCode(), equalTo(404)); - // user-manage cannot access the result - exc = expectThrows(ResponseException.class, () -> getAsyncSearch(id, "user-manage")); + // user-cancel cannot access the result + exc = expectThrows(ResponseException.class, () -> getAsyncSearch(id, "user-cancel")); assertThat(exc.getResponse().getStatusLine().getStatusCode(), equalTo(404)); // other cannot delete the result @@ -145,13 +146,17 @@ private void testCase(String user, String other) throws Exception { Response delResp = deleteAsyncSearch(id, user); assertOK(delResp); - // check that user with 'manage' privileges can delete an async - // search submitted by a different user - Response newResp = submitAsyncSearch(indexName, "foo:bar", TimeValue.timeValueSeconds(10), user); - assertOK(newResp); - String newId = extractResponseId(newResp); - delResp = deleteAsyncSearch(newId, "user-manage"); - assertOK(delResp); + // check that users with the 'cancel_tasks' privilege can delete an async + // search submitted by a different user. + for (String runAs : new String[] { "user-cancel", "test_kibana_user" }) { + Response newResp = submitAsyncSearch(indexName, "foo:bar", TimeValue.timeValueSeconds(10), user); + assertOK(newResp); + String newId = extractResponseId(newResp); + exc = expectThrows(ResponseException.class, () -> getAsyncSearch(id, runAs)); + assertThat(exc.getResponse().getStatusLine().getStatusCode(), greaterThan(400)); + delResp = deleteAsyncSearch(newId, runAs); + assertOK(delResp); + } } ResponseException exc = expectThrows(ResponseException.class, () -> submitAsyncSearch("index-" + other, "*", TimeValue.timeValueSeconds(10), user)); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/DeleteAsyncResultsService.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/DeleteAsyncResultsService.java index 2d533604d2847..b7f2e796060bb 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/DeleteAsyncResultsService.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/DeleteAsyncResultsService.java @@ -47,19 +47,19 @@ public DeleteAsyncResultsService(AsyncTaskIndexService listener) { - hasManagePrivilegeAsync(resp -> deleteResponseAsync(request, resp, listener)); + hasCancelTasksPrivilegeAsync(resp -> deleteResponseAsync(request, resp, listener)); } /** - * Checks if the authenticated user has the right privilege (manage) to + * Checks if the authenticated user has the right privilege (cancel_tasks) to * delete async search submitted by another user. */ - private void hasManagePrivilegeAsync(Consumer consumer) { + private void hasCancelTasksPrivilegeAsync(Consumer consumer) { final Authentication current = store.getAuthentication(); if (current != null) { HasPrivilegesRequest req = new HasPrivilegesRequest(); req.username(current.getUser().principal()); - req.clusterPrivileges(ClusterPrivilegeResolver.MANAGE.name()); + req.clusterPrivileges(ClusterPrivilegeResolver.CANCEL_TASKS.name()); req.indexPrivileges(new RoleDescriptor.IndicesPrivileges[]{}); req.applicationPrivileges(new RoleDescriptor.ApplicationResourcePrivileges[]{}); try { @@ -75,17 +75,17 @@ private void hasManagePrivilegeAsync(Consumer consumer) { } private void deleteResponseAsync(DeleteAsyncResultRequest request, - boolean hasManagePrivilege, + boolean hasCancelTasksPrivilege, ActionListener listener) { try { AsyncExecutionId searchId = AsyncExecutionId.decode(request.getId()); - AsyncTask task = hasManagePrivilege ? store.getTask(taskManager, searchId, AsyncTask.class) : + AsyncTask task = hasCancelTasksPrivilege ? store.getTask(taskManager, searchId, AsyncTask.class) : store.getTaskAndCheckAuthentication(taskManager, searchId, AsyncTask.class); if (task != null) { //the task was found and gets cancelled. The response may or may not be found, but we will return 200 anyways. task.cancelTask(taskManager, () -> deleteResponseFromIndex(searchId, true, listener), "cancelled by user"); } else { - if (hasManagePrivilege) { + if (hasCancelTasksPrivilege) { deleteResponseFromIndex(searchId, false, listener); } else { store.ensureAuthenticatedUserCanDeleteFromIndex(searchId, diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java index 94218a980bc8a..43f8fd8dc0751 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java @@ -148,6 +148,9 @@ public class ClusterPrivilegeResolver { public static final NamedClusterPrivilege MANAGE_LOGSTASH_PIPELINES = new ActionClusterPrivilege("manage_logstash_pipelines", Set.of("cluster:admin/logstash/pipeline/*")); + public static final NamedClusterPrivilege CANCEL_TASKS = new ActionClusterPrivilege("cancel_tasks", + Set.of("cluster:admin/cancel/task")); + private static final Map VALUES = sortByAccessLevel(List.of( NONE, ALL, @@ -187,7 +190,8 @@ public class ClusterPrivilegeResolver { DELEGATE_PKI, MANAGE_OWN_API_KEY, MANAGE_ENRICH, - MANAGE_LOGSTASH_PIPELINES)); + MANAGE_LOGSTASH_PIPELINES, + CANCEL_TASKS)); /** * Resolves a {@link NamedClusterPrivilege} from a given name if it exists. 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 5891110f34ef7..0801733c7efeb 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 @@ -123,7 +123,9 @@ private static Map initializeReservedRoles() { // The symbolic constant for this one is in SecurityActionMapper, so not accessible from X-Pack core "cluster:admin/analyze", // To facilitate using the file uploader functionality - "monitor_text_structure" + "monitor_text_structure", + // To cancel tasks and delete async searches + "cancel_tasks" }, new RoleDescriptor.IndicesPrivileges[] { RoleDescriptor.IndicesPrivileges.builder() diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/AsyncSearchUser.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/AsyncSearchUser.java index c526dc5ea7147..08e1fc1a8f015 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/AsyncSearchUser.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/AsyncSearchUser.java @@ -17,7 +17,7 @@ public class AsyncSearchUser extends User { public static final AsyncSearchUser INSTANCE = new AsyncSearchUser(); public static final String ROLE_NAME = UsernamesField.ASYNC_SEARCH_ROLE; public static final Role ROLE = Role.builder(new RoleDescriptor(ROLE_NAME, - null, + new String[] { "cancel_tasks" }, new RoleDescriptor.IndicesPrivileges[] { RoleDescriptor.IndicesPrivileges.builder() .indices(RestrictedIndicesNames.ASYNC_SEARCH_PREFIX + "*") diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java index 70cab2bab9ba9..3dda16b47ee05 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java @@ -281,4 +281,9 @@ public void testIngestPipelinePrivileges() { } } + + public void testCancelTasksPrivilege() { + verifyClusterActionAllowed(ClusterPrivilegeResolver.CANCEL_TASKS, "cluster:admin/cancel/task"); + verifyClusterActionDenied(ClusterPrivilegeResolver.CANCEL_TASKS, "cluster:admin/whatever"); + } } From 8c8898ec62aaa079a062f34c3e39736c50a47b66 Mon Sep 17 00:00:00 2001 From: jimczi Date: Thu, 11 Feb 2021 09:18:09 +0100 Subject: [PATCH 2/3] fix yaml test --- .../test/resources/rest-api-spec/test/privileges/11_builtin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/privileges/11_builtin.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/privileges/11_builtin.yml index 350408eba40b4..4274291bc9262 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/test/privileges/11_builtin.yml +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/privileges/11_builtin.yml @@ -15,5 +15,5 @@ setup: # This is fragile - it needs to be updated every time we add a new cluster/index privilege # I would much prefer we could just check that specific entries are in the array, but we don't have # an assertion for that - - length: { "cluster" : 39 } + - length: { "cluster" : 40 } - length: { "index" : 19 } From 47cd93cf8501c856fc419ca21665d3238bbb7a2b Mon Sep 17 00:00:00 2001 From: jimczi Date: Thu, 11 Feb 2021 16:29:26 +0100 Subject: [PATCH 3/3] rename to cancel_task and fix action path --- docs/reference/search/async-search.asciidoc | 2 +- .../security/get-builtin-privileges.asciidoc | 2 +- .../en/security/authorization/privileges.asciidoc | 2 +- x-pack/plugin/async-search/qa/security/roles.yml | 2 +- .../xpack/search/AsyncSearchSecurityIT.java | 2 +- .../core/async/DeleteAsyncResultsService.java | 14 +++++++------- .../authz/privilege/ClusterPrivilegeResolver.java | 6 +++--- .../security/authz/store/ReservedRolesStore.java | 2 +- .../xpack/core/security/user/AsyncSearchUser.java | 2 +- .../security/authz/privilege/PrivilegeTests.java | 5 +++-- 10 files changed, 20 insertions(+), 19 deletions(-) diff --git a/docs/reference/search/async-search.asciidoc b/docs/reference/search/async-search.asciidoc index fbefe5f43c104..1327bb58e66f2 100644 --- a/docs/reference/search/async-search.asciidoc +++ b/docs/reference/search/async-search.asciidoc @@ -319,4 +319,4 @@ DELETE /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWH If the {es} {security-features} are enabled, the deletion of a specific async search is restricted to: * The authenticated user that submitted the original search request. - * Users that have the `cancel_tasks` cluster privilege. + * Users that have the `cancel_task` cluster privilege. diff --git a/x-pack/docs/en/rest-api/security/get-builtin-privileges.asciidoc b/x-pack/docs/en/rest-api/security/get-builtin-privileges.asciidoc index 85b1f1bb3c0c4..cd7caffa85ffd 100644 --- a/x-pack/docs/en/rest-api/security/get-builtin-privileges.asciidoc +++ b/x-pack/docs/en/rest-api/security/get-builtin-privileges.asciidoc @@ -62,7 +62,7 @@ A successful call returns an object with "cluster" and "index" fields. { "cluster" : [ "all", - "cancel_tasks", + "cancel_task", "create_snapshot", "delegate_pki", "grant_api_key", diff --git a/x-pack/docs/en/security/authorization/privileges.asciidoc b/x-pack/docs/en/security/authorization/privileges.asciidoc index d4575ea2d1108..a3cc4fe39aff6 100644 --- a/x-pack/docs/en/security/authorization/privileges.asciidoc +++ b/x-pack/docs/en/security/authorization/privileges.asciidoc @@ -12,7 +12,7 @@ This section lists the privileges that you can assign to a role. All cluster administration operations, like snapshotting, node shutdown/restart, settings update, rerouting, or managing users and roles. -`cancel_tasks`:: +`cancel_task`:: Privileges to cancel tasks and delete async searches. See <> API for more informations. diff --git a/x-pack/plugin/async-search/qa/security/roles.yml b/x-pack/plugin/async-search/qa/security/roles.yml index 2e1e6325cae3c..a5f3c14b22ac0 100644 --- a/x-pack/plugin/async-search/qa/security/roles.yml +++ b/x-pack/plugin/async-search/qa/security/roles.yml @@ -58,4 +58,4 @@ user-dls: user-cancel: cluster: - - cancel_tasks + - cancel_task diff --git a/x-pack/plugin/async-search/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/search/AsyncSearchSecurityIT.java b/x-pack/plugin/async-search/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/search/AsyncSearchSecurityIT.java index 4c29e1cce19e8..967ac118bd0a6 100644 --- a/x-pack/plugin/async-search/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/search/AsyncSearchSecurityIT.java +++ b/x-pack/plugin/async-search/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/search/AsyncSearchSecurityIT.java @@ -146,7 +146,7 @@ private void testCase(String user, String other) throws Exception { Response delResp = deleteAsyncSearch(id, user); assertOK(delResp); - // check that users with the 'cancel_tasks' privilege can delete an async + // check that users with the 'cancel_task' privilege can delete an async // search submitted by a different user. for (String runAs : new String[] { "user-cancel", "test_kibana_user" }) { Response newResp = submitAsyncSearch(indexName, "foo:bar", TimeValue.timeValueSeconds(10), user); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/DeleteAsyncResultsService.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/DeleteAsyncResultsService.java index b7f2e796060bb..b917d63178217 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/DeleteAsyncResultsService.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/DeleteAsyncResultsService.java @@ -47,19 +47,19 @@ public DeleteAsyncResultsService(AsyncTaskIndexService listener) { - hasCancelTasksPrivilegeAsync(resp -> deleteResponseAsync(request, resp, listener)); + hasCancelTaskPrivilegeAsync(resp -> deleteResponseAsync(request, resp, listener)); } /** - * Checks if the authenticated user has the right privilege (cancel_tasks) to + * Checks if the authenticated user has the right privilege (cancel_task) to * delete async search submitted by another user. */ - private void hasCancelTasksPrivilegeAsync(Consumer consumer) { + private void hasCancelTaskPrivilegeAsync(Consumer consumer) { final Authentication current = store.getAuthentication(); if (current != null) { HasPrivilegesRequest req = new HasPrivilegesRequest(); req.username(current.getUser().principal()); - req.clusterPrivileges(ClusterPrivilegeResolver.CANCEL_TASKS.name()); + req.clusterPrivileges(ClusterPrivilegeResolver.CANCEL_TASK.name()); req.indexPrivileges(new RoleDescriptor.IndicesPrivileges[]{}); req.applicationPrivileges(new RoleDescriptor.ApplicationResourcePrivileges[]{}); try { @@ -75,17 +75,17 @@ private void hasCancelTasksPrivilegeAsync(Consumer consumer) { } private void deleteResponseAsync(DeleteAsyncResultRequest request, - boolean hasCancelTasksPrivilege, + boolean hasCancelTaskPrivilege, ActionListener listener) { try { AsyncExecutionId searchId = AsyncExecutionId.decode(request.getId()); - AsyncTask task = hasCancelTasksPrivilege ? store.getTask(taskManager, searchId, AsyncTask.class) : + AsyncTask task = hasCancelTaskPrivilege ? store.getTask(taskManager, searchId, AsyncTask.class) : store.getTaskAndCheckAuthentication(taskManager, searchId, AsyncTask.class); if (task != null) { //the task was found and gets cancelled. The response may or may not be found, but we will return 200 anyways. task.cancelTask(taskManager, () -> deleteResponseFromIndex(searchId, true, listener), "cancelled by user"); } else { - if (hasCancelTasksPrivilege) { + if (hasCancelTaskPrivilege) { deleteResponseFromIndex(searchId, false, listener); } else { store.ensureAuthenticatedUserCanDeleteFromIndex(searchId, diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java index 43f8fd8dc0751..911104b94187d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilegeResolver.java @@ -148,8 +148,8 @@ public class ClusterPrivilegeResolver { public static final NamedClusterPrivilege MANAGE_LOGSTASH_PIPELINES = new ActionClusterPrivilege("manage_logstash_pipelines", Set.of("cluster:admin/logstash/pipeline/*")); - public static final NamedClusterPrivilege CANCEL_TASKS = new ActionClusterPrivilege("cancel_tasks", - Set.of("cluster:admin/cancel/task")); + public static final NamedClusterPrivilege CANCEL_TASK = new ActionClusterPrivilege("cancel_task", + Set.of("cluster:admin/tasks/cancel")); private static final Map VALUES = sortByAccessLevel(List.of( NONE, @@ -191,7 +191,7 @@ public class ClusterPrivilegeResolver { MANAGE_OWN_API_KEY, MANAGE_ENRICH, MANAGE_LOGSTASH_PIPELINES, - CANCEL_TASKS)); + CANCEL_TASK)); /** * Resolves a {@link NamedClusterPrivilege} from a given name if it exists. 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 0801733c7efeb..3fbe41c1cc5e3 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 @@ -125,7 +125,7 @@ private static Map initializeReservedRoles() { // To facilitate using the file uploader functionality "monitor_text_structure", // To cancel tasks and delete async searches - "cancel_tasks" + "cancel_task" }, new RoleDescriptor.IndicesPrivileges[] { RoleDescriptor.IndicesPrivileges.builder() diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/AsyncSearchUser.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/AsyncSearchUser.java index 08e1fc1a8f015..56d154bd2b683 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/AsyncSearchUser.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/AsyncSearchUser.java @@ -17,7 +17,7 @@ public class AsyncSearchUser extends User { public static final AsyncSearchUser INSTANCE = new AsyncSearchUser(); public static final String ROLE_NAME = UsernamesField.ASYNC_SEARCH_ROLE; public static final Role ROLE = Role.builder(new RoleDescriptor(ROLE_NAME, - new String[] { "cancel_tasks" }, + new String[] { "cancel_task" }, new RoleDescriptor.IndicesPrivileges[] { RoleDescriptor.IndicesPrivileges.builder() .indices(RestrictedIndicesNames.ASYNC_SEARCH_PREFIX + "*") diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java index 3dda16b47ee05..1af274c964600 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.core.security.authz.privilege; import org.apache.lucene.util.automaton.Operations; +import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksAction; import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.core.enrich.action.DeleteEnrichPolicyAction; @@ -283,7 +284,7 @@ public void testIngestPipelinePrivileges() { } public void testCancelTasksPrivilege() { - verifyClusterActionAllowed(ClusterPrivilegeResolver.CANCEL_TASKS, "cluster:admin/cancel/task"); - verifyClusterActionDenied(ClusterPrivilegeResolver.CANCEL_TASKS, "cluster:admin/whatever"); + verifyClusterActionAllowed(ClusterPrivilegeResolver.CANCEL_TASK, CancelTasksAction.NAME); + verifyClusterActionDenied(ClusterPrivilegeResolver.CANCEL_TASK, "cluster:admin/whatever"); } }