Add new 'maintenance' index privilege #50643

This commit creates a new index privilege named `maintenance`.
The privilege grants the following actions: `refresh`, `flush` (also synced-`flush`),
and `force-merge`. Previously the actions were only under the `manage` privilege
which in some situations was too permissive.

Co-authored-by: Amir H Movahed <arhd83@gmail.com>
This commit is contained in:
Albert Zaharovits 2020-01-30 11:59:11 +02:00 committed by GitHub
parent b5a2ee5be2
commit f25b6cc2eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 38 deletions

View File

@ -350,8 +350,9 @@ public final class Role {
public static final String MANAGE_FOLLOW_INDEX = "manage_follow_index";
public static final String MANAGE_ILM = "manage_ilm";
public static final String CREATE_DOC = "create_doc";
public static final String MAINTENANCE = "maintenance";
public static final String[] ALL_ARRAY = new String[] { NONE, ALL, READ, READ_CROSS, CREATE, INDEX, DELETE, WRITE, MONITOR, MANAGE,
DELETE_INDEX, CREATE_INDEX, VIEW_INDEX_METADATA, MANAGE_FOLLOW_INDEX, MANAGE_ILM, CREATE_DOC };
DELETE_INDEX, CREATE_INDEX, VIEW_INDEX_METADATA, MANAGE_FOLLOW_INDEX, MANAGE_ILM, CREATE_DOC, MAINTENANCE };
}
}

View File

@ -12,7 +12,7 @@ available in this version of {es}.
[[security-api-get-builtin-privileges-request]]
==== {api-request-title}
`GET /_security/privilege/_builtin`
`GET /_security/privilege/_builtin`
[[security-api-get-builtin-privileges-prereqs]]
@ -104,6 +104,7 @@ A successful call returns an object with "cluster" and "index" fields.
"delete",
"delete_index",
"index",
"maintenance",
"manage",
"manage_follow_index",
"manage_ilm",

View File

@ -21,15 +21,15 @@ Privileges to list and view details on existing repositories and snapshots.
`manage`::
Builds on `monitor` and adds cluster operations that change values in the cluster.
This includes snapshotting, updating settings, and rerouting. It also includes
obtaining snapshot and restore status. This privilege does not include the
This includes snapshotting, updating settings, and rerouting. It also includes
obtaining snapshot and restore status. This privilege does not include the
ability to manage security.
`manage_api_key`::
All security-related operations on {es} API keys including
{ref}/security-api-create-api-key.html[creating new API keys],
{ref}/security-api-get-api-key.html[retrieving information about API keys], and
{ref}/security-api-invalidate-api-key.html[invalidating API keys].
All security-related operations on {es} API keys including
<<security-api-create-api-key,creating new API keys>>,
<<security-api-get-api-key,retrieving information about API keys>>, and
<<security-api-invalidate-api-key,invalidating API keys>>.
+
--
[NOTE]
@ -45,10 +45,10 @@ owned by other users.
--
`manage_ccr`::
All {ccr} operations related to managing follower indices and auto-follow
patterns. It also includes the authority to grant the privileges necessary to
manage follower indices and auto-follow patterns. This privilege is necessary
only on clusters that contain follower indices.
All {ccr} operations related to managing follower indices and auto-follow
patterns. It also includes the authority to grant the privileges necessary to
manage follower indices and auto-follow patterns. This privilege is necessary
only on clusters that contain follower indices.
`manage_transform`::
All operations related to managing {transforms}.
@ -76,10 +76,10 @@ roles of the user who created or updated them.
`manage_own_api_key`::
All security-related operations on {es} API keys that are owned by the current
authenticated user. The operations include
{ref}/security-api-create-api-key.html[creating new API keys],
{ref}/security-api-get-api-key.html[retrieving information about API keys], and
{ref}/security-api-invalidate-api-key.html[invalidating API keys].
authenticated user. The operations include
<<security-api-create-api-key,creating new API keys>>,
<<security-api-get-api-key,retrieving information about API keys>>, and
<<security-api-invalidate-api-key,invalidating API keys>>.
`manage_pipeline`::
All operations on ingest pipelines.
@ -112,7 +112,7 @@ security roles of the user who created or updated them.
--
`monitor`::
All cluster read-only operations, like cluster health and state, hot threads,
All cluster read-only operations, like cluster health and state, hot threads,
node info, node and cluster stats, and pending cluster tasks.
`monitor_transform`::
@ -124,16 +124,16 @@ model snapshots, or results.
`monitor_rollup`::
All read-only rollup operations, such as viewing the list of historical and
currently running rollup jobs and their capabilities.
currently running rollup jobs and their capabilities.
`monitor_watcher`::
All read-only watcher operations, such as getting a watch and watcher stats.
`read_ccr`::
All read-only {ccr} operations, such as getting information about indices and
metadata for leader indices in the cluster. It also includes the authority to
check whether users have the appropriate privileges to follow leader indices.
This privilege is necessary only on clusters that contain leader indices.
All read-only {ccr} operations, such as getting information about indices and
metadata for leader indices in the cluster. It also includes the authority to
check whether users have the appropriate privileges to follow leader indices.
This privilege is necessary only on clusters that contain leader indices.
`read_ilm`::
All read-only {Ilm} operations, such as getting policies and checking the
@ -197,6 +197,10 @@ Privilege to delete an index.
Privilege to index and update documents. Also grants access to the update
mapping action.
`maintenance`::
Permits refresh, flush, synced flush and force merge index administration operations.
No privilege to read or write index data or otherwise manage the index.
`manage`::
All `monitor` privileges plus index administration (aliases, analyze, cache clear,
close, delete, exists, flush, mapping, open, force merge, refresh, settings,
@ -204,8 +208,8 @@ search shards, templates, validate).
`manage_follow_index`::
All actions that are required to manage the lifecycle of a follower index, which
includes creating a follower index, closing it, and converting it to a regular
index. This privilege is necessary only on clusters that contain follower indices.
includes creating a follower index, closing it, and converting it to a regular
index. This privilege is necessary only on clusters that contain follower indices.
`manage_ilm`::
All {Ilm} operations relating to managing the execution of policies of an index
@ -218,7 +222,7 @@ includes {ref}/ccr-post-forget-follower.html[forgetting a follower]. This
privilege is necessary only on clusters that contain leader indices.
`monitor`::
All actions that are required for monitoring (recovery, segments info, index
All actions that are required for monitoring (recovery, segments info, index
stats and status).
`read`::
@ -251,14 +255,14 @@ sequence.) For more information, see
[[application-privileges]]
==== Application privileges
Application privileges are managed within {es} and can be retrieved with the
{ref}/security-api-has-privileges.html[has privileges API] and the
{ref}/security-api-get-privileges.html[get application privileges API]. They do
not, however, grant access to any actions or resources within {es}. Their
purpose is to enable applications to represent and store their own privilege
models within {es} roles.
Application privileges are managed within {es} and can be retrieved with the
<<security-api-has-privileges,has privileges API>> and the
<<security-api-get-privileges,get application privileges API>>. They do
not, however, grant access to any actions or resources within {es}. Their
purpose is to enable applications to represent and store their own privilege
models within {es} roles.
To create application privileges, use the
{ref}/security-api-put-privileges.html[add application privileges API]. You can
then associate these application privileges with roles, as described in
<<defining-roles>>.
To create application privileges, use the
<<security-api-put-privileges,add application privileges API>>. You can
then associate these application privileges with roles, as described in
<<defining-roles>>.

View File

@ -70,6 +70,8 @@ public final class IndexPrivilege extends Privilege {
CloseIndexAction.NAME + "*");
private static final Automaton MANAGE_LEADER_INDEX_AUTOMATON = patterns(ForgetFollowerAction.NAME + "*");
private static final Automaton MANAGE_ILM_AUTOMATON = patterns("indices:admin/ilm/*");
private static final Automaton MAINTENANCE_AUTOMATON = patterns("indices:admin/refresh*", "indices:admin/flush*",
"indices:admin/synced_flush", "indices:admin/forcemerge*");
public static final IndexPrivilege NONE = new IndexPrivilege("none", Automatons.EMPTY);
public static final IndexPrivilege ALL = new IndexPrivilege("all", ALL_AUTOMATON);
@ -87,7 +89,8 @@ public final class IndexPrivilege extends Privilege {
public static final IndexPrivilege VIEW_METADATA = new IndexPrivilege("view_index_metadata", VIEW_METADATA_AUTOMATON);
public static final IndexPrivilege MANAGE_FOLLOW_INDEX = new IndexPrivilege("manage_follow_index", MANAGE_FOLLOW_INDEX_AUTOMATON);
public static final IndexPrivilege MANAGE_LEADER_INDEX = new IndexPrivilege("manage_leader_index", MANAGE_LEADER_INDEX_AUTOMATON);
public static final IndexPrivilege MANAGE_ILM = new IndexPrivilege("manage_ilm", MANAGE_ILM_AUTOMATON);
public static final IndexPrivilege MANAGE_ILM = new IndexPrivilege("manage_ilm", MANAGE_ILM_AUTOMATON);
public static final IndexPrivilege MAINTENANCE = new IndexPrivilege("maintenance", MAINTENANCE_AUTOMATON);
private static final Map<String, IndexPrivilege> VALUES = MapBuilder.<String, IndexPrivilege>newMapBuilder()
.put("none", NONE)
@ -107,6 +110,7 @@ public final class IndexPrivilege extends Privilege {
.put("manage_follow_index", MANAGE_FOLLOW_INDEX)
.put("manage_leader_index", MANAGE_LEADER_INDEX)
.put("manage_ilm", MANAGE_ILM)
.put("maintenance", MAINTENANCE)
.immutableMap();
public static final Predicate<String> ACTION_MATCHER = ALL.predicate();

View File

@ -69,6 +69,10 @@ public class IndexPrivilegeTests extends AbstractPrivilegeTestCase {
" indices:\n" +
" - names: 'b'\n" +
" privileges: [ monitor ]\n" +
"maintenance_a_role:\n" +
" indices:\n" +
" - names: 'a'\n" +
" privileges: [ maintenance ]\n" +
"read_write_a_role:\n" +
" indices:\n" +
" - names: 'a'\n" +
@ -96,6 +100,7 @@ public class IndexPrivilegeTests extends AbstractPrivilegeTestCase {
"read_write_all_role:u12\n" +
"create_c_role:u11\n" +
"monitor_b_role:u14\n" +
"maintenance_a_role:u15\n" +
"read_write_a_role:u12\n" +
"delete_b_role:u11\n" +
"index_a_role:u13\n";
@ -129,7 +134,8 @@ public class IndexPrivilegeTests extends AbstractPrivilegeTestCase {
"u11:" + usersPasswdHashed + "\n" +
"u12:" + usersPasswdHashed + "\n" +
"u13:" + usersPasswdHashed + "\n" +
"u14:" + usersPasswdHashed + "\n";
"u14:" + usersPasswdHashed + "\n" +
"u15:" + usersPasswdHashed + "\n" ;
}
@Override
@ -308,12 +314,14 @@ public class IndexPrivilegeTests extends AbstractPrivilegeTestCase {
assertUserIsDenied("u11", "manage", "b");
assertUserIsDenied("u11", "index", "b");
assertUserIsDenied("u11", "search", "b");
assertUserIsDenied("u11", "maintenance", "b");
assertUserIsAllowed("u11", "delete", "b");
assertAccessIsAllowed("admin", "DELETE", "/c");
assertUserIsAllowed("u11", "create_index", "c");
assertUserIsDenied("u11", "data_access", "c");
assertUserIsDenied("u11", "monitor", "c");
assertUserIsDenied("u11", "maintenance", "c");
assertAccessIsDenied("u11",
"GET", "/" + randomIndex() + "/foo/_msearch", "{}\n{ \"query\" : { \"match_all\" : {} } }\n");
@ -385,6 +393,11 @@ public class IndexPrivilegeTests extends AbstractPrivilegeTestCase {
"GET", "/" + randomIndex() + "/_mtermvectors", "{ \"docs\" : [ { \"_id\": \"1\" }, { \"_id\": \"2\" } ] }");
}
public void testUserU15() throws Exception {
assertUserIsAllowed("u15", "maintenance", "a");
assertUserIsDenied("u15", "crud", "a");
}
public void testThatUnknownUserIsRejectedProperly() throws Exception {
try {
Request request = new Request("GET", "/");
@ -419,6 +432,20 @@ public class IndexPrivilegeTests extends AbstractPrivilegeTestCase {
}
break;
case "maintenance" :
if (userIsAllowed) {
assertAccessIsAllowed(user, "POST", "/" + index + "/_refresh");
assertAccessIsAllowed(user, "POST", "/" + index + "/_flush");
assertAccessIsAllowed(user, "POST", "/" + index + "/_flush/synced");
assertAccessIsAllowed(user, "POST", "/" + index + "/_forcemerge");
} else {
assertAccessIsDenied(user, "POST", "/" + index + "/_refresh");
assertAccessIsDenied(user, "POST", "/" + index + "/_flush");
assertAccessIsDenied(user, "POST", "/" + index + "/_flush/synced");
assertAccessIsDenied(user, "POST", "/" + index + "/_forcemerge");
}
break;
case "manage" :
if (userIsAllowed) {
assertAccessIsAllowed(user, "DELETE", "/" + index);

View File

@ -16,4 +16,4 @@ setup:
# 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" : 34 }
- length: { "index" : 17 }
- length: { "index" : 18 }