security: add a built-in role for reporting

This commit adds a built-in role that grants read and write privileges to the reporting
indices.

See elastic/elasticsearch#2374
Closes elastic/elasticsearch#3196

Original commit: elastic/x-pack-elasticsearch@c8c1b465f8
This commit is contained in:
jaymode 2016-09-07 08:20:54 -04:00
parent c6b6e457c2
commit 5f4e6164e5
4 changed files with 128 additions and 5 deletions

View File

@ -0,0 +1,34 @@
/*
* 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.xpack.security.authz.permission;
import org.elasticsearch.xpack.security.authz.RoleDescriptor;
import org.elasticsearch.xpack.security.authz.permission.ClusterPermission.Core;
import org.elasticsearch.xpack.security.support.MetadataUtils;
/**
* A role for users of the reporting features in xpack
*/
public class ReportingUserRole extends Role {
private static final RoleDescriptor.IndicesPrivileges[] INDICES_PRIVILEGES = new RoleDescriptor.IndicesPrivileges[] {
RoleDescriptor.IndicesPrivileges.builder()
.indices(".reporting-*")
.privileges("read", "write")
.build()
};
public static final String NAME = "reporting_user";
public static final RoleDescriptor DESCRIPTOR =
new RoleDescriptor(NAME, null, INDICES_PRIVILEGES, null, MetadataUtils.DEFAULT_RESERVED_METADATA);
public static final ReportingUserRole INSTANCE = new ReportingUserRole();
private ReportingUserRole() {
super(DESCRIPTOR.getName(),
Core.NONE,
new IndicesPermission.Core(Role.Builder.convertFromIndicesPrivileges(DESCRIPTOR.getIndicesPrivileges())),
RunAsPermission.Core.NONE);
}
}

View File

@ -19,6 +19,7 @@ import org.elasticsearch.xpack.security.authz.permission.KibanaRole;
import org.elasticsearch.xpack.security.authz.permission.KibanaUserRole;
import org.elasticsearch.xpack.security.authz.permission.MonitoringUserRole;
import org.elasticsearch.xpack.security.authz.permission.RemoteMonitoringAgentRole;
import org.elasticsearch.xpack.security.authz.permission.ReportingUserRole;
import org.elasticsearch.xpack.security.authz.permission.Role;
import org.elasticsearch.xpack.security.authz.permission.SuperuserRole;
import org.elasticsearch.xpack.security.authz.permission.TransportClientRole;
@ -53,6 +54,8 @@ public class ReservedRolesStore implements RolesStore {
return RemoteMonitoringAgentRole.INSTANCE;
case IngestAdminRole.NAME:
return IngestAdminRole.INSTANCE;
case ReportingUserRole.NAME:
return ReportingUserRole.INSTANCE;
case KibanaRole.NAME:
// The only user that should know about this role is the kibana user itself (who has this role). The reason we want to hide
// this role is that it was created specifically for kibana, with all the permissions that the kibana user needs.
@ -86,6 +89,8 @@ public class ReservedRolesStore implements RolesStore {
return RemoteMonitoringAgentRole.DESCRIPTOR;
case IngestAdminRole.NAME:
return IngestAdminRole.DESCRIPTOR;
case ReportingUserRole.NAME:
return ReportingUserRole.DESCRIPTOR;
case KibanaRole.NAME:
// The only user that should know about this role is the kibana user itself (who has this role). The reason we want to hide
// this role is that it was created specifically for kibana, with all the permissions that the kibana user needs.
@ -103,15 +108,16 @@ public class ReservedRolesStore implements RolesStore {
if (DEFAULT_ENABLED_KIBANA_USER.equals(securityContext.getUser())) {
return Arrays.asList(SuperuserRole.DESCRIPTOR, TransportClientRole.DESCRIPTOR, KibanaUserRole.DESCRIPTOR,
KibanaRole.DESCRIPTOR, MonitoringUserRole.DESCRIPTOR, RemoteMonitoringAgentRole.DESCRIPTOR,
IngestAdminRole.DESCRIPTOR);
IngestAdminRole.DESCRIPTOR, ReportingUserRole.DESCRIPTOR);
}
return Arrays.asList(SuperuserRole.DESCRIPTOR, TransportClientRole.DESCRIPTOR, KibanaUserRole.DESCRIPTOR,
MonitoringUserRole.DESCRIPTOR, RemoteMonitoringAgentRole.DESCRIPTOR, IngestAdminRole.DESCRIPTOR);
MonitoringUserRole.DESCRIPTOR, RemoteMonitoringAgentRole.DESCRIPTOR, IngestAdminRole.DESCRIPTOR,
ReportingUserRole.DESCRIPTOR);
}
public static Set<String> names() {
return Sets.newHashSet(SuperuserRole.NAME, KibanaRole.NAME, TransportClientRole.NAME, KibanaUserRole.NAME,
MonitoringUserRole.NAME, RemoteMonitoringAgentRole.NAME, IngestAdminRole.NAME);
MonitoringUserRole.NAME, RemoteMonitoringAgentRole.NAME, IngestAdminRole.NAME, ReportingUserRole.NAME);
}
public static boolean isReserved(String role) {
@ -124,6 +130,7 @@ public class ReservedRolesStore implements RolesStore {
case RemoteMonitoringAgentRole.NAME:
case SystemUser.ROLE_NAME:
case IngestAdminRole.NAME:
case ReportingUserRole.NAME:
return true;
default:
return false;

View File

@ -0,0 +1,74 @@
/*
* 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.xpack.security.authz.permission;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction;
import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteAction;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsAction;
import org.elasticsearch.action.admin.cluster.state.ClusterStateAction;
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction;
import org.elasticsearch.action.admin.indices.create.CreateIndexAction;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsAction;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateAction;
import org.elasticsearch.action.bulk.BulkAction;
import org.elasticsearch.action.delete.DeleteAction;
import org.elasticsearch.action.get.GetAction;
import org.elasticsearch.action.index.IndexAction;
import org.elasticsearch.action.search.SearchAction;
import org.elasticsearch.action.update.UpdateAction;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.transport.TransportRequest;
import org.elasticsearch.xpack.monitoring.action.MonitoringBulkAction;
import org.elasticsearch.xpack.security.authc.Authentication;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;
/**
* Unit tests for the built in reporting user role
*/
public class ReportingUserRoleTests extends ESTestCase {
public void testCluster() {
final TransportRequest request = new TransportRequest.Empty();
final Authentication authentication = mock(Authentication.class);
assertThat(ReportingUserRole.INSTANCE.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false));
assertThat(ReportingUserRole.INSTANCE.cluster().check(ClusterStateAction.NAME, request, authentication), is(false));
assertThat(ReportingUserRole.INSTANCE.cluster().check(ClusterStatsAction.NAME, request, authentication), is(false));
assertThat(ReportingUserRole.INSTANCE.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false));
assertThat(ReportingUserRole.INSTANCE.cluster().check(ClusterRerouteAction.NAME, request, authentication), is(false));
assertThat(ReportingUserRole.INSTANCE.cluster().check(ClusterUpdateSettingsAction.NAME, request, authentication), is(false));
assertThat(ReportingUserRole.INSTANCE.cluster().check(MonitoringBulkAction.NAME, request, authentication), is(false));
}
public void testRunAs() {
assertThat(ReportingUserRole.INSTANCE.runAs().isEmpty(), is(true));
}
public void testUnauthorizedIndices() {
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(SearchAction.NAME).test("foo"), is(false));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(SearchAction.NAME).test(".reporting"), is(false));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(SearchAction.NAME).test(".kibana"), is(false));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher("indices:foo").test(randomAsciiOfLengthBetween(8, 24)),
is(false));
}
public void testReadWriteAccess() {
final String index = ".reporting-" + randomAsciiOfLength(randomIntBetween(0, 13));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher("indices:foo").test(index), is(false));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher("indices:bar").test(index), is(false));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(false));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(false));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(false));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(true));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(true));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(UpdateAction.NAME).test(index), is(true));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(true));
assertThat(ReportingUserRole.INSTANCE.indices().allowedIndicesMatcher(BulkAction.NAME).test(index), is(true));
}
}

View File

@ -11,6 +11,7 @@ import org.elasticsearch.xpack.security.authz.permission.KibanaRole;
import org.elasticsearch.xpack.security.authz.permission.KibanaUserRole;
import org.elasticsearch.xpack.security.authz.permission.MonitoringUserRole;
import org.elasticsearch.xpack.security.authz.permission.RemoteMonitoringAgentRole;
import org.elasticsearch.xpack.security.authz.permission.ReportingUserRole;
import org.elasticsearch.xpack.security.authz.permission.SuperuserRole;
import org.elasticsearch.xpack.security.authz.permission.TransportClientRole;
import org.elasticsearch.xpack.security.user.ElasticUser;
@ -66,9 +67,12 @@ public class ReservedRolesStoreTests extends ESTestCase {
assertThat(reservedRolesStore.role(RemoteMonitoringAgentRole.NAME), sameInstance(RemoteMonitoringAgentRole.INSTANCE));
assertThat(reservedRolesStore.roleDescriptor(RemoteMonitoringAgentRole.NAME), sameInstance(RemoteMonitoringAgentRole.DESCRIPTOR));
assertThat(reservedRolesStore.role(ReportingUserRole.NAME), sameInstance(ReportingUserRole.INSTANCE));
assertThat(reservedRolesStore.roleDescriptor(ReportingUserRole.NAME), sameInstance(ReportingUserRole.DESCRIPTOR));
assertThat(reservedRolesStore.roleDescriptors(), contains(SuperuserRole.DESCRIPTOR, TransportClientRole.DESCRIPTOR,
KibanaUserRole.DESCRIPTOR, MonitoringUserRole.DESCRIPTOR, RemoteMonitoringAgentRole.DESCRIPTOR,
IngestAdminRole.DESCRIPTOR));
IngestAdminRole.DESCRIPTOR, ReportingUserRole.DESCRIPTOR));
assertThat(reservedRolesStore.role(KibanaRole.NAME), nullValue());
assertThat(reservedRolesStore.roleDescriptor(KibanaRole.NAME), nullValue());
@ -99,9 +103,12 @@ public class ReservedRolesStoreTests extends ESTestCase {
assertThat(reservedRolesStore.role(RemoteMonitoringAgentRole.NAME), sameInstance(RemoteMonitoringAgentRole.INSTANCE));
assertThat(reservedRolesStore.roleDescriptor(RemoteMonitoringAgentRole.NAME), sameInstance(RemoteMonitoringAgentRole.DESCRIPTOR));
assertThat(reservedRolesStore.role(ReportingUserRole.NAME), sameInstance(ReportingUserRole.INSTANCE));
assertThat(reservedRolesStore.roleDescriptor(ReportingUserRole.NAME), sameInstance(ReportingUserRole.DESCRIPTOR));
assertThat(reservedRolesStore.roleDescriptors(), contains(SuperuserRole.DESCRIPTOR, TransportClientRole.DESCRIPTOR,
KibanaUserRole.DESCRIPTOR, KibanaRole.DESCRIPTOR, MonitoringUserRole.DESCRIPTOR, RemoteMonitoringAgentRole.DESCRIPTOR,
IngestAdminRole.DESCRIPTOR));
IngestAdminRole.DESCRIPTOR, ReportingUserRole.DESCRIPTOR));
assertThat(reservedRolesStore.role(SystemUser.ROLE_NAME), nullValue());
}
@ -116,5 +123,6 @@ public class ReservedRolesStoreTests extends ESTestCase {
assertThat(ReservedRolesStore.isReserved(IngestAdminRole.NAME), is(true));
assertThat(ReservedRolesStore.isReserved(RemoteMonitoringAgentRole.NAME), is(true));
assertThat(ReservedRolesStore.isReserved(MonitoringUserRole.NAME), is(true));
assertThat(ReservedRolesStore.isReserved(ReportingUserRole.NAME), is(true));
}
}