Internal user not able to perform operations based on internal role

I have an OpenSearch 1.2.4 cluster with the following security configs

{
    "config": {
        "dynamic": {
            "filtered_alias_mode": "warn",
            "disable_rest_auth": false,
            "disable_intertransport_auth": false,
            "respect_request_indices_options": false,
            "kibana": {
                "multitenancy_enabled": true,
                "server_username": "kibanaserver",
                "index": ".kibana"
            },
            "http": {
                "anonymous_auth_enabled": false,
                "xff": {
                    "enabled": false,
                    "internalProxies": "192\\.168\\.0\\.10|192\\.168\\.0\\.11",
                    "remoteIpHeader": "X-Forwarded-For"
                }
            },
            "authc": {
                "basic_internal_auth_domain": {
                    "http_enabled": true,
                    "transport_enabled": true,
                    "order": 1,
                    "http_authenticator": {
                        "challenge": true,
                        "type": "basic",
                        "config": {}
                    },
                    "authentication_backend": {
                        "type": "intern",
                        "config": {}
                    },
                    "description": "Authenticate via HTTP Basic against internal users database"
                }
            },
            "authz": {},
            "auth_failure_listeners": {},
            "do_not_fail_on_forbidden": true,
            "multi_rolespan_enabled": true,
            "hosts_resolver_mode": "ip-only",
            "do_not_fail_on_forbidden_empty": true
        }
    }
}

Created an internal role with all kinds of index permissions for index pattern sem*; assign this role to an internal user

curl -XPUT https://localhost:9200/_plugins/_security/api/roles/sem-role -H 'Content-Type: application/json' -d'
{
  "cluster_permissions": [
    "cluster_monitor"
  ],
  "index_permissions": [{
    "index_patterns": [
      "sem*"
    ],
    "allowed_actions" : ["*"]
  }]
}
'

curl -XPUT https://localhost:9200/_plugins/_security/api/internalusers/sem-user   -H 'Content-Type: application/json' -d'
{
  "password": "######",
  "opendistro_security_roles": ["sem-role"]
}
'

Following APIs fail for this newly created user

  1. GET Aliases
# curl https://localhost:9200/_cat/aliases/sem*?pretty -u sem-user
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "no permissions for [indices:admin/aliases/get] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
      }
    ],
    "type" : "security_exception",
    "reason" : "no permissions for [indices:admin/aliases/get] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
  },
  "status" : 403
}

Changing index_patterns to “*” fixes this access issue. But this defeats the purpose of having a role in the first place if this user is able to access all indices.

  1. INDEX DOCUMENT
# curl -u sem-user -X POST "https://localhost:9200/sem1234/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
  "@timestamp": "2000-11-15T13:12:00",
  "message": "test",
  "user": {
    "id": "abcd"
  }                         
}                            
'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "no permissions for [indices:data/write/bulk] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
      }
    ],
    "type" : "security_exception",
    "reason" : "no permissions for [indices:data/write/bulk] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
  },
  "status" : 403
}

The index pattern “sem*” works as expected for CREATE INDEX API. It allows creating index name say sem1234 and blocks creating an index with name asem1234

# curl -XPUT https://localhost:9200/sem1234?pretty -u sem-user
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "sem1234"
}
# curl -XPUT https://localhost:9200/asem1234?pretty -u sem-user
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "no permissions for [indices:admin/create] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
      }
    ],
    "type" : "security_exception",
    "reason" : "no permissions for [indices:admin/create] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
  },
  "status" : 403
}
#

Any idea why the basic APIs such as indexing documents don’t work with the given permission?

1 Like

@ronniepg The indexing should be fixed with mapping role “own_index” to this user.

The alias is a different issue and filtering does not seem to be supported, see similar case here

1 Like

@Anthony thanks for your reply.

I assigned “own_index” to this user

# curl -XGET "https://localhost:9200/_plugins/_security/api/internalusers/sem-user?pretty"
{
  "sem-user" : {
    "hash" : "",
    "reserved" : false,
    "hidden" : false,
    "backend_roles" : [ ],
    "attributes" : { },
    "opendistro_security_roles" : [
      "own_index"
    ],
    "static" : false
  }
}

Still this user is not able to index a document to an index which starts with this user’s name.

# curl -X POST "https://localhost:9200/sem-user1234/_doc/1?pretty" -H 'Content-Type: application/json' -d'{"a": "b"}'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "no permissions for [indices:data/write/index] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
      }
    ],
    "type" : "security_exception",
    "reason" : "no permissions for [indices:data/write/index] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
  },
  "status" : 403
}

One observation is that the error response has an empty backend_roles for this user.

Any ideas on what i might be missing?

Also will own_index allow to work on indices whose names don’t start with the user name?

@ronniepg Apologies if my previous reply was unclear, I meant you need to add “own_index” to the list of roles for that use, not replace.

So when you run below command:

curl --insecure -u username:password -XGET "https://localhost:9200/_opendistro/_security/authinfo?pretty"

You should see 2 roles under roles (own_index and sem-role)

@Anthony Thanks a lot. yes that worked for the basic API like indexing! I will test further…

The user is able to create the indices based on the index pattern defined in the other role, even though the index pattern for own_index says ${user_name}. I wonder how this own_index role work? I couldn’t find any docs about this role.

# curl -XGET "https://localhost:9200/_plugins/_security/api/roles/own_index?pretty"
{
  "own_index" : {
    "reserved" : true,
    "hidden" : false,
    "description" : "Allow all for indices named like the current user",
    "cluster_permissions" : [
      "cluster_composite_ops"
    ],
    "index_permissions" : [
      {
        "index_patterns" : [
          "${user_name}"
        ],
        "fls" : [ ],
        "masked_fields" : [ ],
        "allowed_actions" : [
          "indices_all"
        ]
      }
    ],
    "tenant_permissions" : [ ],
    "static" : true
  }
}

Shouldnt this own_index role be implicitly applied to all users?

1 Like

@ronniepg Glad it’s fixed. “own_index” is usually mapped to every user, but it is still an option.

@Anthony i have been testing this further. There are some APIs which don’t work for this sem-user, despite being part of the own_index role + the sem-role as defined in the OP.

  1. Define Template
# curl -XPUT  -u sem-user "https://localhost:9200/_template/sem1234?pretty" -H 'Content-Type: application/json' -d'
> {
>   "index_patterns": ["sem1234*"],
>   "template": {
>     "settings": {
>       "number_of_shards": 2,
>       "number_of_replicas": 1
>     },
>     "mappings": {
>       "properties": {
>         "timestamp": {
>           "type": "date",
>           "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
>         },
>         "value": {
>           "type": "double"
>         }
>       }
>     }
>   }
> }
> '
Enter host password for user 'sem-user':
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "no permissions for [indices:admin/template/put] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
      }
    ],
    "type" : "security_exception",
    "reason" : "no permissions for [indices:admin/template/put] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
  },
  "status" : 403
}
  1. Index Rollover
# curl -u sem-user -X POST "https://localhost:9200/sem-source1/_rollover?pretty"
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "no permissions for [indices:admin/rollover] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
      }
    ],
    "type" : "security_exception",
    "reason" : "no permissions for [indices:admin/rollover] and User [name=sem-user, backend_roles=[], requestedTenant=null]"
  },
  "status" : 403
}

Any reason why these are not permitted since both the own_index and sem-role includes all index permissions?

@ronniepg The indices:admin/template/put needs to be applied on the cluster level.

and the indices:admin/rollover permission would need to be applied to “*” indices.

Hope this helps

@Anthony Thanks for your reply! Both the APIs are permitted after implementing your suggestions.

Had a few questions.

  1. Why are Template APIs listed under Index Permissions Permissions - OpenSearch documentation, if these are actually Cluster permissions? Also is it possible to restrict these Template APIs based on an index pattern?

  2. Why does the rollover API require “*” index pattern? Can’t it restrict based on the the source and target index name? Basically I dont want this user to rollover indices for some other user.

@ronniepg You are correct, that permission page does not appear to be completely accurate.

Regarding the other questions, these operations are considered to be admin. I don’t think opensearch filters on the template or alias, therefore the permission needs to be for everything.

Might be worth raising a ticket for this here and referencing this case.

I would also suggest looking at ISM to archive what you are looking (RE rollover).