elastic / elasticsearch

Free and Open Source, Distributed, RESTful Search Engine
https://www.elastic.co/products/elasticsearch
Other
1.25k stars 24.86k forks source link

ECK operator service account #85171

Open barkbay opened 2 years ago

barkbay commented 2 years ago

Description

Hi,

This issue is to discuss the addition of an Elasticsearch service account for the ECK operator.

For the moment the ECK operator creates an internal user which is granted the superuser role to interact with Elasticsearch. We think that the operator would benefit from a dedicated service account with a more restricted set of privileges.

My understanding is that the closest cluster privilege that would match the operator needs would be the manage cluster privilege. However, unless I'm missing something we don't need the indices:admin/* actions.

I did a few preliminary tests with the following cluster privilege:

    public static final NamedClusterPrivilege ORCHESTRATION = new ActionClusterPrivilege("orchestration", Set.of("cluster:*"), ALL_SECURITY_PATTERN);

I also added the monitor index privilege to allow the ECK operator to access _cat/shards, so the overall ServiceAccount and its RoleDescriptor would be something along those lines:

--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccounts.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/service/ElasticServiceAccounts.java
@@ -12,6 +12,7 @@ import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
 import org.elasticsearch.xpack.core.security.authz.store.ReservedRolesStore;
 import org.elasticsearch.xpack.core.security.user.User;

+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -22,6 +23,22 @@ final class ElasticServiceAccounts {

     static final String NAMESPACE = "elastic";

+    private static final ServiceAccount ORCHESTRATION_ACCOUNT = new ElasticServiceAccount(
+        "orchestration",
+        new RoleDescriptor(
+            NAMESPACE + "/orchestration",
+            new String[] { "orchestration" },
+            new RoleDescriptor.IndicesPrivileges[]{
+                RoleDescriptor.IndicesPrivileges.builder().indices("*").privileges("monitor").build(),
+            },
+            new RoleDescriptor.ApplicationResourcePrivileges[] {},
+            null,
+            null,
+            null,
+            Collections.emptyMap()
+        )
+    );

FYI here are the APIs used by the ECK operator:

Let me know if you have any question, and if you have any thoughts on this proposal.

Thanks !

elasticmachine commented 2 years ago

Pinging @elastic/es-security (Team:Security)

bytebilly commented 2 years ago

Thanks @barkbay that's an interesting use case.

A few thoughts:

tvernum commented 2 years ago

There's a a few ways we could approach this.

What we need is:

One option would be:

Alternatively:

That issue with the latter is that it means the same account has different access (i.e. operator or non-operator) depending on the type of token used. We have tried to avoid that so far, so I'd prefer a model that prevented an API-token usage for this account.

ywangd commented 2 years ago

Tim's suggestions are technically feasible (either block API token or only treat file token as operator user). But my question is more about whether "service account" is a good mix with "operator user". So far, my understanding for "service account" is that it is used for services that can potentially managed by end-users, e.g., fleet-server or kibana instance. It is possible that end-user can run their own fleet-server which connects to a Cloud ES deployment. Therefore, service account is by design accessible to end-users, while "operator user" is by design not accessible (or even visible because it is defined in file) to end-users. Also, any change to service account has a high cost because it is built into the code which means a new release is needed. While "operator user" is more flexibile since they are defined externally and does not have to tie to ES's release cycle. In this sense, if the "service" is more fluid in terms of privileges, "service account" may not be a good fit. Are the privileges required by ECK operator stable enough or can be tied to ES release cycle?

Going back to Tim's suggestions, all of them involves using the file based token. This means ECK at least needs to manage this file. So it is not completely free for ECK even if we take the option of "Add a flag to a service account to mark it as an operator (that is, this account is always an operator)". Does managing this one file a considerable advantage over managing the a file realm user for ECK?

barkbay commented 2 years ago

Hi,

First of all thanks for your feedback and thoughts 🙇

ECK does not rely (yet?) on the operator privilege. I think there are two things to consider:

 So far, my understanding for "service account" is that it is used for services that can potentially be managed by end-users, e.g., fleet-server or kibana instance. It is possible that end-user can run their own fleet-server which connects to a Cloud ES deployment. Therefore, service account is by design accessible to end-users, while "operator user" is by design not accessible (or even visible because it is defined in file) to end-users.

I see your point. My understanding was that service accounts should be the preferred way to manage "technical" users. By "technical" I mean anything that is not a person, for example a stack application or the ECK operator.

 Are the privileges required by ECK operator stable enough or can be tied to ES release cycle?

I think the privileges required by ECK should be pretty stable: I would expect any new API to be consumed by ECK to be related to its orchestration purpose, as such I would also expect the relevant privileges to be "automatically" included in the operator privileges.

 Going back to Tim's suggestions, all of them involves using the file based token. This means ECK at least needs to manage this file.

This is already the case, ECK can generate the service account tokens, and inject them in $ES_HOME/config/service_tokens in all the ES cluster containers.

tvernum commented 2 years ago

My understanding was that service accounts should be the preferred way to manage "technical" users.

Maybe eventually, but I don't think we (ES) have ever drawn that line.

One of the design goals for service accounts (as they exist now) is to separate what is part of the orchestrated product (that is the existence of the service account & its privileges) from what is managed by the orchestrator (specifically the credentials, which need to be sync'd between ES and the client application). This was helpful because the old model of defining these accounts as file based users required the orchestrator to own everything - the existence of the user, its roles & its password - just so it could be responsible for the password (and manage the lifecycle of it).

A service account for the orchestrator feels different. Maybe the behaviour ends up being mostly the same (although per the above comments, they're not exactly the same), but logically it's not an account for running an orchestrated product, it is the orchestrator.
More concretely, to @ywangd's comment above, it's not clear to me what tangible difference it would make if ECK were to move from a file based user to a file based service token. Understanding the benefit would be helpful.

ECK does not rely (yet?) on the operator privilege.

I think that means that if we were to move forward with this, we probably want a model where the code defines that "this service account only supports file based tokens", rather than something that ties it in operator-privileges.

barkbay commented 2 years ago

This was helpful because the old model of defining these accounts as file based users required the orchestrator to own everything - the existence of the user, its roles & its password - just so it could be responsible for the password [...]

I think that's what we would like here: if the user and the role for the operator itself is managed by Elasticsearch then the ECK operator only needs to manage the token/password.

Understanding the benefit would be helpful.

I think the main argument is that we are relying on the superuser role now, which does not feel great:

For the moment the ECK operator creates an internal user which is granted the superuser role to interact with Elasticsearch. We think that the operator would benefit from a dedicated service account with a more restricted set of privileges.