Skip to content

Commit 05ac3aa

Browse files
tvernumlegrego
andcommitted
Deprecating kibana_user and kibana_dashboard_only_user roles
This change adds a new `kibana_admin` role, and deprecates the old `kibana_user` and`kibana_dashboard_only_user`roles. The deprecation is implemented via a new reserved metadata attribute, which can be consumed from the API and also triggers deprecation logging when used (by a user authenticating to Elasticsearch). Some docs have been updated to avoid references to these deprecated roles. Backport of: elastic#46456 Co-authored-by: Tim Vernum <tim@adjective.org> Co-authored-by: Larry Gregory <legrego@users.noreply.github.com>
1 parent b02b073 commit 05ac3aa

File tree

13 files changed

+268
-77
lines changed

13 files changed

+268
-77
lines changed

client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,8 +693,8 @@ public void testGetRoles() throws Exception {
693693

694694
List<Role> roles = response.getRoles();
695695
assertNotNull(response);
696-
// 28 system roles plus the three we created
697-
assertThat(roles.size(), equalTo(28 + 3));
696+
// 29 system roles plus the three we created
697+
assertThat(roles.size(), equalTo(29 + 3));
698698
}
699699

700700
{

docs/reference/monitoring/configuring-filebeat.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ If {security-features} are enabled, you must provide a valid user ID and
117117
password so that {filebeat} can connect to {kib}:
118118

119119
.. Create a user on the monitoring cluster that has the
120-
<<built-in-roles,`kibana_user` built-in role>> or equivalent
120+
<<built-in-roles,`kibana_admin` built-in role>> or equivalent
121121
privileges.
122122

123123
.. Add the `username` and `password` settings to the {es} output information in

x-pack/docs/en/security/authentication/oidc-guide.asciidoc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,21 +418,25 @@ through either the
418418
NOTE: You cannot use <<mapping-roles-file,role mapping files>>
419419
to grant roles to users authenticating via OpenID Connect.
420420

421-
This is an example of a simple role mapping that grants the `kibana_user` role
421+
This is an example of a simple role mapping that grants the `example_role` role
422422
to any user who authenticates against the `oidc1` OpenID Connect realm:
423423

424424
[source,console]
425425
--------------------------------------------------
426-
PUT /_security/role_mapping/oidc-kibana
426+
PUT /_security/role_mapping/oidc-example
427427
{
428-
"roles": [ "kibana_user" ],
428+
"roles": [ "example_role" ], <1>
429429
"enabled": true,
430430
"rules": {
431431
"field": { "realm.name": "oidc1" }
432432
}
433433
}
434434
--------------------------------------------------
435435

436+
<1> The `example_role` role is *not* a builtin Elasticsearch role.
437+
This example assumes that you have created a custom role of your own, with
438+
appropriate access to your <<roles-indices-priv,indices>> and
439+
{kibana-ref}/kibana-privileges.html#kibana-feature-privileges[Kibana features].
436440

437441
The user properties that are mapped via the realm configuration are used to process
438442
role mapping rules, and these rules determine which roles a user is granted.

x-pack/docs/en/security/authentication/saml-guide.asciidoc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -631,21 +631,25 @@ through either the
631631
NOTE: You cannot use <<mapping-roles-file,role mapping files>>
632632
to grant roles to users authenticating via SAML.
633633

634-
This is an example of a simple role mapping that grants the `kibana_user` role
634+
This is an example of a simple role mapping that grants the `example_role` role
635635
to any user who authenticates against the `saml1` realm:
636636

637637
[source,console]
638638
--------------------------------------------------
639-
PUT /_security/role_mapping/saml-kibana
639+
PUT /_security/role_mapping/saml-example
640640
{
641-
"roles": [ "kibana_user" ],
641+
"roles": [ "example_role" ], <1>
642642
"enabled": true,
643643
"rules": {
644644
"field": { "realm.name": "saml1" }
645645
}
646646
}
647647
--------------------------------------------------
648648

649+
<1> The `example_role` role is *not* a builtin Elasticsearch role.
650+
This example assumes that you have created a custom role of your own, with
651+
appropriate access to your <<roles-indices-priv,indices>> and
652+
{kibana-ref}/kibana-privileges.html#kibana-feature-privileges[Kibana features].
649653

650654
The attributes that are mapped via the realm configuration are used to process
651655
role mapping rules, and these rules determine which roles a user is granted.

x-pack/docs/en/security/authorization/built-in-roles.asciidoc

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,12 @@ NOTE: This role does *not* provide the ability to create indices; those privileg
7272
must be defined in a separate role.
7373

7474
[[built-in-roles-kibana-dashboard]] `kibana_dashboard_only_user` ::
75-
Grants access to the {kib} Dashboard and read-only permissions to Kibana.
76-
This role does not have access to editing tools in {kib}. For more
77-
information, see
78-
{kibana-ref}/xpack-dashboard-only-mode.html[{kib} Dashboard Only Mode].
75+
(This role is deprecated, please use
76+
{kibana-ref}/kibana-privileges.html#kibana-feature-privileges[{kib} feature privileges]
77+
instead).
78+
Grants read-only access to the {kib} Dashboard in every
79+
{kibana-ref}/xpack-spaces.html[space in {kib}].
80+
This role does not have access to editing tools in {kib}.
7981

8082
[[built-in-roles-kibana-system]] `kibana_system` ::
8183
Grants access necessary for the {kib} system user to read from and write to the
@@ -87,9 +89,15 @@ see {kibana-ref}/using-kibana-with-security.html[Configuring Security in {kib}].
8789
NOTE: This role should not be assigned to users as the granted permissions may
8890
change between releases.
8991

92+
[[built-in-roles-kibana-admin]] `kibana_admin`::
93+
Grants access to all features in {kib}. For more information on {kib} authorization,
94+
see {kibana-ref}/xpack-security-authorization.html[Kibana authorization].
95+
9096
[[built-in-roles-kibana-user]] `kibana_user`::
91-
Grants access to all features in {kib}. For more information on Kibana authorization,
92-
see {kibana-ref}/xpack-security-authorization.html[Kibana Authorization].
97+
(This role is deprecated, please use the
98+
<<built-in-roles-kibana-admin,`kibana_admin`>> role instead.)
99+
Grants access to all features in {kib}. For more information on {kib} authorization,
100+
see {kibana-ref}/xpack-security-authorization.html[Kibana authorization].
93101

94102
[[built-in-roles-logstash-admin]] `logstash_admin` ::
95103
Grants access to the `.logstash*` indices for managing configurations.
@@ -127,7 +135,8 @@ Grants the minimum privileges required for any user of {monitoring} other than t
127135
required to use {kib}. This role grants access to the monitoring indices and grants
128136
privileges necessary for reading basic cluster information. This role also includes
129137
all {kibana-ref}/kibana-privileges.html[Kibana privileges] for the {stack-monitor-features}.
130-
Monitoring users should also be assigned the `kibana_user` role.
138+
Monitoring users should also be assigned the `kibana_admin` role, or another role
139+
with {kibana-ref}/xpack-security-authorization.html[access to the {kib} instance].
131140

132141
[[built-in-roles-remote-monitoring-agent]] `remote_monitoring_agent`::
133142
Grants the minimum privileges required to write data into the monitoring indices
@@ -140,9 +149,10 @@ Grants the minimum privileges required to collect monitoring data for the {stack
140149
[[built-in-roles-reporting-user]] `reporting_user`::
141150
Grants the specific privileges required for users of {reporting} other than those
142151
required to use {kib}. This role grants access to the reporting indices; each
143-
user has access to only their own reports. Reporting users should also be
144-
assigned the `kibana_user` role and a role that grants them access to the data
145-
that will be used to generate reports.
152+
user has access to only their own reports.
153+
Reporting users should also be assigned additional roles that grant
154+
{kibana-ref}/xpack-security-authorization.html[access to {kib}] as well as read
155+
access to the <<roles-indices-priv,indices>> that will be used to generate reports.
146156

147157
[[built-in-roles-snapshot-user]] `snapshot_user`::
148158
Grants the necessary privileges to create snapshots of **all** the indices and

x-pack/docs/en/security/ccs-clients-integrations/cross-cluster-kibana.asciidoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ NOTE: If you configure the local cluster as another remote in {es}, the
3131
`logstash_reader` role on your local cluster also needs to grant the
3232
`read_cross_cluster` privilege.
3333

34-
. Assign your {kib} users the `kibana_user` role and your `logstash_reader`
35-
role.
34+
. Assign your {kib} users a role that grants
35+
{kibana-ref}/xpack-security-authorization.html[access to {kib}]
36+
as well as your `logstash_reader` role.
3637

3738
. On the remote cluster, create a `logstash_reader` role that grants the
3839
`read_cross_cluster` privilege and `read` and `view_index_metadata` privileges

x-pack/docs/en/security/get-started-security.asciidoc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,16 @@ Select a role to see more information about its privileges. For example, select
167167
the `kibana_system` role to see its list of cluster and index privileges. To
168168
learn more, see <<privileges-list-indices>>.
169169

170-
Let's assign the `kibana_user` role to your user. Go back to the
171-
*Management / Security / Users* page and select your user. Add the `kibana_user`
170+
Let's assign the `kibana_admin` role to your user. Go back to the
171+
*Management / Security / Users* page and select your user. Add the `kibana_admin`
172172
role and save the change. For example:
173173

174174
[role="screenshot"]
175175
image::security/images/assign-role.jpg["Assigning a role to a user in Kibana"]
176176

177-
This user now has access to all features in {kib}. For more information about granting
178-
access to Kibana see {kibana-ref}/xpack-security-authorization.html[Kibana Authorization].
177+
This user now has administrative access to all features in {kib}.
178+
For more information about granting access to Kibana see
179+
{kibana-ref}/xpack-security-authorization.html[Kibana authorization].
179180

180181
If you completed all of the steps in
181182
{stack-gs}/get-started-elastic-stack.html[Getting started with the {stack}], you should

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,9 @@ private static Map<String, RoleDescriptor> initializeReservedRoles() {
5252
.put("superuser", SUPERUSER_ROLE_DESCRIPTOR)
5353
.put("transport_client", new RoleDescriptor("transport_client", new String[] { "transport_client" }, null, null,
5454
MetadataUtils.DEFAULT_RESERVED_METADATA))
55-
.put("kibana_user", new RoleDescriptor("kibana_user", null, null, new RoleDescriptor.ApplicationResourcePrivileges[] {
56-
RoleDescriptor.ApplicationResourcePrivileges.builder()
57-
.application("kibana-.kibana").resources("*").privileges("all").build() },
58-
null, null,
59-
MetadataUtils.DEFAULT_RESERVED_METADATA, null))
55+
.put("kibana_admin", kibanaAdminUser("kibana_admin", MetadataUtils.DEFAULT_RESERVED_METADATA))
56+
.put("kibana_user", kibanaAdminUser("kibana_user",
57+
MetadataUtils.getDeprecatedReservedMetadata("Please use the [kibana_admin] role instead")))
6058
.put("monitoring_user", new RoleDescriptor("monitoring_user",
6159
new String[] { "cluster:monitor/main", "cluster:monitor/xpack/info", RemoteInfoAction.NAME },
6260
new RoleDescriptor.IndicesPrivileges[] {
@@ -110,7 +108,7 @@ private static Map<String, RoleDescriptor> initializeReservedRoles() {
110108
RoleDescriptor.ApplicationResourcePrivileges.builder()
111109
.application("kibana-.kibana").resources("*").privileges("read").build() },
112110
null, null,
113-
MetadataUtils.DEFAULT_RESERVED_METADATA,
111+
MetadataUtils.getDeprecatedReservedMetadata("Please use Kibana feature privileges instead"),
114112
null))
115113
.put(KibanaUser.ROLE_NAME, new RoleDescriptor(KibanaUser.ROLE_NAME,
116114
new String[] {
@@ -266,6 +264,16 @@ private static Map<String, RoleDescriptor> initializeReservedRoles() {
266264
.immutableMap();
267265
}
268266

267+
private static RoleDescriptor kibanaAdminUser(String name, Map<String, Object> metadata) {
268+
return new RoleDescriptor(name, null, null,
269+
new RoleDescriptor.ApplicationResourcePrivileges[] {
270+
RoleDescriptor.ApplicationResourcePrivileges.builder()
271+
.application("kibana-.kibana")
272+
.resources("*").privileges("all")
273+
.build() },
274+
null, null, metadata, null);
275+
}
276+
269277
public static boolean isReserved(String role) {
270278
return RESERVED_ROLES.containsKey(role) || UsernamesField.SYSTEM_ROLE.equals(role) || UsernamesField.XPACK_ROLE.equals(role);
271279
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/support/MetadataUtils.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@
55
*/
66
package org.elasticsearch.xpack.core.security.support;
77

8+
import org.elasticsearch.common.collect.MapBuilder;
9+
810
import java.util.Collections;
911
import java.util.Map;
1012

1113
public class MetadataUtils {
1214

1315
public static final String RESERVED_PREFIX = "_";
1416
public static final String RESERVED_METADATA_KEY = RESERVED_PREFIX + "reserved";
17+
public static final String DEPRECATED_METADATA_KEY = RESERVED_PREFIX + "deprecated";
18+
public static final String DEPRECATED_REASON_METADATA_KEY = RESERVED_PREFIX + "deprecated_reason";
1519
public static final Map<String, Object> DEFAULT_RESERVED_METADATA = Collections.singletonMap(RESERVED_METADATA_KEY, true);
1620

1721
private MetadataUtils() {
@@ -25,4 +29,12 @@ public static boolean containsReservedMetadata(Map<String, Object> metadata) {
2529
}
2630
return false;
2731
}
32+
33+
public static Map<String, Object> getDeprecatedReservedMetadata(String reason) {
34+
return MapBuilder.<String, Object>newMapBuilder()
35+
.put(RESERVED_METADATA_KEY, true)
36+
.put(DEPRECATED_METADATA_KEY, true)
37+
.put(DEPRECATED_REASON_METADATA_KEY, reason)
38+
.immutableMap();
39+
}
2840
}

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@
169169

170170
import static org.hamcrest.Matchers.hasEntry;
171171
import static org.hamcrest.Matchers.is;
172+
import static org.hamcrest.Matchers.not;
172173
import static org.mockito.Mockito.mock;
173174

174175
/**
@@ -184,6 +185,7 @@ public void testIsReserved() {
184185
assertThat(ReservedRolesStore.isReserved("foobar"), is(false));
185186
assertThat(ReservedRolesStore.isReserved(SystemUser.ROLE_NAME), is(true));
186187
assertThat(ReservedRolesStore.isReserved("transport_client"), is(true));
188+
assertThat(ReservedRolesStore.isReserved("kibana_admin"), is(true));
187189
assertThat(ReservedRolesStore.isReserved("kibana_user"), is(true));
188190
assertThat(ReservedRolesStore.isReserved("ingest_admin"), is(true));
189191
assertThat(ReservedRolesStore.isReserved("monitoring_user"), is(true));
@@ -409,13 +411,62 @@ public void testKibanaSystemRole() {
409411
assertNoAccessAllowed(kibanaRole, RestrictedIndicesNames.ASYNC_SEARCH_PREFIX + randomAlphaOfLengthBetween(0, 2));
410412
}
411413

414+
public void testKibanaAdminRole() {
415+
final TransportRequest request = mock(TransportRequest.class);
416+
final Authentication authentication = mock(Authentication.class);
417+
418+
RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("kibana_admin");
419+
assertNotNull(roleDescriptor);
420+
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
421+
assertThat(roleDescriptor.getMetadata(), not(hasEntry("_deprecated", true)));
422+
423+
Role kibanaAdminRole = Role.builder(roleDescriptor, null).build();
424+
assertThat(kibanaAdminRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false));
425+
assertThat(kibanaAdminRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(false));
426+
assertThat(kibanaAdminRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(false));
427+
assertThat(kibanaAdminRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false));
428+
assertThat(kibanaAdminRole.cluster().check(ClusterRerouteAction.NAME, request, authentication), is(false));
429+
assertThat(kibanaAdminRole.cluster().check(ClusterUpdateSettingsAction.NAME, request, authentication),
430+
is(false));
431+
assertThat(kibanaAdminRole.cluster().check(MonitoringBulkAction.NAME, request, authentication), is(false));
432+
assertThat(kibanaAdminRole.cluster().check(DelegatePkiAuthenticationAction.NAME, request, authentication),
433+
is(false));
434+
435+
assertThat(kibanaAdminRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false));
436+
437+
assertThat(kibanaAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test("foo"), is(false));
438+
assertThat(kibanaAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(".reporting"), is(false));
439+
assertThat(
440+
kibanaAdminRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),
441+
is(false));
442+
443+
final String randomApplication = "kibana-" + randomAlphaOfLengthBetween(8, 24);
444+
assertThat(kibanaAdminRole.application().grants(new ApplicationPrivilege(randomApplication, "app-random", "all"),
445+
"*"), is(false));
446+
447+
final String application = "kibana-.kibana";
448+
assertThat(kibanaAdminRole.application().grants(new ApplicationPrivilege(application, "app-foo", "foo"), "*"),
449+
is(false));
450+
assertThat(kibanaAdminRole.application().grants(new ApplicationPrivilege(application, "app-all", "all"), "*"),
451+
is(true));
452+
453+
final String applicationWithRandomIndex = "kibana-.kibana_" + randomAlphaOfLengthBetween(8, 24);
454+
assertThat(
455+
kibanaAdminRole.application()
456+
.grants(new ApplicationPrivilege(applicationWithRandomIndex, "app-random-index", "all"), "*"),
457+
is(false));
458+
459+
assertNoAccessAllowed(kibanaAdminRole, RestrictedIndicesNames.RESTRICTED_NAMES);
460+
}
461+
412462
public void testKibanaUserRole() {
413463
final TransportRequest request = mock(TransportRequest.class);
414464
final Authentication authentication = mock(Authentication.class);
415465

416466
RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("kibana_user");
417467
assertNotNull(roleDescriptor);
418468
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
469+
assertThat(roleDescriptor.getMetadata(), hasEntry("_deprecated", true));
419470

420471
Role kibanaUserRole = Role.builder(roleDescriptor, null).build();
421472
assertThat(kibanaUserRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false));
@@ -745,6 +796,7 @@ public void testKibanaDashboardOnlyUserRole() {
745796
RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("kibana_dashboard_only_user");
746797
assertNotNull(roleDescriptor);
747798
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
799+
assertThat(roleDescriptor.getMetadata(), hasEntry("_deprecated", true));
748800

749801
Role dashboardsOnlyUserRole = Role.builder(roleDescriptor, null).build();
750802
assertThat(dashboardsOnlyUserRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false));

0 commit comments

Comments
 (0)