Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,19 @@
package org.elasticsearch.xpack.security.authc.service;

import org.elasticsearch.common.Strings;
import org.elasticsearch.xpack.core.ilm.action.GetLifecycleAction;
import org.elasticsearch.xpack.core.ilm.action.PutLifecycleAction;
import org.elasticsearch.xpack.core.monitoring.action.MonitoringBulkAction;
import org.elasticsearch.xpack.core.security.action.InvalidateApiKeyAction;
import org.elasticsearch.xpack.core.security.action.privilege.GetBuiltinPrivilegesAction;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
import org.elasticsearch.xpack.core.security.authz.privilege.ConfigurableClusterPrivilege;
import org.elasticsearch.xpack.core.security.authz.privilege.ConfigurableClusterPrivileges;
import org.elasticsearch.xpack.core.security.authz.store.ReservedRolesStore;
import org.elasticsearch.xpack.core.security.support.MetadataUtils;
import org.elasticsearch.xpack.core.security.user.User;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -44,7 +54,78 @@ final class ElasticServiceAccounts {
null
));

static final Map<String, ServiceAccount> ACCOUNTS = List.of(FLEET_ACCOUNT).stream()
private static final ServiceAccount KIBANA_ACCOUNT = new ElasticServiceAccount("kibana-system",
new RoleDescriptor(
NAMESPACE + "/kibana-system",
new String[] {
"monitor", "manage_index_templates", MonitoringBulkAction.NAME, "manage_saml", "manage_token", "manage_oidc",
InvalidateApiKeyAction.NAME, "grant_api_key",
GetBuiltinPrivilegesAction.NAME, "delegate_pki", GetLifecycleAction.NAME, PutLifecycleAction.NAME,
// To facilitate ML UI functionality being controlled using Kibana security privileges
"manage_ml",
// The symbolic constant for this one is in SecurityActionMapper, so not accessible from X-Pack core
"cluster:admin/analyze",
// To facilitate using the file uploader functionality
"monitor_text_structure",
// To cancel tasks and delete async searches
"cancel_task"
},
new RoleDescriptor.IndicesPrivileges[] {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question is there a way to share this role descriptor with the one used to define the kibana_system reserved role, so that we have a single source of truth for our necessary privileges?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to hear the news!
We'll push for a single source of truth for the reserved role and the service account, I don't think there's any issue preventing this.

RoleDescriptor.IndicesPrivileges.builder()
.indices(".kibana*", ".reporting-*").privileges("all").build(),
RoleDescriptor.IndicesPrivileges.builder()
.indices(".monitoring-*").privileges("read", "read_cross_cluster").build(),
RoleDescriptor.IndicesPrivileges.builder()
.indices(".management-beats").privileges("create_index", "read", "write").build(),
// To facilitate ML UI functionality being controlled using Kibana security privileges
RoleDescriptor.IndicesPrivileges.builder()
.indices(".ml-anomalies*", ".ml-notifications*", ".ml-stats-*")
.privileges("read").build(),
RoleDescriptor.IndicesPrivileges.builder().indices(".ml-annotations*")
.privileges("read", "write").build(),
// APM agent configuration
RoleDescriptor.IndicesPrivileges.builder()
.indices(".apm-agent-configuration").privileges("all").build(),
// APM custom link index creation
RoleDescriptor.IndicesPrivileges.builder()
.indices(".apm-custom-link").privileges("all").build(),
// APM telemetry queries APM indices in kibana task runner
RoleDescriptor.IndicesPrivileges.builder()
.indices("apm-*")
.privileges("read", "read_cross_cluster").build(),
// Data telemetry reads mappings, metadata and stats of indices
RoleDescriptor.IndicesPrivileges.builder()
.indices("*")
.privileges("view_index_metadata", "monitor").build(),
// Endpoint diagnostic information. Kibana reads from these indices to send telemetry
RoleDescriptor.IndicesPrivileges.builder()
.indices(".logs-endpoint.diagnostic.collection-*")
.privileges("read").build(),
// Fleet Server indices. Kibana create this indice before Fleet Server use them.
// Fleet Server indices. Kibana read and write to this indice to manage Elastic Agents
RoleDescriptor.IndicesPrivileges.builder()
.indices(".fleet*")
.privileges("all").build(),
// Legacy "Alerts as data" index. Kibana user will create this index.
// Kibana user will read / write to these indices
RoleDescriptor.IndicesPrivileges.builder()
.indices(ReservedRolesStore.LEGACY_ALERTS_INDEX)
.privileges("all").build(),
// "Alerts as data" index. Kibana user will create this index.
// Kibana user will read / write to these indices
RoleDescriptor.IndicesPrivileges.builder()
.indices(ReservedRolesStore.ALERTS_INDEX)
.privileges("all").build()
},
null,
new ConfigurableClusterPrivilege[] { new
ConfigurableClusterPrivileges.ManageApplicationPrivileges(Collections.singleton("kibana-*")) },
null,
MetadataUtils.DEFAULT_RESERVED_METADATA,
null
));

static final Map<String, ServiceAccount> ACCOUNTS = List.of(FLEET_ACCOUNT, KIBANA_ACCOUNT).stream()
.collect(Collectors.toMap(a -> a.id().asPrincipal(), Function.identity()));;

private ElasticServiceAccounts() {}
Expand Down