elastic / kibana

Your window into the Elastic Stack
https://www.elastic.co/products/kibana
Other
19.69k stars 8.24k forks source link

Explicitly Restrict API endpoints to Superusers and Operators #196271

Open elena-shostak opened 1 month ago

elena-shostak commented 1 month ago

Some APIs in Kibana are implicitly restricted to superusers by specifying access tags that are not defined in Kibana’s authorization model. For instance, the API at key_rotation.ts uses the access:rotateEncryptionKey tag, which results in only superusers or privileged accounts being able to access the endpoint.

We need to implement a more explicit mechanism to restrict API access to superusers or similarly privileged users, instead of relying on implicit behavior.

For the superuser access we can introduce explicit and reserved privilege set

const SuperuserPrivilegeSet = {
  kibana: ['*'],
  elasticsearch: {
    cluster: ['all'],
    index: { '*': ['all'] }
  }
};

For operators, we can check privileges using the getCurrentUser().operator method which indicates whether user is operator or not.

Introduce reserved privileges set with alias corresponding to Superuser and Operator:

enum ReservedPrivilegesSet {
  Operator = 'operator',
  Superuser = 'superuser',
}

Checks performed in api_authorization need to be adjusted accordingly.

elasticmachine commented 1 month ago

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

legrego commented 1 month ago

For operators, we can check privileges using the getCurrentUser().operator method which indicates whether user is operator or not.

@elena-shostak let's discuss operator privileges a bit more. I expect we'll want something more granular than "is this user an operator"?

elena-shostak commented 1 month ago

Draft PR for operator privileges. Summarizing what we currently have for operator privileges:

  1. If user has all operator privileges granted, but is not listed as operator in operator_users.yml, ES would throw an unauthorized error.
  2. If user is listed as operator in operator_users.yml, but doesn't have necessary privileges granted, ES would throw an unauthorized error.
  3. It’s not possible to determine if a user is operator via any ES API, i.e. _has_privileges.
  4. To be clarified serverless vs stateful behavior.

    operators have different rules for stateful vs. serverless. In serverless, operators mostly impact which REST API's can be called, but that is not the case for stateful.

The simplest check we can make is looking whether getCurrentUser().operator is set to true. The registry for default privileges is defined on the ES side in DefaultOperatorOnlyRegistry. Mirroring those into Kibana might bring some potential inconsistencies in the future as Kibana would be still not the source of truth for operator privileges check.

What to do if operator privileges are disabled? If xpack.security.operator_privileges.enabled is set to false, I suppose we can fallback to checking if user is a superuser.

What to do with operator privileges on prem? Since operator privileges are a subset of privileges taken away from superuser we can fallback to checking if user is a superuser as well, that would be applicable only for on prem customers.

@legrego @azasypkin WDYT?

azasypkin commented 1 month ago
  1. If user has all operator privileges granted, but is not listed as operator in operator_users.yml, ES would throw an unauthorized error.
  2. If user is listed as operator in operator_users.yml, but doesn't have necessary privileges granted, ES would throw an unauthorized error.

Thanks for checking this. Do I understand correctly that if the operator privileges functionality is disabled, but a user has the privileges listed here, they will still be able to perform all these operations? Looking at the cluster:admin/xpack/license/delete action within operator-actions I assume the answer is yes since superusers are able to delete licenses, but I want to make sure.

If xpack.security.operator_privileges.enabled is set to false, I suppose we can fallback to checking if user is a superuser.

@elena-shostak As far as I understand, this is an Elasticsearch configuration, and in Kibana, we might not have a way to know its value (might be worth checking with ES team?) or distinguish between the case when the operator privileges functionality is disabled and when it’s just a user who isn’t an operator.

The way it’s implemented in Elasticsearch, it feels more like a complementary filter to the authorization decision - an additional layer that can be enabled or disabled, but it doesn’t replace proper privilege checks. Technically, any user can be marked as an operator via operator_users.yml, not necessarily just highly privileged users. Also, this functionality seems to be disabled by default for on-prem and enabled in managed environments. I see the docs mention:

This feature is designed for indirect use by Elasticsearch Service, Elastic Cloud Enterprise, and Elastic Cloud on Kubernetes. Direct use is not supported.

I’m leaning towards replicating this behavior in Kibana as well unless there’s a reason for us to deviate. For instance, the Kibana endpoint could be restricted to superusers who are also operators, or it could require a specific non-superuser privilege/access tag and operator status. If the operator privileges functionality is disabled, we would just ignore the operator part of the requirement. I’m not sure yet how to best model this in the route’s security config, but that’s an implementation detail we can iterate on.

Eventually, we might extend this check to more Kibana privilege areas, similar to how Elasticsearch applies it to both actions and cluster settings. But for now, restricting it to Kibana API access seems reasonable.

The challenge is determining how Kibana can know whether the operator privileges functionality is enabled in the Elasticsearch cluster. If there’s no way to get this info from Elasticsearch, we could probably introduce a xpack.security.operator_privileges.enabled setting in Kibana that would explicitly require the same setting set in Elasticsearch.

What do you think?

Since operator privileges are a subset of privileges taken away from superuser

I’m not sure we can say that these privileges are taken away from superuser. To perform any operation that requires operator privileges, a superuser must still have all the necessary privileges, the only difference is that they also need to be marked as an operator.

legrego commented 1 month ago

Since operator privileges are a subset of privileges taken away from superuser

I’m not sure we can say that these privileges are taken away from superuser. To perform any operation that requires operator privileges, a superuser must still have all the necessary privileges, the only difference is that they also need to be marked as an operator.

Sorry @azasypkin, this is the framing that I've been using, even though it's not technically correct to think of it this way. The net result is that an on-prem superuser is able to perform operations that an ECH superuser cannot, and that is due to the enforcement of operator privileges. And here, I'm referring to superuser as a (human) cluster administrator who is assigned the superuser role.

elena-shostak commented 1 month ago

Do I understand correctly that if the operator privileges functionality is disabled, but a user has the privileges listed here, they will still be able to perform all these operations? Looking at the cluster:admin/xpack/license/delete action within operator-actions I assume the answer is yes since superusers are able to delete licenses, but I want to make sure.

Yep, users with necessary privileges (like superusers) will be able to perform operations

the Kibana endpoint could be restricted to superusers who are also operators

I actually lean towards this one, if operator functionality is disabled we skip the operator check, but still check the superuser access. Seems to cover our use case for both on-prem superuser and ECH superuser. Moreover we could easily enforce it explicitly

requiredPrivileges: [ReservedPrivilegesSet.operator, ReservedPrivilegesSet.superuser]

For the privilege/access tag option, I initially wanted to distinguish between reserved privileges check (superuser, operator) and simple privilege/access tag check, because the last one we just check as is.

As far as I understand, this is an Elasticsearch configuration, and in Kibana, we might not have a way to know its value (might be worth checking with ES team?)

Will check it out, in worst case we would need to mirror setting to the Kibana config

legrego commented 1 month ago

@elena-shostak it looks like we can determine this from the /_xpack/usage API, which I believe we're already using elsewhere in the security plugin.

GET /_xpack/usage?filter_path=security.operator_privileges
# This result is from my ECH deployment
{
  "security": {
    "operator_privileges": {
      "available": true,
      "enabled": true
    }
  }
}