Skip to content

Commit

Permalink
Service Accounts - update privileges for elastic/fleet-server (elasti…
Browse files Browse the repository at this point in the history
…c#71516) (elastic#71544)

This PR grants elastic/fleet-server service account index privileges of
"read", "write", "monitor", "create_index", "auto_configure" for the .fleet-* index pattern.

Also allow indexing into the ".logs-endpoint.diagnostic.collection-*" index pattern similar
to "logs-*", "metrics-*" and "traces-*".
  • Loading branch information
ywangd authored Apr 12, 2021
1 parent 224cbbe commit 664039c
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public class ServiceAccountIT extends ESRestTestCase {
+ " \"authentication_type\": \"token\"\n"
+ "}\n";

private static final String ELASTIC_FLEET_ROLE_DESCRIPTOR = ""
private static final String ELASTIC_FLEET_SERVER_ROLE_DESCRIPTOR = ""
+ "{\n"
+ " \"cluster\": [\n"
+ " \"monitor\",\n"
Expand All @@ -73,14 +73,28 @@ public class ServiceAccountIT extends ESRestTestCase {
+ " \"names\": [\n"
+ " \"logs-*\",\n"
+ " \"metrics-*\",\n"
+ " \"traces-*\"\n"
+ " \"traces-*\",\n"
+ " \".logs-endpoint.diagnostic.collection-*\"\n"
+ " ],\n"
+ " \"privileges\": [\n"
+ " \"write\",\n"
+ " \"create_index\",\n"
+ " \"auto_configure\"\n"
+ " ],\n"
+ " \"allow_restricted_indices\": false\n"
+ " },\n"
+ " {\n"
+ " \"names\": [\n"
+ " \".fleet-*\"\n"
+ " ],\n"
+ " \"privileges\": [\n"
+ " \"read\",\n"
+ " \"write\",\n"
+ " \"monitor\",\n"
+ " \"create_index\",\n"
+ " \"auto_configure\"\n"
+ " ],\n"
+ " \"allow_restricted_indices\": false\n"
+ " }\n"
+ " ],\n"
+ " \"applications\": [],\n"
Expand Down Expand Up @@ -120,19 +134,19 @@ public void testGetServiceAccount() throws IOException {
final Response getServiceAccountResponse1 = client().performRequest(getServiceAccountRequest1);
assertOK(getServiceAccountResponse1);
assertServiceAccountRoleDescriptor(getServiceAccountResponse1,
"elastic/fleet-server", ELASTIC_FLEET_ROLE_DESCRIPTOR);
"elastic/fleet-server", ELASTIC_FLEET_SERVER_ROLE_DESCRIPTOR);

final Request getServiceAccountRequest2 = new Request("GET", "_security/service/elastic");
final Response getServiceAccountResponse2 = client().performRequest(getServiceAccountRequest2);
assertOK(getServiceAccountResponse2);
assertServiceAccountRoleDescriptor(getServiceAccountResponse2,
"elastic/fleet-server", ELASTIC_FLEET_ROLE_DESCRIPTOR);
"elastic/fleet-server", ELASTIC_FLEET_SERVER_ROLE_DESCRIPTOR);

final Request getServiceAccountRequest3 = new Request("GET", "_security/service/elastic/fleet-server");
final Response getServiceAccountResponse3 = client().performRequest(getServiceAccountRequest3);
assertOK(getServiceAccountResponse3);
assertServiceAccountRoleDescriptor(getServiceAccountResponse3,
"elastic/fleet-server", ELASTIC_FLEET_ROLE_DESCRIPTOR);
"elastic/fleet-server", ELASTIC_FLEET_SERVER_ROLE_DESCRIPTOR);

final String requestPath = "_security/service/" + randomFrom("foo", "elastic/foo", "foo/bar");
final Request getServiceAccountRequest4 = new Request("GET", requestPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ final class ElasticServiceAccounts {
new RoleDescriptor.IndicesPrivileges[]{
RoleDescriptor.IndicesPrivileges
.builder()
.indices("logs-*", "metrics-*", "traces-*")
.indices("logs-*", "metrics-*", "traces-*", ".logs-endpoint.diagnostic.collection-*")
.privileges("write", "create_index", "auto_configure")
.build(),
RoleDescriptor.IndicesPrivileges
.builder()
.indices(".fleet-*")
.privileges("read", "write", "monitor", "create_index", "auto_configure")
.build()
},
null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@

package org.elasticsearch.xpack.security.authc.service;

import org.elasticsearch.action.admin.indices.create.AutoCreateAction;
import org.elasticsearch.action.admin.indices.create.CreateIndexAction;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexAction;
import org.elasticsearch.action.admin.indices.mapping.put.AutoPutMappingAction;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsAction;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsAction;
import org.elasticsearch.action.bulk.BulkAction;
import org.elasticsearch.action.delete.DeleteAction;
import org.elasticsearch.action.get.GetAction;
import org.elasticsearch.action.get.MultiGetAction;
import org.elasticsearch.action.index.IndexAction;
import org.elasticsearch.action.search.MultiSearchAction;
import org.elasticsearch.action.search.SearchAction;
import org.elasticsearch.cluster.metadata.IndexAbstraction;
import org.elasticsearch.common.Strings;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.security.action.CreateApiKeyAction;
Expand All @@ -25,6 +39,7 @@
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class ElasticServiceAccountsTests extends ESTestCase {

Expand All @@ -40,6 +55,41 @@ public void testElasticFleetPrivileges() {
assertThat(role.cluster().check(InvalidateApiKeyAction.NAME,
InvalidateApiKeyRequest.usingUserName(randomAlphaOfLengthBetween(3, 16)), authentication), is(false));

org.elasticsearch.common.collect.List.of(
"logs-" + randomAlphaOfLengthBetween(1, 20),
"metrics-" + randomAlphaOfLengthBetween(1, 20),
"traces-" + randomAlphaOfLengthBetween(1, 20),
".logs-endpoint.diagnostic.collection-" + randomAlphaOfLengthBetween(1, 20))
.stream().map(this::mockIndexAbstraction)
.forEach(index -> {
assertThat(role.indices().allowedIndicesMatcher(AutoPutMappingAction.NAME).test(index), is(true));
assertThat(role.indices().allowedIndicesMatcher(AutoCreateAction.NAME).test(index), is(true));
assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(true));
assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(true));
assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(true));
assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(index), is(true));
assertThat(role.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(false));
assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(false));
assertThat(role.indices().allowedIndicesMatcher(MultiGetAction.NAME).test(index), is(false));
assertThat(role.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(false));
assertThat(role.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(false));
assertThat(role.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(false));
});

final String dotFleetIndexName = ".fleet-" + randomAlphaOfLengthBetween(1, 20);
final IndexAbstraction dotFleetIndex = mockIndexAbstraction(dotFleetIndexName);
assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(dotFleetIndex), is(true));
assertThat(role.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(dotFleetIndex), is(true));
assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test(dotFleetIndex), is(true));
assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(dotFleetIndex), is(true));
assertThat(role.indices().allowedIndicesMatcher(GetAction.NAME).test(dotFleetIndex), is(true));
assertThat(role.indices().allowedIndicesMatcher(MultiGetAction.NAME).test(dotFleetIndex), is(true));
assertThat(role.indices().allowedIndicesMatcher(SearchAction.NAME).test(dotFleetIndex), is(true));
assertThat(role.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(dotFleetIndex), is(true));
assertThat(role.indices().allowedIndicesMatcher(IndicesStatsAction.NAME).test(dotFleetIndex), is(true));
assertThat(role.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(dotFleetIndex), is(false));
assertThat(role.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(dotFleetIndex), is(false));
assertThat(role.indices().allowedIndicesMatcher("indices:foo").test(dotFleetIndex), is(false));
// TODO: more tests when role descriptor is finalised for elastic/fleet-server
}

Expand Down Expand Up @@ -68,4 +118,12 @@ public void testElasticServiceAccount() {
"the provided role descriptor [" + roleDescriptor2.getName()
+ "] must have the same name as the service account [" + principal + "]"));
}

private IndexAbstraction mockIndexAbstraction(String name) {
IndexAbstraction mock = mock(IndexAbstraction.class);
when(mock.getName()).thenReturn(name);
when(mock.getType()).thenReturn(randomFrom(IndexAbstraction.Type.CONCRETE_INDEX,
IndexAbstraction.Type.ALIAS, IndexAbstraction.Type.DATA_STREAM));
return mock;
}
}

0 comments on commit 664039c

Please sign in to comment.