Skip to content

Commit

Permalink
Expand beats_system role privileges (#40876) (#41232)
Browse files Browse the repository at this point in the history
Traditionally we have [recommended](https://www.elastic.co/guide/en/beats/filebeat/current/monitoring.html) that Beats send their monitoring data to the **production** Elasticsearch cluster. Beats do this by calling the `POST _monitoring/bulk` API. When Security is enabled this API call requires the `cluster:admin/xpack/monitoring/bulk` privilege. The built-in `beats_system` role has this privilege.

[Going forward](elastic/beats#9260), Beats will be able to send their monitoring data directly to the **monitoring** Elasticsearch cluster. Beats will do this by calling the regular `POST _bulk` API. When Security is enabled this API call requires the `indices:data/write/bulk` privilege. Further, the call has to be able to create any indices that don't exist.

This PR expands the built-in `beats_system` role's privileges. Specifically, it adds index-level `write` and `create_index` privileges for `.monitoring-beats-*` indices. 

This will allow Beats users to continue using the `beats_system` role for the new direct monitoring route when Security is enabled.
  • Loading branch information
ycombinator committed Apr 16, 2019
1 parent 56c00ee commit 750db02
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ private static Map<String, RoleDescriptor> initializeReservedRoles() {
},
null, MetadataUtils.DEFAULT_RESERVED_METADATA))
.put(UsernamesField.BEATS_ROLE, new RoleDescriptor(UsernamesField.BEATS_ROLE,
new String[] { "monitor", MonitoringBulkAction.NAME}, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA))
new String[] { "monitor", MonitoringBulkAction.NAME},
new RoleDescriptor.IndicesPrivileges[]{
RoleDescriptor.IndicesPrivileges.builder()
.indices(".monitoring-beats-*").privileges("create_index", "create").build()
},
null, MetadataUtils.DEFAULT_RESERVED_METADATA))
.put(UsernamesField.APM_ROLE, new RoleDescriptor(UsernamesField.APM_ROLE,
new String[] { "monitor", MonitoringBulkAction.NAME}, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA))
.put("apm_user", new RoleDescriptor("apm_user",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -838,23 +838,30 @@ public void testBeatsSystemRole() {
assertNotNull(roleDescriptor);
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));

Role logstashSystemRole = Role.builder(roleDescriptor, null).build();
assertThat(logstashSystemRole.cluster().check(ClusterHealthAction.NAME, request), is(true));
assertThat(logstashSystemRole.cluster().check(ClusterStateAction.NAME, request), is(true));
assertThat(logstashSystemRole.cluster().check(ClusterStatsAction.NAME, request), is(true));
assertThat(logstashSystemRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false));
assertThat(logstashSystemRole.cluster().check(ClusterRerouteAction.NAME, request), is(false));
assertThat(logstashSystemRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false));
assertThat(logstashSystemRole.cluster().check(MonitoringBulkAction.NAME, request), is(true));
Role beatsSystemRole = Role.builder(roleDescriptor, null).build();
assertThat(beatsSystemRole.cluster().check(ClusterHealthAction.NAME, request), is(true));
assertThat(beatsSystemRole.cluster().check(ClusterStateAction.NAME, request), is(true));
assertThat(beatsSystemRole.cluster().check(ClusterStatsAction.NAME, request), is(true));
assertThat(beatsSystemRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false));
assertThat(beatsSystemRole.cluster().check(ClusterRerouteAction.NAME, request), is(false));
assertThat(beatsSystemRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false));
assertThat(beatsSystemRole.cluster().check(MonitoringBulkAction.NAME, request), is(true));

assertThat(logstashSystemRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false));
assertThat(beatsSystemRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false));

assertThat(logstashSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test("foo"), is(false));
assertThat(logstashSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(".reporting"), is(false));
assertThat(logstashSystemRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),

final String index = ".monitoring-beats-" + randomIntBetween(0, 5);;
logger.info("index name [{}]", index);
assertThat(beatsSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test("foo"), is(false));
assertThat(beatsSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(".reporting"), is(false));
assertThat(beatsSystemRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),
is(false));
assertThat(beatsSystemRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(true));
assertThat(beatsSystemRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(true));
assertThat(beatsSystemRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(false));
assertThat(beatsSystemRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(index), is(true));

assertNoAccessAllowed(logstashSystemRole, RestrictedIndicesNames.RESTRICTED_NAMES);
assertNoAccessAllowed(beatsSystemRole, RestrictedIndicesNames.RESTRICTED_NAMES);
}

public void testAPMSystemRole() {
Expand Down

0 comments on commit 750db02

Please sign in to comment.