Using KeyCloak RBAC/ABAC in OpenSearch

I’m currently working on a POC of integrating KeyCloak with OpenSearch. For this I’m currently running postgres, KeyCloak & OpenSearch nodes & dashboard as container over the Docker.

With the config.yaml, opensearch.yml & opensearch-dashboard.yml configuration. I successfully able to login to OpenSearch dashboard using KeyCloak.

After setting up the OpenSearch authentication via KeyCloak; now my further task is to enforce RBAC/ABAC from KeyCloak to OpenSearch documents/fields. Is there any way to directly configure authorization without manually adding/replicating KeyCloak Roles & user Policies to OpenSearch while making an OpenSearch API request for querying OS Cluster. This is a nodejs application which invokes the OpenSearch API for executing the OS queries.

Hi @vishal.gilbile ,

You can set an openid_auth_domain.http_authenticator.config.roles_key: roles in config.yaml, this will allow you to send back-end roles to control permissions on KeyCloal side.

Make sure:

navigate to : Client Scopes > roles > Tab “Mappers” > Realm Roles

set:
Token Claim Name = roles
Add to ID token → On
Add to access token → On
Add to userinfo → On

5f818567447c486c06d47a46ffa9e5785292f30e_2_329x500

To configure your (cluster/index/documents/fields) permission you can modify roles.yml and/or roles_mapping.yml accordingly or use API please see here: API - OpenSearch documentation

Please let me know if you have any further questions.

Best,
Mantas

Thanks @Mantas for the quick reply. I forgot to add in the description, my organization has decided to use KeyCloak for user-management. We don’t want to duplicate users/roles/policies with OpenSearch. Currently the nodeJs POC I’m working upon has keyCloak integrated & I’m able to get accessToken & other details likes rbac/abac from keyCloak. I’m looking out for a way while making an API call from my node application to OpenSearch Cluster; if I can integrate those RBAC/ABAC received from keyCloak Token & pass it to OpenSearch & accordingly OS can filter the results for me based on permissions.

If you can share any reference links covering my use; which I can go through that would be really helpful.

Thank you so much for your prompt reply.

You can indeed pass your realm roles or RBAC/ABAC in the token and use them as backend roles on the OpenSearch to control permission.

For more details, please check: Access control - OpenSearch documentation

You will need to map your user to roles (permission) based on your backend roles, please see more here: Users and roles - OpenSearch documentation

Let me know if you have any further questions.

Best,
Mantas

@Mantas - Thanks for your input; I went through the links shared but it doesn’t provide the necessary info on the practical implementations for the below points:

  1. Passing KeyCloak tokens to create an OpenSearch Client; following the document I was able to create an OpenSearch client using below code snippet:
const osClient: Client = new Client({
    node: protocol + "://" + username:password + "@" + host + ":" + port,
    ssl: {
        ca: fs.readFileSync(ca_certs_path),
        rejectUnauthorized: false
    }
});

but my requirement over here was how could I use the AccessToken from KeyCloak to create an OSClient object instead of passing username:password.

  1. I also followed your link of user to roles mapping; one query I do have here do we have to create all the users defined in KeyCloak to OpenSearch

  2. How to make OpenSearch REST API call (specifically the security API calls) in nodejs using the OSClient we created in point 1. I’m currently using “@opensearch-project/opensearch”: “^2.4.0”, library.

Thank you in advance.

Hi @vishal.gilbile,

On the point #2
You only need to create a role mapping to whatever you are passing from the KeyCloak as a roles_key: <back-end-role> (i.e. the JWT from KeyCloak contains <back-end-role>: X and you have a role Y that has "backend_roles": [ "X", "Z" ] this will grant all the privileges assigned to role Y to a user with <back-end-role>: X), so no need to create users, just need to define privileges/permissions in the roles, so backend knows.

You could explore the JWT authentication for your osClients authorization:
See more here: JSON Web Token - OpenSearch documentation

Let me know if you have any further questions.

Best,
Mantas

Hello @Mantas,
Thanks for the input; I was able to create a new role in my Dockerized OpenSearch
OS Role: data_limited_view_role with DLS restricting documents for location Europe

image

KeyCloak
Role: data_limited_view_role
User Added in above role: limited_access

when I login using the limited_access credentials; I could see my all roles & identities in OpenSearch dashboard

But when I query the data; just a simple match_all query; ideally it should had returned me the records matching the DLS expression but it returns none & it doesn’t throw any exception.

There are almost close to 100 records having the continent_name as Europe; but the result doesn’t show up any data. Let me know if I miss any setting

Thank you in advance.

With Regards,
Vishal Gilbile

Hi @vishal.gilbile ,

Could you test your DLS with the below instead:

{
  "bool": {
    "must": {
      "match": {
        "geoip.continent_name": "Europe"
      }
    }
  }
}

best,
mj

Hi @vishal.gilbile,

How do you map your Backend role: data_limited_view_role to OpenSearch role: data_limited_view_role (roles_mapping.yml ?)?

Thanks,
mj

Hello @Mantas,

I mapped it using the config.yaml file, by setting
openid_auth_domain.http_authenticator.config.roles_key = “roles”;

Hi @vishal.gilbile, is it working now as expected?

best,
mj

Yes @Mantas

Hello @Mantas ,

Today I was trying to re-setup the OpenSearch Keycloak on my system, though keeping all the configuration same as old; but this time I’m not able to configure Keycloak groups with OpenSearch Backend roles. If I login as Admin user I get to see that the all_access role is not assigned to my admin user:
image

And also the groups are though listed as Backend roles but it fails with the below exception:

I’ve set up the DLS for the appropriate back end roles in OpenSearch but still no luck.

Hi @vishal.gilbile,

Could you share a screenshot of your Realm Role Mapper Details (same as per below):

5f818567447c486c06d47a46ffa9e5785292f30e_2_329x500

Thanks,
mj

Hello @Mantas,

Any update @Mantas still stuck with the same issue; though from KeyCloak we are able to send all the groups & also the backend role mapping is been configured in OpenSearch & we can see those in OpenSearch but still when we try to Query OS it fails with the
Security exception: no permissions for [indices:data/read/search] and User [name=xxxx, backend_roles=[group1, group2, group3], requestedTenant=_ user _]

Could you share the JWT token that you are sending from Keycloak, as well as your ../opensearch-security/config.yml file.

thanks,
mj

JWT Token:

eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJMUlI3NEhHblM4Rzg5cEZLUWt0MG1QTVlndHFseVgtNWpoUUFqOVhDM1ZZIn0.eyJleHAiOjE3MDY2MjYyMDksImlhdCI6MTcwNjYyMjYwOSwianRpIjoiZjYzZTI0MTQtZjMzOC00OWQzLTg1MDktMzM5YzlkNWMzZTc3IiwiaXNzIjoiaHR0cHM6Ly8xNzIuMjMuMTEyLjE6ODQ0My9hdXRoL3JlYWxtcy9tYXN0ZXIiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNTgwNzUxNzgtOWQ0MC00N2E0LWIxNWMtMDA2NWEwNDBlMWQzIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiU1BBUlFfQVNTRVQiLCJzZXNzaW9uX3N0YXRlIjoiNjYxM2IxMjAtZWEyYS00MjJmLThjNWEtMWUwMjRiZGE5YTFlIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyJodHRwczovLzE3Mi4yMy4xMTIuMTo1NjAxIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLW1hc3RlciIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InRlbmFudCBwcm9maWxlIHRlbmFudElEIiwic2lkIjoiNjYxM2IxMjAtZWEyYS00MjJmLThjNWEtMWUwMjRiZGE5YTFlIiwicm9sZXMiOlsiZGVmYXVsdC1yb2xlcy1tYXN0ZXIiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdLCJ0ZW5hbnRJZCI6Im1hc3RlciIsIm5hbWUiOiJBbmphbGkgU2hhaCIsImdyb3VwcyI6WyIvYXNpYV9jb21wcmVzc29yX2dyb3VwIiwiL2V1cm9wZV9jb21wcmVzc29yX2dyb3VwIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFuamFsaXNoYWgiLCJnaXZlbl9uYW1lIjoiQW5qYWxpIiwiZmFtaWx5X25hbWUiOiJTaGFoIiwidGVuYW50IjoibWFzdGVyIn0.aLbRYcGD22BxGmMZ9NhubsT2nuRRSnkhrb4iOkc9gNYj88pG8HpZpV48J_DheLeoh2JHxIkWJ3ncsvOsy8Cnntdj4QQhnwQAWyGoZTF7oWCiGSEau9UgiVfMHEzin_EqMIXAPXwtis9Dd4AnssUiDW4K6iHFORbJMEaDzji_yk-AiPgwhYbx68Tc5dimmq6_r9cSN8yn6UGJl_wPz2210skS9Bsy-XeoEn3o1NFe0uBDdry08Kn79WhMfIW4KQHL_AZDKVvi7cBW3WgB97tNsuNSZzmTmBnhMLaFb1OUxFXnu-d3uXOiiAWYGFhiqHMK0t-LRGmpBpEzjBi8XxnTnQ

Config.yaml file

_meta:
  type: "config"
  config_version: 2
config:
  dynamic:
    authc:
      basic_internal_auth_domain:
        http_enabled: true
        transport_enabled: true
        order: 2
        http_authenticator:
          type: basic
          challenge: false
        authentication_backend:
          type: intern
      openid_auth_domain:
        http_enabled: true
        transport_enabled: true
        order: 0
        http_authenticator:
          type: openid
          challenge: false
          config:
            openid_connect_idp:
              enable_ssl: true
              verify_hostnames: false
              pemtrustedcas_filepath: /usr/share/opensearch/config/certificates/ca/ca.pem
            subject_key: preferred_username
            roles_key: groups
            openid_connect_url: https://172.23.112.1:8443/auth/realms/master/.well-known/openid-configuration
        authentication_backend:
          type: noop
      jwt_auth_domain:
        description: "Authenticate via Json Web Token"
        http_enabled: true
        transport_enabled: true
        order: 1
        http_authenticator:
           type: jwt
           challenge: false
           config:
             signing_key: |-
               -----BEGIN PUBLIC KEY-----
               MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApthDHnemi4EYCDqzx1hZv4/pk0vhD2nFrEjB6SA11+tAdzyxCvKVf/QhkjQymaiO2u1ph/N6gjiH59y3HC9ciezX0ZiMjFTKVELwr8yWfOcG1BohdT0W9KlIuuI6anyVt4gwXLbfGLK9bJEchyVIFZKwvasEriB5rY3k6ZT+CsNXhlu6X9G6pdOOlIlXhc4RRl3WCWruYVhswc5U+JS7Lt3djTfJlNQs+KJXmE4/ZmvJXMiCuJgJmD6FcaqQXRwKPFJK47gmynLYmt1pk/xCePKrolyHnHdBiaQtYNo8x1S0OqOYuILwPyB/7l7vfgKqdfl4/paGUGXNrwzKw82TkwIDAQAB
               -----END PUBLIC KEY-----
             jwt_header: "Authorization"
             jwt_token_type: "Bearer"
             jwt_url_parameters: null
             #jwt_clock_skew_tolerance_seconds: 30
             roles_key: groups
             subject_key: preferred_username
        authentication_backend:
          type: noop

could you share the ../opensearch-security/roles_mapping.yml so I can see the full picture?

Thanks,
mj

roles-mapping.yml file

---
# In this file users, backendroles and hosts can be mapped to Security roles.
# Permissions for OpenSearch roles are configured in roles.yml

_meta:
  type: "rolesmapping"
  config_version: 2

# Define your roles mapping here

## Demo roles mapping

all_access:
  reserved: false
  backend_roles:
  - "admin"
  description: "Maps admin to all_access"

own_index:
  reserved: false
  users:
  - "*"
  description: "Allow full access to an index named like the username"

logstash:
  reserved: false
  backend_roles:
  - "logstash"

kibana_user:
  reserved: false
  backend_roles:
  - "kibanauser"
  description: "Maps kibanauser to kibana_user"

readall:
  reserved: false
  backend_roles:
  - "readall"

manage_snapshots:
  reserved: false
  backend_roles:
  - "snapshotrestore"

kibana_server:
  reserved: true
  users:
  - "kibanaserver"

roles.yml file

_meta:
  type: "roles"
  config_version: 2

# Restrict users so they can only view visualization and dashboard on OpenSearchDashboards
kibana_read_only:
  reserved: true

# The security REST API access role is used to assign specific users access to change the security settings through the REST API.
security_rest_api_access:
  reserved: true

security_rest_api_full_access:
  reserved: true
  cluster_permissions:
    - 'restapi:admin/actiongroups'
    - 'restapi:admin/allowlist'
    - 'restapi:admin/config/update'
    - 'restapi:admin/internalusers'
    - 'restapi:admin/nodesdn'
    - 'restapi:admin/roles'
    - 'restapi:admin/rolesmapping'
    - 'restapi:admin/ssl/certs/info'
    - 'restapi:admin/ssl/certs/reload'
    - 'restapi:admin/tenants'

# Allows users to view monitors, destinations and alerts
alerting_read_access:
  reserved: true
  cluster_permissions:
    - '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/findings/get'
    - 'cluster:admin/opensearch/alerting/workflow/get'
    - 'cluster:admin/opensearch/alerting/workflow_alerts/get'

# Allows users to view and acknowledge alerts
alerting_ack_alerts:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opendistro/alerting/alerts/*'
    - 'cluster:admin/opendistro/alerting/chained_alerts/*'
    - 'cluster:admin/opendistro/alerting/workflow_alerts/*'

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

# Allow users to read Anomaly Detection detectors and results
anomaly_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opendistro/ad/detector/info'
    - 'cluster:admin/opendistro/ad/detector/search'
    - 'cluster:admin/opendistro/ad/detectors/get'
    - 'cluster:admin/opendistro/ad/result/search'
    - 'cluster:admin/opendistro/ad/tasks/search'
    - 'cluster:admin/opendistro/ad/detector/validate'
    - 'cluster:admin/opendistro/ad/result/topAnomalies'

# Allows users to use all Anomaly Detection functionality
anomaly_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster_monitor'
    - 'cluster:admin/opendistro/ad/*'
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - 'indices_monitor'
        - 'indices:admin/aliases/get'
        - 'indices:admin/mappings/get'

# Allow users to execute read only k-NN actions
knn_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/knn_search_model_action'
    - 'cluster:admin/knn_get_model_action'
    - 'cluster:admin/knn_stats_action'

# Allow users to use all k-NN functionality
knn_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/knn_training_model_action'
    - 'cluster:admin/knn_training_job_router_action'
    - 'cluster:admin/knn_training_job_route_decision_info_action'
    - 'cluster:admin/knn_warmup_action'
    - 'cluster:admin/knn_delete_model_action'
    - 'cluster:admin/knn_remove_model_from_cache_action'
    - 'cluster:admin/knn_update_model_graveyard_action'
    - 'cluster:admin/knn_search_model_action'
    - 'cluster:admin/knn_get_model_action'
    - 'cluster:admin/knn_stats_action'

# Allow users to execute read only ip2geo datasource action
ip2geo_datasource_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/geospatial/datasource/get'

# Allow users to use all ip2geo datasource action
ip2geo_datasource_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/geospatial/datasource/*'

# Allows users to read Notebooks
notebooks_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opendistro/notebooks/list'
    - 'cluster:admin/opendistro/notebooks/get'

# Allows users to all Notebooks functionality
notebooks_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opendistro/notebooks/create'
    - 'cluster:admin/opendistro/notebooks/update'
    - 'cluster:admin/opendistro/notebooks/delete'
    - 'cluster:admin/opendistro/notebooks/get'
    - 'cluster:admin/opendistro/notebooks/list'

# Allows users to read observability objects
observability_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/observability/get'

# Allows users to all Observability functionality
observability_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/observability/create'
    - 'cluster:admin/opensearch/observability/update'
    - 'cluster:admin/opensearch/observability/delete'
    - 'cluster:admin/opensearch/observability/get'

# Allows users to all PPL functionality
ppl_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/ppl'
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - 'indices:admin/mappings/get'
        - 'indices:data/read/search*'
        - 'indices:monitor/settings/get'

# Allows users to read and download Reports
reports_instances_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opendistro/reports/instance/list'
    - 'cluster:admin/opendistro/reports/instance/get'
    - 'cluster:admin/opendistro/reports/menu/download'

# Allows users to read and download Reports and Report-definitions
reports_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opendistro/reports/definition/get'
    - 'cluster:admin/opendistro/reports/definition/list'
    - 'cluster:admin/opendistro/reports/instance/list'
    - 'cluster:admin/opendistro/reports/instance/get'
    - 'cluster:admin/opendistro/reports/menu/download'

# Allows users to all Reports functionality
reports_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opendistro/reports/definition/create'
    - 'cluster:admin/opendistro/reports/definition/update'
    - 'cluster:admin/opendistro/reports/definition/on_demand'
    - 'cluster:admin/opendistro/reports/definition/delete'
    - 'cluster:admin/opendistro/reports/definition/get'
    - 'cluster:admin/opendistro/reports/definition/list'
    - 'cluster:admin/opendistro/reports/instance/list'
    - 'cluster:admin/opendistro/reports/instance/get'
    - 'cluster:admin/opendistro/reports/menu/download'

# Allows users to use all asynchronous-search functionality
asynchronous_search_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opendistro/asynchronous_search/*'
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - 'indices:data/read/search*'

# Allows users to read stored asynchronous-search results
asynchronous_search_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opendistro/asynchronous_search/get'

# Allows user to use all index_management actions - ism policies, rollups, transforms
index_management_full_access:
  reserved: true
  cluster_permissions:
    - "cluster:admin/opendistro/ism/*"
    - "cluster:admin/opendistro/rollup/*"
    - "cluster:admin/opendistro/transform/*"
    - "cluster:admin/opensearch/controlcenter/lron/*"
    - "cluster:admin/opensearch/notifications/channels/get"
    - "cluster:admin/opensearch/notifications/feature/publish"
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - 'indices:admin/opensearch/ism/*'

# Allows users to use all cross cluster replication functionality at leader cluster
cross_cluster_replication_leader_full_access:
  reserved: true
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - "indices:admin/plugins/replication/index/setup/validate"
        - "indices:data/read/plugins/replication/changes"
        - "indices:data/read/plugins/replication/file_chunk"

# Allows users to use all cross cluster replication functionality at follower cluster
cross_cluster_replication_follower_full_access:
  reserved: true
  cluster_permissions:
    - "cluster:admin/plugins/replication/autofollow/update"
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - "indices:admin/plugins/replication/index/setup/validate"
        - "indices:data/write/plugins/replication/changes"
        - "indices:admin/plugins/replication/index/start"
        - "indices:admin/plugins/replication/index/pause"
        - "indices:admin/plugins/replication/index/resume"
        - "indices:admin/plugins/replication/index/stop"
        - "indices:admin/plugins/replication/index/update"
        - "indices:admin/plugins/replication/index/status_check"

# Allows users to use all cross cluster search functionality at remote cluster
cross_cluster_search_remote_full_access:
  reserved: true
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - 'indices:admin/shards/search_shards'
        - 'indices:data/read/search'

# Allow users to read ML stats/models/tasks
ml_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/ml/stats/nodes'
    - 'cluster:admin/opensearch/ml/model_groups/search'
    - 'cluster:admin/opensearch/ml/models/get'
    - 'cluster:admin/opensearch/ml/models/search'
    - 'cluster:admin/opensearch/ml/tasks/get'
    - 'cluster:admin/opensearch/ml/tasks/search'

# Allows users to use all ML functionality
ml_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster_monitor'
    - 'cluster:admin/opensearch/ml/*'
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - 'indices_monitor'

# Allows users to use all Notifications functionality
notifications_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/notifications/*'

# Allows users to read Notifications config/channels
notifications_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/notifications/configs/get'
    - 'cluster:admin/opensearch/notifications/features'
    - 'cluster:admin/opensearch/notifications/channels/get'

# Allows users to use all snapshot management functionality
snapshot_management_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/snapshot_management/*'
    - 'cluster:admin/opensearch/notifications/feature/publish'
    - 'cluster:admin/repository/*'
    - 'cluster:admin/snapshot/*'

# Allows users to see snapshots, repositories, and snapshot management policies
snapshot_management_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/snapshot_management/policy/get'
    - 'cluster:admin/opensearch/snapshot_management/policy/search'
    - 'cluster:admin/opensearch/snapshot_management/policy/explain'
    - 'cluster:admin/repository/get'
    - 'cluster:admin/snapshot/get'

# Allows user to use point in time functionality
point_in_time_full_access:
  reserved: true
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - 'manage_point_in_time'

# Allows users to see security analytics detectors and others
security_analytics_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/securityanalytics/alerts/get'
    - 'cluster:admin/opensearch/securityanalytics/correlations/findings'
    - 'cluster:admin/opensearch/securityanalytics/correlations/list'
    - 'cluster:admin/opensearch/securityanalytics/detector/get'
    - 'cluster:admin/opensearch/securityanalytics/detector/search'
    - 'cluster:admin/opensearch/securityanalytics/findings/get'
    - 'cluster:admin/opensearch/securityanalytics/mapping/get'
    - 'cluster:admin/opensearch/securityanalytics/mapping/view/get'
    - 'cluster:admin/opensearch/securityanalytics/rule/get'
    - 'cluster:admin/opensearch/securityanalytics/rule/search'

# Allows users to use all security analytics functionality
security_analytics_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/securityanalytics/alerts/*'
    - 'cluster:admin/opensearch/securityanalytics/correlations/*'
    - 'cluster:admin/opensearch/securityanalytics/detector/*'
    - 'cluster:admin/opensearch/securityanalytics/findings/*'
    - 'cluster:admin/opensearch/securityanalytics/mapping/*'
    - 'cluster:admin/opensearch/securityanalytics/rule/*'
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - 'indices:admin/mapping/put'
        - 'indices:admin/mappings/get'

# Allows users to view and acknowledge alerts
security_analytics_ack_alerts:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/securityanalytics/alerts/*'

Just an FYI- we’ve not updated any of the yaml files other than config.yaml, opensearch.yaml & opensearch-dashboards.yaml file