I encountered the same issue, and this seemed to work for me.
Step 1: Create a new custom role, in this example we'll name it "my-readonly-role".
- As stated in other posts and in the OpenSearch documentation, it must have the cluster permission "cluster_composite_ops_ro".
- What does not seem to be well documented, is that the index permissions for the indices used by the dashboards, must include the allowed actions "read" and "indices:data/read/search*".
- What also does not seem to be well documented, is that you must declare index permissions for indices matching both ".kibana*" and ".opensearch_dashboards*" and its allowed actions must include "read".
Here is an example API payload that implements the above steps:
{
"cluster_permissions": [
"cluster_composite_ops_ro"
],
"index_permissions": [
{
"index_patterns": ["some_pattern*"],
"dls": "",
"fls": [],
"masked_fields": [],
"allowed_actions": ["read", "indices:data/read/search*"]
},
{
"index_patterns": [".kibana*", ".opensearch_dashboards*"],
"dls": "",
"fls": [],
"masked_fields": [],
"allowed_actions": ["read"]
}
],
"tenant_permissions": [
{
"tenant_patterns": ["*"],
"allowed_actions": ["read"]
}
]
}
Step 2: Assign your backend_roles and/or users to both your new custom role "my-readonly-role" as well as the out of the box role "opensearch_dashboards_read_only".
There may be better ways to do this, and the end user experience is not great to be honest, meaning read only users can still click edit dashboard and proceed to change things, but will get an error when they try to save. But at least this keeps them from being able to save dashboard changes, and also prevents/restricts them from navigating to "non-dashboard" parts of the web UI (security, stack management, etc.).