Skip to content

Commit 3e1bd0a

Browse files
ywangdtvernum
andcommitted
Phase 1 support for operator privileges (elastic#65256)
In some Elastic Stack environments, there is a distinction between the operator of the cluster infrastructure and the administrator of the cluster. This distinction cannot be supported currently because the "administrator" often has the superuser role which grants each and every privilege of the cluster. This PR adds a new feature to protect a fixed set of APIs from the "administrator" even when it is a highly privileged user such as superuser. It enhances the Elasticsearch security model to have an additional layer of restriction in addition to the RBAC. Co-authored-by: Tim Vernum <[email protected]>
1 parent 7435e34 commit 3e1bd0a

File tree

31 files changed

+1977
-38
lines changed

31 files changed

+1977
-38
lines changed

docs/reference/rest-api/info.asciidoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ Example response:
111111
"available" : true,
112112
"enabled" : true
113113
},
114+
"operator_privileges": {
115+
"available": true,
116+
"enabled": false
117+
},
114118
"rollup": {
115119
"available": true,
116120
"enabled": true

x-pack/plugin/core/src/main/java/org/elasticsearch/license/XPackLicenseState.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ public enum Feature {
104104

105105
AGGREGATE_METRIC(OperationMode.MISSING, true),
106106

107-
SEARCHABLE_SNAPSHOTS(OperationMode.ENTERPRISE, true);
107+
SEARCHABLE_SNAPSHOTS(OperationMode.ENTERPRISE, true),
108+
109+
OPERATOR_PRIVILEGES(OperationMode.ENTERPRISE, true);
108110

109111
final OperationMode minimumOperationMode;
110112
final boolean needsActive;

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackField.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ public final class XPackField {
6565
public static final String DATA_TIERS = "data_tiers";
6666
/** Name constant for the aggregate_metric plugin. */
6767
public static final String AGGREGATE_METRIC = "aggregate_metric";
68+
/** Name constant for the operator privileges feature. */
69+
public static final String OPERATOR_PRIVILEGES = "operator_privileges";
6870

6971
private XPackField() {}
7072

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
package org.elasticsearch.xpack.core.action;
7+
8+
import org.elasticsearch.action.ActionType;
9+
import org.elasticsearch.xpack.core.XPackField;
10+
11+
import java.util.ArrayList;
12+
import java.util.Arrays;
13+
import java.util.Collections;
14+
import java.util.List;
15+
16+
/**
17+
* A base action for info about a feature plugin.
18+
*
19+
* This action is implemented by each feature plugin, bound to the public constants here. The
20+
* {@link XPackInfoAction} implementation iterates over the {@link #ALL} list of actions to form
21+
* the complete info result.
22+
*/
23+
public class XPackInfoFeatureAction extends ActionType<XPackInfoFeatureResponse> {
24+
25+
private static final String BASE_NAME = "cluster:monitor/xpack/info/";
26+
27+
public static final XPackInfoFeatureAction SECURITY = new XPackInfoFeatureAction(XPackField.SECURITY);
28+
public static final XPackInfoFeatureAction MONITORING = new XPackInfoFeatureAction(XPackField.MONITORING);
29+
public static final XPackInfoFeatureAction WATCHER = new XPackInfoFeatureAction(XPackField.WATCHER);
30+
public static final XPackInfoFeatureAction GRAPH = new XPackInfoFeatureAction(XPackField.GRAPH);
31+
public static final XPackInfoFeatureAction MACHINE_LEARNING = new XPackInfoFeatureAction(XPackField.MACHINE_LEARNING);
32+
public static final XPackInfoFeatureAction LOGSTASH = new XPackInfoFeatureAction(XPackField.LOGSTASH);
33+
public static final XPackInfoFeatureAction EQL = new XPackInfoFeatureAction(XPackField.EQL);
34+
public static final XPackInfoFeatureAction SQL = new XPackInfoFeatureAction(XPackField.SQL);
35+
public static final XPackInfoFeatureAction ROLLUP = new XPackInfoFeatureAction(XPackField.ROLLUP);
36+
public static final XPackInfoFeatureAction INDEX_LIFECYCLE = new XPackInfoFeatureAction(XPackField.INDEX_LIFECYCLE);
37+
public static final XPackInfoFeatureAction SNAPSHOT_LIFECYCLE = new XPackInfoFeatureAction(XPackField.SNAPSHOT_LIFECYCLE);
38+
public static final XPackInfoFeatureAction CCR = new XPackInfoFeatureAction(XPackField.CCR);
39+
public static final XPackInfoFeatureAction TRANSFORM = new XPackInfoFeatureAction(XPackField.TRANSFORM);
40+
public static final XPackInfoFeatureAction VECTORS = new XPackInfoFeatureAction(XPackField.VECTORS);
41+
public static final XPackInfoFeatureAction VOTING_ONLY = new XPackInfoFeatureAction(XPackField.VOTING_ONLY);
42+
public static final XPackInfoFeatureAction FROZEN_INDICES = new XPackInfoFeatureAction(XPackField.FROZEN_INDICES);
43+
public static final XPackInfoFeatureAction SPATIAL = new XPackInfoFeatureAction(XPackField.SPATIAL);
44+
public static final XPackInfoFeatureAction ANALYTICS = new XPackInfoFeatureAction(XPackField.ANALYTICS);
45+
public static final XPackInfoFeatureAction ENRICH = new XPackInfoFeatureAction(XPackField.ENRICH);
46+
public static final XPackInfoFeatureAction SEARCHABLE_SNAPSHOTS = new XPackInfoFeatureAction(XPackField.SEARCHABLE_SNAPSHOTS);
47+
public static final XPackInfoFeatureAction DATA_STREAMS = new XPackInfoFeatureAction(XPackField.DATA_STREAMS);
48+
public static final XPackInfoFeatureAction DATA_TIERS = new XPackInfoFeatureAction(XPackField.DATA_TIERS);
49+
public static final XPackInfoFeatureAction AGGREGATE_METRIC = new XPackInfoFeatureAction(XPackField.AGGREGATE_METRIC);
50+
public static final XPackInfoFeatureAction OPERATOR_PRIVILEGES = new XPackInfoFeatureAction(XPackField.OPERATOR_PRIVILEGES);
51+
52+
public static final List<XPackInfoFeatureAction> ALL;
53+
static {
54+
final List<XPackInfoFeatureAction> actions = new ArrayList<>();
55+
actions.addAll(Arrays.asList(
56+
SECURITY, MONITORING, WATCHER, GRAPH, MACHINE_LEARNING, LOGSTASH, EQL, SQL, ROLLUP, INDEX_LIFECYCLE, SNAPSHOT_LIFECYCLE, CCR,
57+
TRANSFORM, VECTORS, VOTING_ONLY, FROZEN_INDICES, SPATIAL, ANALYTICS, ENRICH, DATA_STREAMS, SEARCHABLE_SNAPSHOTS, DATA_TIERS,
58+
AGGREGATE_METRIC, OPERATOR_PRIVILEGES
59+
));
60+
ALL = Collections.unmodifiableList(actions);
61+
}
62+
63+
private XPackInfoFeatureAction(String name) {
64+
super(BASE_NAME + name, XPackInfoFeatureResponse::new);
65+
}
66+
67+
@Override
68+
public String toString() {
69+
return "ActionType [" + name() + "]";
70+
}
71+
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationField.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ public final class AuthenticationField {
1010
public static final String AUTHENTICATION_KEY = "_xpack_security_authentication";
1111
public static final String API_KEY_ROLE_DESCRIPTORS_KEY = "_security_api_key_role_descriptors";
1212
public static final String API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY = "_security_api_key_limited_by_role_descriptors";
13+
public static final String PRIVILEGE_CATEGORY_KEY = "_security_privilege_category";
14+
public static final String PRIVILEGE_CATEGORY_VALUE_OPERATOR = "operator";
1315

1416
private AuthenticationField() {}
1517
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
apply plugin: 'elasticsearch.esplugin'
2+
apply plugin: 'elasticsearch.java-rest-test'
3+
4+
esplugin {
5+
name 'operator-privileges-test'
6+
description 'An test plugin for testing hard to get internals'
7+
classname 'org.elasticsearch.xpack.security.operator.OperatorPrivilegesTestPlugin'
8+
}
9+
10+
dependencies {
11+
compileOnly project(':x-pack:plugin:core')
12+
javaRestTestImplementation project(':x-pack:plugin:core')
13+
javaRestTestImplementation project(':client:rest-high-level')
14+
javaRestTestImplementation project(':x-pack:plugin:security')
15+
// let the javaRestTest see the classpath of main
16+
javaRestTestImplementation project.sourceSets.main.runtimeClasspath
17+
}
18+
19+
testClusters.all {
20+
testDistribution = 'DEFAULT'
21+
numberOfNodes = 3
22+
23+
extraConfigFile 'operator_users.yml', file('src/javaRestTest/resources/operator_users.yml')
24+
extraConfigFile 'roles.yml', file('src/javaRestTest/resources/roles.yml')
25+
26+
setting 'xpack.license.self_generated.type', 'trial'
27+
setting 'xpack.security.enabled', 'true'
28+
setting 'xpack.security.http.ssl.enabled', 'false'
29+
setting 'xpack.security.operator_privileges.enabled', "true"
30+
31+
user username: "test_admin", password: 'x-pack-test-password', role: "superuser"
32+
user username: "test_operator", password: 'x-pack-test-password', role: "limited_operator"
33+
}

0 commit comments

Comments
 (0)