From f554d9e4c14cc5c87e24334bf4e06ea8772609fe Mon Sep 17 00:00:00 2001 From: kobelb Date: Mon, 16 Jul 2018 07:44:08 -0400 Subject: [PATCH 01/13] Changed kibaan_user and kibana_dashboard_only_user to use the app privs --- .../authz/store/ReservedRolesStore.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) 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 79c29b6e31268..bab672192bfdd 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 @@ -44,9 +44,10 @@ private static Map initializeReservedRoles() { MetadataUtils.DEFAULT_RESERVED_METADATA)) .put("transport_client", new RoleDescriptor("transport_client", new String[] { "transport_client" }, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA)) - .put("kibana_user", new RoleDescriptor("kibana_user", null, new RoleDescriptor.IndicesPrivileges[] { - RoleDescriptor.IndicesPrivileges.builder().indices(".kibana*").privileges("manage", "read", "index", "delete") - .build() }, null, MetadataUtils.DEFAULT_RESERVED_METADATA)) + .put("kibana_user", new RoleDescriptor("kibana_user", null, null, new RoleDescriptor.ApplicationResourcePrivileges[] { + RoleDescriptor.ApplicationResourcePrivileges.builder() + .application("kibana-.kibana").resources("*").privileges("all").build() }, + null, MetadataUtils.DEFAULT_RESERVED_METADATA, null)) .put("monitoring_user", new RoleDescriptor("monitoring_user", new String[] { "cluster:monitor/main" }, new RoleDescriptor.IndicesPrivileges[] { @@ -72,12 +73,13 @@ private static Map initializeReservedRoles() { .put("kibana_dashboard_only_user", new RoleDescriptor( "kibana_dashboard_only_user", null, - new RoleDescriptor.IndicesPrivileges[] { - RoleDescriptor.IndicesPrivileges.builder() - .indices(".kibana*").privileges("read", "view_index_metadata").build() - }, null, - MetadataUtils.DEFAULT_RESERVED_METADATA)) + new RoleDescriptor.ApplicationResourcePrivileges[] { + RoleDescriptor.ApplicationResourcePrivileges.builder() + .application("kibana-.kibana").resources("*").privileges("read").build() }, + null, + MetadataUtils.DEFAULT_RESERVED_METADATA, + null)) .put(KibanaUser.ROLE_NAME, new RoleDescriptor(KibanaUser.ROLE_NAME, new String[] { "monitor", "manage_index_templates", MonitoringBulkAction.NAME, "manage_saml", From 2e405149a80cd5971cfaa1624351befb9d099927 Mon Sep 17 00:00:00 2001 From: kobelb Date: Mon, 16 Jul 2018 09:47:25 -0400 Subject: [PATCH 02/13] Fixing ReservedRoleTests --- .../authz/store/ReservedRolesStoreTests.java | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java index 8bf9626f74b45..be9f56746d317 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java @@ -89,6 +89,7 @@ import org.elasticsearch.xpack.core.security.authz.accesscontrol.IndicesAccessControl.IndexAccessControl; import org.elasticsearch.xpack.core.security.authz.permission.FieldPermissionsCache; import org.elasticsearch.xpack.core.security.authz.permission.Role; +import org.elasticsearch.xpack.core.security.authz.privilege.ApplicationPrivilege; import org.elasticsearch.xpack.core.security.user.BeatsSystemUser; import org.elasticsearch.xpack.core.security.user.LogstashSystemUser; import org.elasticsearch.xpack.core.security.user.SystemUser; @@ -279,14 +280,18 @@ public void testKibanaUserRole() { assertThat(kibanaUserRole.indices().allowedIndicesMatcher("indices:foo").test(index), is(false)); assertThat(kibanaUserRole.indices().allowedIndicesMatcher("indices:bar").test(index), is(false)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(true)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(true)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(true)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(true)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(true)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(true)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(true)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(false)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(false)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(false)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(false)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(false)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(false)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(false)); }); + + assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege(randomAlphaOfLengthBetween(8, 24), "app-random", "all"), "*"), is(false)); + assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege("kibana-.kibana", "app-foo", "foo"), "*"), is(false)); + assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege("kibana-.kibana", "app-all", "all"), "*"), is(true)); } public void testMonitoringUserRole() { @@ -441,9 +446,14 @@ public void testKibanaDashboardOnlyUserRole() { assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(false)); assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(false)); - assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(index), is(true)); - assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(true)); - assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(true)); + assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(index), is(false)); + assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(false)); + assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(false)); + + assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(randomAlphaOfLengthBetween(8, 24), "app-random", "all"), "*"), is(false)); + assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege("kibana-.kibana", "app-foo", "foo"), "*"), is(false)); + assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege("kibana-.kibana", "app-all", "all"), "*"), is(false)); + assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege("kibana-.kibana", "app-read", "read"), "*"), is(true)); } public void testSuperuserRole() { From 57e5e2630703003498391e71a007b16a0ede5d1b Mon Sep 17 00:00:00 2001 From: kobelb Date: Wed, 18 Jul 2018 07:33:54 -0400 Subject: [PATCH 03/13] Fixing some style issues with the tests --- .../authz/store/ReservedRolesStoreTests.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java index be9f56746d317..436deff45e49d 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java @@ -289,9 +289,12 @@ public void testKibanaUserRole() { assertThat(kibanaUserRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(false)); }); - assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege(randomAlphaOfLengthBetween(8, 24), "app-random", "all"), "*"), is(false)); - assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege("kibana-.kibana", "app-foo", "foo"), "*"), is(false)); - assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege("kibana-.kibana", "app-all", "all"), "*"), is(true)); + final String randomApplication = "kibana-" + randomAlphaOfLengthBetween(8, 24); + assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege(randomApplication, "app-random", "all"), "*"), is(false)); + + final String application = "kibana-.kibana"; + assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege(application, "app-foo", "foo"), "*"), is(false)); + assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege(application, "app-all", "all"), "*"), is(true)); } public void testMonitoringUserRole() { @@ -450,10 +453,14 @@ public void testKibanaDashboardOnlyUserRole() { assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(false)); assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(false)); - assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(randomAlphaOfLengthBetween(8, 24), "app-random", "all"), "*"), is(false)); - assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege("kibana-.kibana", "app-foo", "foo"), "*"), is(false)); - assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege("kibana-.kibana", "app-all", "all"), "*"), is(false)); - assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege("kibana-.kibana", "app-read", "read"), "*"), is(true)); + final String randomApplication = "kibana-" + randomAlphaOfLengthBetween(8, 24); + assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(randomApplication, "app-random", "all"), "*"), + is(false)); + + final String application = "kibana-.kibana"; + assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(application, "app-foo", "foo"), "*"), is(false)); + assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(application, "app-all", "all"), "*"), is(false)); + assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(application, "app-read", "read"), "*"), is(true)); } public void testSuperuserRole() { From 937ec7caeb070f85194ff10670cf32e42ec89e05 Mon Sep 17 00:00:00 2001 From: kobelb Date: Wed, 18 Jul 2018 13:25:32 -0400 Subject: [PATCH 04/13] Adding the action to the patterns if there are no descriptors --- .../core/security/authz/privilege/ApplicationPrivilege.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ApplicationPrivilege.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ApplicationPrivilege.java index 52f283b6b4377..c810d61333f5c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ApplicationPrivilege.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ApplicationPrivilege.java @@ -193,7 +193,7 @@ private static ApplicationPrivilege resolve(String application, Set name if (descriptor != null) { patterns.addAll(descriptor.getActions()); } else { - throw new IllegalArgumentException("unknown application privilege [" + name + "]"); + patterns.add(name); } } else { actions.add(name); From 57b2e03302588c89d84a87ff8fe8a0c1d31c1386 Mon Sep 17 00:00:00 2001 From: kobelb Date: Thu, 19 Jul 2018 06:23:28 -0400 Subject: [PATCH 05/13] KibanaUserRoleIntegTests now inherits from NativeRealmIntegTestCase This causes the test to properly close the security index in the @after to ensure we aren't leaving the .security index open --- .../elasticsearch/integration/KibanaUserRoleIntegTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java index cc080a846fae3..818143c5854b1 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java @@ -20,7 +20,7 @@ import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.test.SecurityIntegTestCase; +import org.elasticsearch.test.NativeRealmIntegTestCase; import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken; import java.util.Locale; @@ -36,7 +36,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; -public class KibanaUserRoleIntegTests extends SecurityIntegTestCase { +public class KibanaUserRoleIntegTests extends NativeRealmIntegTestCase { protected static final SecureString USERS_PASSWD = new SecureString("change_me".toCharArray()); From 2ceefc1c75a2aed6f5045708db018b64afbbc5b4 Mon Sep 17 00:00:00 2001 From: kobelb Date: Thu, 19 Jul 2018 06:29:42 -0400 Subject: [PATCH 06/13] Switching the AuditTrailTests to use monitoring_user This way the test doesn't transiently load the .security index because it has application privileges and need to close the index when it's done --- .../xpack/security/audit/index/AuditTrailTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/index/AuditTrailTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/index/AuditTrailTests.java index 7d4469133687e..453820ea519fc 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/index/AuditTrailTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/index/AuditTrailTests.java @@ -79,7 +79,7 @@ public String configUsers() { public String configUsersRoles() { return super.configUsersRoles() + ROLE_CAN_RUN_AS + ":" + AUTHENTICATE_USER + "\n" - + "kibana_user:" + EXECUTE_USER; + + "monitoring_user:" + EXECUTE_USER; } @Override From eb6188c2ddd7cbdb8f42692187a82acf7e2b7990 Mon Sep 17 00:00:00 2001 From: kobelb Date: Thu, 19 Jul 2018 06:47:29 -0400 Subject: [PATCH 07/13] kibana_user can no longer create indexes, or index documents --- .../integration/KibanaUserRoleIntegTests.java | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java index 818143c5854b1..1986fecdb032c 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.integration; +import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.get.GetIndexResponse; @@ -153,27 +154,32 @@ public void testCreateIndexDeleteInKibanaIndex() throws Exception { final String index = randomBoolean()? ".kibana" : ".kibana-" + randomAlphaOfLengthBetween(1, 10).toLowerCase(Locale.ENGLISH); if (randomBoolean()) { - CreateIndexResponse createIndexResponse = client().filterWithHeader(singletonMap("Authorization", + expectThrows(ElasticsearchSecurityException.class, () -> + client().filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) - .admin().indices().prepareCreate(index).get(); - assertThat(createIndexResponse.isAcknowledged(), is(true)); + .admin().indices().prepareCreate(index).get() + ); } - IndexResponse response = client() + final String id = randomBoolean()? "dashboard" : "dashboard-" + randomAlphaOfLengthBetween(1, 10).toLowerCase(Locale.ENGLISH); + expectThrows(ElasticsearchSecurityException.class, () -> + client() + .filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) + .prepareIndex() + .setIndex(index) + .setId(id) + .setType("dashboard") + .setSource("foo", "bar") + .setRefreshPolicy(IMMEDIATE) + .get() + ); + + expectThrows(ElasticsearchSecurityException.class, () -> + client() .filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) - .prepareIndex() - .setIndex(index) - .setType("dashboard") - .setSource("foo", "bar") - .setRefreshPolicy(IMMEDIATE) - .get(); - assertEquals(DocWriteResponse.Result.CREATED, response.getResult()); - - DeleteResponse deleteResponse = client() - .filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) - .prepareDelete(index, "dashboard", response.getId()) - .get(); - assertEquals(DocWriteResponse.Result.DELETED, deleteResponse.getResult()); + .prepareDelete(index, "dashboard", id) + .get() + ); } public void testGetMappings() throws Exception { From 27dabc6ba3f603b57406ffcb3b262d30dba4000a Mon Sep 17 00:00:00 2001 From: kobelb Date: Thu, 19 Jul 2018 09:05:28 -0400 Subject: [PATCH 08/13] Deleting unused imports --- .../KibanaSystemRoleIntegTests.java | 66 +++++++++++++++++++ .../integration/KibanaUserRoleIntegTests.java | 4 -- 2 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaSystemRoleIntegTests.java diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaSystemRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaSystemRoleIntegTests.java new file mode 100644 index 0000000000000..65fa6027c627b --- /dev/null +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaSystemRoleIntegTests.java @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.integration; + +import org.elasticsearch.action.DocWriteResponse; +import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; +import org.elasticsearch.action.delete.DeleteResponse; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.test.SecurityIntegTestCase; +import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken; + +import java.util.Locale; + +import static java.util.Collections.singletonMap; +import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; +import static org.hamcrest.Matchers.is; + +public class KibanaSystemRoleIntegTests extends SecurityIntegTestCase { + + protected static final SecureString USERS_PASSWD = new SecureString("change_me".toCharArray()); + + @Override + public String configUsers() { + final String usersPasswdHashed = new String(getFastStoredHashAlgoForTests().hash(USERS_PASSWD)); + return super.configUsers() + + "kibana_system:" + usersPasswdHashed; + } + + @Override + public String configUsersRoles() { + return super.configUsersRoles() + + "kibana_system:kibana_system"; + } + + + public void testCreateIndexDeleteInKibanaIndex() throws Exception { + final String index = randomBoolean()? ".kibana" : ".kibana-" + randomAlphaOfLengthBetween(1, 10).toLowerCase(Locale.ENGLISH); + + if (randomBoolean()) { + CreateIndexResponse createIndexResponse = client().filterWithHeader(singletonMap("Authorization", + UsernamePasswordToken.basicAuthHeaderValue("kibana_system", USERS_PASSWD))) + .admin().indices().prepareCreate(index).get(); + assertThat(createIndexResponse.isAcknowledged(), is(true)); + } + + IndexResponse response = client() + .filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_system", USERS_PASSWD))) + .prepareIndex() + .setIndex(index) + .setType("dashboard") + .setSource("foo", "bar") + .setRefreshPolicy(IMMEDIATE) + .get(); + assertEquals(DocWriteResponse.Result.CREATED, response.getResult()); + + DeleteResponse deleteResponse = client() + .filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_system", USERS_PASSWD))) + .prepareDelete(index, "dashboard", response.getId()) + .get(); + assertEquals(DocWriteResponse.Result.DELETED, deleteResponse.getResult()); + } +} diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java index 1986fecdb032c..1cd7b3e0ce1ed 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java @@ -6,15 +6,11 @@ package org.elasticsearch.integration; import org.elasticsearch.ElasticsearchSecurityException; -import org.elasticsearch.action.DocWriteResponse; -import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.get.GetIndexResponse; import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse; import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData; import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; import org.elasticsearch.action.admin.indices.validate.query.ValidateQueryResponse; -import org.elasticsearch.action.delete.DeleteResponse; -import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.cluster.metadata.MappingMetaData; From fb882e6174a14e7e9ccb6d2e9fbb609e30f3c47f Mon Sep 17 00:00:00 2001 From: kobelb Date: Fri, 20 Jul 2018 09:01:35 -0400 Subject: [PATCH 09/13] Assigning both index and application privileges --- .../authz/store/ReservedRolesStore.java | 15 ++++-- .../authz/store/ReservedRolesStoreTests.java | 34 +++++++++----- .../integration/KibanaUserRoleIntegTests.java | 47 +++++++++---------- 3 files changed, 54 insertions(+), 42 deletions(-) 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 bab672192bfdd..a40c254c0e122 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 @@ -44,10 +44,12 @@ private static Map initializeReservedRoles() { MetadataUtils.DEFAULT_RESERVED_METADATA)) .put("transport_client", new RoleDescriptor("transport_client", new String[] { "transport_client" }, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA)) - .put("kibana_user", new RoleDescriptor("kibana_user", null, null, new RoleDescriptor.ApplicationResourcePrivileges[] { - RoleDescriptor.ApplicationResourcePrivileges.builder() - .application("kibana-.kibana").resources("*").privileges("all").build() }, - null, MetadataUtils.DEFAULT_RESERVED_METADATA, null)) + .put("kibana_user", new RoleDescriptor("kibana_user", null, new RoleDescriptor.IndicesPrivileges[] { + RoleDescriptor.IndicesPrivileges.builder().indices(".kibana*").privileges("manage", "read", "index", "delete") + .build() }, new RoleDescriptor.ApplicationResourcePrivileges[] { + RoleDescriptor.ApplicationResourcePrivileges.builder() + .application("kibana-.kibana").resources("*").privileges("all").build() }, + null, MetadataUtils.DEFAULT_RESERVED_METADATA, null)) .put("monitoring_user", new RoleDescriptor("monitoring_user", new String[] { "cluster:monitor/main" }, new RoleDescriptor.IndicesPrivileges[] { @@ -73,7 +75,10 @@ private static Map initializeReservedRoles() { .put("kibana_dashboard_only_user", new RoleDescriptor( "kibana_dashboard_only_user", null, - null, + new RoleDescriptor.IndicesPrivileges[] { + RoleDescriptor.IndicesPrivileges.builder() + .indices(".kibana*").privileges("read", "view_index_metadata").build() + }, new RoleDescriptor.ApplicationResourcePrivileges[] { RoleDescriptor.ApplicationResourcePrivileges.builder() .application("kibana-.kibana").resources("*").privileges("read").build() }, diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java index 436deff45e49d..8d1a2692a0853 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java @@ -277,16 +277,16 @@ public void testKibanaUserRole() { Arrays.asList(".kibana", ".kibana-devnull").forEach((index) -> { logger.info("index name [{}]", index); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher("indices:foo").test(index), is(false)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher("indices:bar").test(index), is(false)); - - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(false)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(false)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(false)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(false)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(false)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(false)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(false)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher("indices:foo").test(index), is(true)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher("indices:bar").test(index), is(true)); + + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(true)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(true)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(true)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(true)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(true)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(true)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(true)); }); final String randomApplication = "kibana-" + randomAlphaOfLengthBetween(8, 24); @@ -295,6 +295,10 @@ public void testKibanaUserRole() { final String application = "kibana-.kibana"; assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege(application, "app-foo", "foo"), "*"), is(false)); assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege(application, "app-all", "all"), "*"), is(true)); + + final String applicationWithRandomIndex = "kibana-.kibana_" + randomAlphaOfLengthBetween(8, 24); + assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege(applicationWithRandomIndex, "app-random-index", "all"), + "*"), is(false)); } public void testMonitoringUserRole() { @@ -449,9 +453,9 @@ public void testKibanaDashboardOnlyUserRole() { assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(false)); assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(false)); - assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(index), is(false)); - assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(false)); - assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(false)); + assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(index), is(true)); + assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(true)); + assertThat(dashboardsOnlyUserRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(true)); final String randomApplication = "kibana-" + randomAlphaOfLengthBetween(8, 24); assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(randomApplication, "app-random", "all"), "*"), @@ -461,6 +465,10 @@ public void testKibanaDashboardOnlyUserRole() { assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(application, "app-foo", "foo"), "*"), is(false)); assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(application, "app-all", "all"), "*"), is(false)); assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(application, "app-read", "read"), "*"), is(true)); + + final String applicationWithRandomIndex = "kibana-.kibana_" + randomAlphaOfLengthBetween(8, 24); + assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(applicationWithRandomIndex, "app-random-index", "all"), "*"), + is(false)); } public void testSuperuserRole() { diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java index 1cd7b3e0ce1ed..d2ecb35cc1bee 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java @@ -6,11 +6,15 @@ package org.elasticsearch.integration; import org.elasticsearch.ElasticsearchSecurityException; +import org.elasticsearch.action.DocWriteResponse; +import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.get.GetIndexResponse; import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse; import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData; import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; import org.elasticsearch.action.admin.indices.validate.query.ValidateQueryResponse; +import org.elasticsearch.action.delete.DeleteResponse; +import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.cluster.metadata.MappingMetaData; @@ -150,32 +154,27 @@ public void testCreateIndexDeleteInKibanaIndex() throws Exception { final String index = randomBoolean()? ".kibana" : ".kibana-" + randomAlphaOfLengthBetween(1, 10).toLowerCase(Locale.ENGLISH); if (randomBoolean()) { - expectThrows(ElasticsearchSecurityException.class, () -> - client().filterWithHeader(singletonMap("Authorization", - UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) - .admin().indices().prepareCreate(index).get() - ); + CreateIndexResponse createIndexResponse = client().filterWithHeader(singletonMap("Authorization", + UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) + .admin().indices().prepareCreate(index).get(); + assertThat(createIndexResponse.isAcknowledged(), is(true)); } - final String id = randomBoolean()? "dashboard" : "dashboard-" + randomAlphaOfLengthBetween(1, 10).toLowerCase(Locale.ENGLISH); - expectThrows(ElasticsearchSecurityException.class, () -> - client() - .filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) - .prepareIndex() - .setIndex(index) - .setId(id) - .setType("dashboard") - .setSource("foo", "bar") - .setRefreshPolicy(IMMEDIATE) - .get() - ); - - expectThrows(ElasticsearchSecurityException.class, () -> - client() - .filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) - .prepareDelete(index, "dashboard", id) - .get() - ); + IndexResponse response = client() + .filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) + .prepareIndex() + .setIndex(index) + .setType("dashboard") + .setSource("foo", "bar") + .setRefreshPolicy(IMMEDIATE) + .get(); + assertEquals(DocWriteResponse.Result.CREATED, response.getResult()); + + DeleteResponse deleteResponse = client() + .filterWithHeader(singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD))) + .prepareDelete(index, "dashboard", response.getId()) + .get(); + assertEquals(DocWriteResponse.Result.DELETED, deleteResponse.getResult()); } public void testGetMappings() throws Exception { From cff5d8a484cde82aa8a47f82d4f29c8426d08950 Mon Sep 17 00:00:00 2001 From: Tim Vernum Date: Mon, 23 Jul 2018 16:33:54 +1000 Subject: [PATCH 10/13] Fix line length --- .../core/security/authz/store/ReservedRolesStoreTests.java | 4 ++-- .../elasticsearch/integration/KibanaUserRoleIntegTests.java | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java index 8d1a2692a0853..6f75011ca2bf3 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java @@ -467,8 +467,8 @@ public void testKibanaDashboardOnlyUserRole() { assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(application, "app-read", "read"), "*"), is(true)); final String applicationWithRandomIndex = "kibana-.kibana_" + randomAlphaOfLengthBetween(8, 24); - assertThat(dashboardsOnlyUserRole.application().grants(new ApplicationPrivilege(applicationWithRandomIndex, "app-random-index", "all"), "*"), - is(false)); + assertThat(dashboardsOnlyUserRole.application().grants( + new ApplicationPrivilege(applicationWithRandomIndex, "app-random-index", "all"), "*"), is(false)); } public void testSuperuserRole() { diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java index d2ecb35cc1bee..b5b939e174410 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java @@ -5,7 +5,6 @@ */ package org.elasticsearch.integration; -import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.get.GetIndexResponse; From 15398ce715c6eac325960198ccbc9efdc4cf66f7 Mon Sep 17 00:00:00 2001 From: Tim Vernum Date: Mon, 23 Jul 2018 17:16:27 +1000 Subject: [PATCH 11/13] Fix bad merge --- .../xpack/core/security/authz/store/ReservedRolesStore.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 462af45a62724..0c59343636553 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 @@ -51,7 +51,8 @@ private static Map initializeReservedRoles() { .build() }, new RoleDescriptor.ApplicationResourcePrivileges[] { RoleDescriptor.ApplicationResourcePrivileges.builder() .application("kibana-.kibana").resources("*").privileges("all").build() }, - null, MetadataUtils.DEFAULT_RESERVED_METADATA, null)) + null, null, + MetadataUtils.DEFAULT_RESERVED_METADATA, null)) .put("monitoring_user", new RoleDescriptor("monitoring_user", new String[] { "cluster:monitor/main" }, new RoleDescriptor.IndicesPrivileges[] { @@ -84,7 +85,7 @@ private static Map initializeReservedRoles() { new RoleDescriptor.ApplicationResourcePrivileges[] { RoleDescriptor.ApplicationResourcePrivileges.builder() .application("kibana-.kibana").resources("*").privileges("read").build() }, - null, + null, null, MetadataUtils.DEFAULT_RESERVED_METADATA, null)) .put(KibanaUser.ROLE_NAME, new RoleDescriptor(KibanaUser.ROLE_NAME, From 73682da066060d57ba8af78d1bd23c231eeb91cc Mon Sep 17 00:00:00 2001 From: kobelb Date: Mon, 23 Jul 2018 07:22:25 -0400 Subject: [PATCH 12/13] No longer adding privilege to actions when it has no actions --- .../core/security/authz/privilege/ApplicationPrivilege.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ApplicationPrivilege.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ApplicationPrivilege.java index c810d61333f5c..2378f6037adf4 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ApplicationPrivilege.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ApplicationPrivilege.java @@ -192,8 +192,6 @@ private static ApplicationPrivilege resolve(String application, Set name ApplicationPrivilegeDescriptor descriptor = lookup.get(name); if (descriptor != null) { patterns.addAll(descriptor.getActions()); - } else { - patterns.add(name); } } else { actions.add(name); From a0b046dbada1c8d305409af3351cf5d23fe8d533 Mon Sep 17 00:00:00 2001 From: kobelb Date: Mon, 23 Jul 2018 12:00:27 -0400 Subject: [PATCH 13/13] Putting test back how it was --- .../core/security/authz/store/ReservedRolesStoreTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java index 95a5a7382caab..9cb5e25c5b8d1 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java @@ -299,8 +299,8 @@ public void testKibanaUserRole() { Arrays.asList(".kibana", ".kibana-devnull").forEach((index) -> { logger.info("index name [{}]", index); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher("indices:foo").test(index), is(true)); - assertThat(kibanaUserRole.indices().allowedIndicesMatcher("indices:bar").test(index), is(true)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher("indices:foo").test(index), is(false)); + assertThat(kibanaUserRole.indices().allowedIndicesMatcher("indices:bar").test(index), is(false)); assertThat(kibanaUserRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(true)); assertThat(kibanaUserRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(true));