Skip to content

[RFC] Migrate the definition of privilege presets from the sample roles.yml to static_action_groups.yml and static_roles.yml #5426

@nibix

Description

@nibix

Introduction

Recently, we had quite a few of issues and PRs related to privileges for other plugins defined in roles.yml:

These follow a practise in OpenSearch, which has IMHO significant downsides, while a better approach would be actually quite easy to achieve. I will explain the downsides and the proposed solution in this issue.

As this is an RFC, I would be very grateful for any comments and opinions on this topic.

The role of the file config/roles.yml

The configuration files in the directory config were initially inteded as a demo or example configuration. This is still evident from the file internal_users.yml, which defines example users with hard-coded insecure passwords. Also, the file roles_mapping.yml contains the comment Demo roles mapping.

By default, OpenSearch is not automatically initialized with these files upon first startup; this can be only activated by setting the config option plugins.security.allow_default_init_securityindex

Still, the file roles.yml inside the config directory has evolved into a kind of storage for pre-defined and reusable role definitions for further OpenSearch plugins.

It contains for example generic roles for anomaly detection and alerting:

alerting_ack_alerts:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/alerting/alerts/*'
- 'cluster:admin/opendistro/alerting/chained_alerts/*'
- 'cluster:admin/opendistro/alerting/workflow_alerts/*'
- 'cluster:admin/opensearch/alerting/comments/*'
# Allows users to use all alerting functionality
alerting_full_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/alerting/*'
- 'cluster:admin/opensearch/alerting/*'
- 'cluster:admin/opensearch/notifications/feature/publish'
- 'cluster_monitor'
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- 'indices:admin/aliases/get'
- 'indices:admin/mappings/get'
- 'indices_monitor'

It happens quite often that PR are filed against this file to add new privileges either to existing roles or to new roles.

The challenge caused by this practise

Non-automatic updates

While the changes contained in the PRs filed against roles.yml are trivial, these pose a challenge to administrators of running clusters.

One reason is: Any changes to these files are not automatically applied to the already installed configuration on clusters that already existed before. Thus, any bug fix or addition to the roles.yml file is not effective on these clusters.

As a remedy, there is the POST /_plugins/_security/api/_upgrade_perform API:

This checks for differences between the active role configuration and the role configuration stored in config/opensearch-security/roles.yml and overwrites any roles in the active configuration that also exist in config/opensearch-security/roles.yml by that predefined version.

This API, however, is not well known. A Google search for the endpoint just delivers the API documentation and the PR in which it was introduced. There are no forum discussions on that API. Also, the documentation about upgrading OpenSearch does not mention the API. A quick company internal survey resulted in zero cases of knowledge about this API.

That means that likely most cluster admins will not use this API and thus will be likely using obsolete versions of the role definitions. This might be not so bad if this just causes missing privileges. If, however, a role needs to be changed because it granted too many privileges, this might be an actual issue.

Default configuration is not installed by default

It requires the explicit enabling of a specific config option to enable installing the OpenSearch default configuration. Thus, we need to expect that there are many clusters present, which actually do not have the roles from config/roles.yml present in their effective configuration.

Actually, using this flag must be considered as bad practise for production clusters, as it will install demo configuration which must be considered insecure and unsuitable for production clusters. I would recommend to any cluster admin to review each file and to only use the mimum configuration necessary for their needs.

For these cases, plugin maintainers cannot expect their predefined roles to be present at all.

The solution is already implemented

The OpenSearch security plugin has already the concept of "static" configuration files. These are separate configuration files which are present in the JAR archive of the deployed plugin. Any entries from these configuration files are automatically added to the effective configuration without being persisted to the index. Thus, any update to these files gets automatically effective on each upgrade of the security plugin.

Excerpts from static_roles.yml:

kibana_server:
reserved: true
hidden: false
static: true
description: "Provide the minimum permissions for the Kibana server"
cluster_permissions:
- "cluster_composite_ops"
- "cluster_monitor"
- "indices:admin/index_template*"
- "indices:admin/template*"
- "indices:data/read/scroll*"
- "manage_point_in_time"
index_permissions:
- index_patterns:
- ".kibana"
- ".opensearch_dashboards"
allowed_actions:
- "indices_all"
- index_patterns:
- ".kibana-6"
- ".opensearch_dashboards-6"
allowed_actions:
- "indices_all"
- index_patterns:
- ".kibana_*"
- ".opensearch_dashboards_*"
allowed_actions:
- "indices_all"
- index_patterns:
- ".tasks"
allowed_actions:
- "indices_all"
- index_patterns:
- ".management-beats*"
allowed_actions:
- "indices_all"
- index_patterns:
- "*"
allowed_actions:
- "indices:admin/aliases*"
logstash:
reserved: true
hidden: false
static: true
description: "Provide the minimum permissions for logstash and beats"
cluster_permissions:
- "cluster:admin/ingest/pipeline/get"
- "cluster:admin/ingest/pipeline/put"
- "cluster_composite_ops"
- "cluster_monitor"
- "indices:admin/template/get"
- "indices:admin/template/put"
index_permissions:
- index_patterns:
- "logstash-*"
- "ecs-logstash-*"
allowed_actions:
- "create_index"
- "crud"
- index_patterns:
- "*beat*"
allowed_actions:
- "crud"
- "create_index"

You can see that this files contains role definitions for Kibana/Dashboards and Logstash in a very similar way as the role definitions for alerting and anomaly detection in config/roles.yml.

Excerpts from static_action_groups.yml:

kibana_all_read:
reserved: true
hidden: false
static: true
allowed_actions:
- "kibana:saved_objects/*/read"
type: "kibana"
description: "Allow reading in all OpenSearch Dashboards apps"
cluster_all:
reserved: true
hidden: false
static: true
allowed_actions:
- "cluster:*"
type: "cluster"
description: "Allow everything on cluster level"

This also defines reusable action groups for Kibana/Dashboards.

Thus, it seems that these files solve exactly the described issue. Thus, I would propose that we use them.

Proposal

I would propose the following way forward:

Convert roles from config/roles.yml into static roles and static action groups.

Making roles static is straight-forward; it is just copying roles over to the other file. One only has to keep in mind that the name of static roles should not be equal to the name of the present non-static roles. If it would be equal, the cluster would log warnings on startup.

Additionally, I would propose to also leverage static action groups as much as possible. Thus, any static roles should not directly refer to individual action names, but only to static action groups. This creates a better reusability. Possibly, there are use cases to use action groups rather than roles for defining plugin privileges.

Example: alerting_read_access

https://github.com/kaituo/security2/blob/c3d1e64ca3acf360638ac03e350894ec7dfb3058/config/roles.yml#L28-L39

would become the static action group:

"alerting::read_all":
  reserved: true
  hidden: false
  static: true
  allowed_actions:
    - 'cluster:admin/opendistro/alerting/alerts/get'
    - 'cluster:admin/opendistro/alerting/destination/get'
    - 'cluster:admin/opendistro/alerting/monitor/get'
    - 'cluster:admin/opendistro/alerting/monitor/search'
    - 'cluster:admin/opensearch/alerting/comments/search'
    - 'cluster:admin/opensearch/alerting/findings/get'
    - 'cluster:admin/opensearch/alerting/remote/indexes/get'
    - 'cluster:admin/opensearch/alerting/workflow/get'
    - 'cluster:admin/opensearch/alerting/workflow_alerts/get'
  type: "cluster"
  description: "Allows to read all configuration entities used by OpenSearch alerting"

and the static role:

"alerting::read_all":
  reserved: true
  cluster_permissions:
    - 'alerting::read_all'

Example: anomaly_full_access

https://github.com/kaituo/security2/blob/c3d1e64ca3acf360638ac03e350894ec7dfb3058/config/roles.yml#L78-L98

The role anomaly_full_access is kind of special, as it also gives any user full read access on any index on the cluster. I would argue that we should strive at making this unnecessary, as there are likely very valid scenarios where users can modify the full AD configuration, but should not be able to access all indices.

Thus, we would create the static action group:

"anomaly_detection::manage":
  reserved: true
  hidden: false
  static: true
  allowed_actions:
    - "cluster:admin/ingest/pipeline/delete"
    - "cluster:admin/ingest/pipeline/put"
    - 'cluster:admin/opendistro/ad/*'
    - 'cluster_monitor'
  type: "cluster"
  description: "Allows users to use all Anomaly Detection functionality"

and the static role:

"anomaly_detection::manage":
  reserved: true
  cluster_permissions:
    - 'anomaly_detection::manage'

Any cluster admin could give users full index access explicitly by creating a role like this:

"ad_manager":
  cluster_permissions:
    - 'anomaly_detection::manage'
  index_permissions:
    - index_patterns:
      - "*"
    - allowed_actions:
      - read

Mark plugin specific roles in config/roles.yml as deprecated

A deprecation notice should be added to config/roles.yml to inform users that they should move to the static roles. This pertains both to cluster admins using these roles and to developers defining the permissions.

Write developer documentation on structuring the privileges

To educate contributers about the proper way of defining privileges, clear and easily discoverable developer docs need to be written on that topic.

Deprecate the _upgrade_perform API

As this API won't be no longer necessary, it shall be deprecated and removed. Possibly, the deprecation notice can log information about the new approach.

Metadata

Metadata

Assignees

No one assigned

    Labels

    triagedIssues labeled as 'Triaged' have been reviewed and are deemed actionable.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions