Skip to content

Commit fa4869a

Browse files
legregotvernum
andcommitted
Deprecating kibana_user and kibana_dashboard_only_user roles (#46456)
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. Co-authored-by: Tim Vernum <[email protected]> Co-authored-by: Larry Gregory <[email protected]>
1 parent 75b68fa commit fa4869a

File tree

13 files changed

+267
-77
lines changed

13 files changed

+267
-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
@@ -694,8 +694,8 @@ public void testGetRoles() throws Exception {
694694

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

701701
{

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
@@ -420,21 +420,25 @@ through either the
420420
NOTE: You cannot use <<mapping-roles-file,role mapping files>>
421421
to grant roles to users authenticating via OpenID Connect.
422422

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

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

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

439443
The user properties that are mapped via the realm configuration are used to process
440444
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
@@ -639,21 +639,25 @@ through either the
639639
NOTE: You cannot use <<mapping-roles-file,role mapping files>>
640640
to grant roles to users authenticating via SAML.
641641

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

645645
[source,console]
646646
--------------------------------------------------
647-
PUT /_security/role_mapping/saml-kibana
647+
PUT /_security/role_mapping/saml-example
648648
{
649-
"roles": [ "kibana_user" ],
649+
"roles": [ "example_role" ], <1>
650650
"enabled": true,
651651
"rules": {
652652
"field": { "realm.name": "saml1" }
653653
}
654654
}
655655
--------------------------------------------------
656656

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

658662
The attributes that are mapped via the realm configuration are used to process
659663
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
@@ -168,15 +168,16 @@ Select a role to see more information about its privileges. For example, select
168168
the `kibana_system` role to see its list of cluster and index privileges. To
169169
learn more, see <<privileges-list-indices>>.
170170

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

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

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

181182
If you completed all of the steps in
182183
{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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public class MetadataUtils {
1111

1212
public static final String RESERVED_PREFIX = "_";
1313
public static final String RESERVED_METADATA_KEY = RESERVED_PREFIX + "reserved";
14+
public static final String DEPRECATED_METADATA_KEY = RESERVED_PREFIX + "deprecated";
15+
public static final String DEPRECATED_REASON_METADATA_KEY = RESERVED_PREFIX + "deprecated_reason";
1416
public static final Map<String, Object> DEFAULT_RESERVED_METADATA = Map.of(RESERVED_METADATA_KEY, true);
1517

1618
private MetadataUtils() {
@@ -24,4 +26,12 @@ public static boolean containsReservedMetadata(Map<String, Object> metadata) {
2426
}
2527
return false;
2628
}
29+
30+
public static Map<String, Object> getDeprecatedReservedMetadata(String reason) {
31+
return Map.of(
32+
RESERVED_METADATA_KEY, true,
33+
DEPRECATED_METADATA_KEY, true,
34+
DEPRECATED_REASON_METADATA_KEY, reason
35+
);
36+
}
2737
}

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)