REST API: creation of user with role does not update rolesmapping

Hi,
this is on ES 6.5.4 and SG 24.1.

I have the admin:password user with sg_all_access role.
I used it to create a user with role sg_all_access. When I check the user it exists:

$ curl -k -uadmin:password https://localhost:33533/_searchguard/api/user/tony_stark_1550230687
{
“tony_stark_1550230687”: {
“roles”: [
“sg_all_access”
],
“hash”: “”
}
}

I then run this query thinking Tony Stark can run anything - he is Ironman after all :wink:

$ curl -k -utony_stark_1550230687:2090203225 https://localhost:33533/index1/_search?pretty
{
“error” : {
“root_cause” : [
{
“type” : “security_exception”,
“reason” : “no permissions for [indices:data/read/search] and User [name=tony_stark_1550230687, roles=[sg_all_access], requestedTenant=null]”
}
],
“type” : “security_exception”,
“reason” : “no permissions for [indices:data/read/search] and User [name=tony_stark_1550230687, roles=[sg_all_access], requestedTenant=null]”
},
“status” : 403
}

So I’m surprised!! It’s Tony with sg_all_access and he cannot access indices:data/read/search?!?!

Then I check the roles mapping, indeed tony stark is not listed in there:

$ curl -k -uadmin:password https://localhost:33533/_searchguard/api/rolesmapping?pretty
{
“sg_all_access” : {
“users” : [
“admin”
]
}
}

But I created Tony with sg_all_access role, is this the normal behavior?
It looks to me not … what did I miss?

The documentation does not say anything about having to patch the rolesmapping after user creation with the RESP API:

Anyways, now I PATCH the rolesmapping:
curl -X PATCH -k -uadmin:password https://localhost:33533/_searchguard/api/rolesmapping/sg_all_access -H “Content-type: application/json” -d ’
[{“op”: “replace”, “path”: “/users”, “value”: [“admin”, “tony_stark_1550230687"]}]’

Check the rolesmapping and this time Tony is there:
$ curl -k -uadmin:password https://localhost:33533/_searchguard/api/rolesmapping?pretty
{
“sg_all_access” : {
“users” : [
“admin”,
“tony_stark_1550230687”
]
}}

And sure enough Tony Stark can now search indices:
$ curl -k -utony_stark_1550230687:2090203225 https://localhost:33533/index1/_search?pretty
{
“took” : 5,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 2,
“max_score” : 1.0,
“hits” : [
{
“_index” : “index1”,
“_type” : “_doc”,
“_id” : “0”,
“_score” : 1.0,
“_source” : {
“id” : 0
}
},
{
“_index” : “index1”,
“_type” : “_doc”,
“_id” : “1”,
“_score” : 1.0,
“_source” : {
“id” : 1
}
}
]
}
}

PS:
There is also an error in the doc concerning the return message after the creation of a user.

// SG doc says one thing and in fact the API returns something else.
// Internal users REST API endpoints | Elasticsearch Security | Search Guard
// This should be the return message according to the doc:
// withJsonPath(“message”, equalTo(“User $userName created”.toString())),

// This is what SG 24.1 in fact returns:
withJsonPath(“message”, equalTo(“‘$userName’ created.”.toString())),

The confusion here probably stems from a very unfortunate naming decision in SG6 (which has been corrected in SG7).

The default in SG6 is that we will always apply the roles mapping in order to map users to roles. This also affects the internal user database. The confusion comes from the “roles” key in the internal users configuration:

So this output here:

$ curl -k -uadmin:password https://localhost:33533/_searchguard/api/user/tony_stark_1550230687
{
“tony_stark_1550230687”: {
  “roles”: [
     “sg_all_access”
  ],
  “hash”: “”
 }
}

means that your user tony_stark_1550230687 has the backend_role (not SG role!) called “sg_all_access”.

As a next step SG would then apply the roles mapping, and since none is there for the user or the backend role, no SG role will be applied.

The roles mapping step is needed especially when you use external authentication, like LDAP, JWT, SAML, Active Directory etc. Admitted, when using the internal user database this step is not really required.

In SG6 you have the option to deactivate the roles mapping. This means you can use SG roles in the internal users file directly:

We are also working on a new feature for SG7 which will make it possible to configure SG roles in the internal users file explicitly.

Again, sorry for the confusion here!

Thx for clearing out some of the confusion.

So the backend_roles are checked against the external authentication service,

The roles mapping step is needed especially when you use external authentication, like LDAP, JWT, SAML, Active Directory etc. Admitted, when using the internal user database this step is not really required.

Here nothing but internal user db is used:

searchguard:

dynamic:
respect_request_indices_options: true
kibana:
do_not_fail_on_forbidden: true
http:
anonymous_auth_enabled: false
xff:
enabled: false
authc:
transport_auth_domain:
enabled: true
order: 2
http_authenticator:
type: basic
authentication_backend:
type: internal
basic_internal_auth_domain:
enabled: true
http_authenticator:
type: basic
challenge: true
authentication_backend:
type: internal

Therefore as mentioned in the doc, the rolesmapping should not have been necessary:

Search Guard will use the name of the authenticated user to look up the corresponding entry in the internal user database. If found, the configures roles will be assigned as backen roles to this user.

Is searchguard.roles_mapping_resolution required to be set to MAPPING_ONLY or BOTH for the configures roles will be assigned as backen roles to this user to work automatically, here the doc does not say so?

Thx :slight_smile:

No quite :wink:

  • the backend roles for a user are fetched when the user authenticates.
  • this happens for every authentication method, like LDAP, OpenID and also the internal users DB
  • In the next step, the roles mapping kicks in
  • SG will map the user to a SG role by using either the username or the backend roles

Say you have the following user definition:

myuser:
  hash: ...
  roles: 
    - myrole

Here the username is myuser, and this user has one backend role, namely myrole.

SG then looks at the role mapping configuration. If you want to assign this user to a SG role called sg_role, in the roles mapping you can use either:

sg_role:
  users:
    - myuser

or:

sg_role:
  backendroles:
    - myuser

This is the default behaviour of SG: The role mapping is mandatory, regardless what authentication type you use.

You can change this behavior by setting:

searchguard.roles_mapping_resolution: BACKENDROLES_ONLY

or

searchguard.roles_mapping_resolution: BOTH

In this case you can use a SG role in your internal users definition directly, and forget about the roles mapping altogether:

myuser:
  hash: ...
  roles: 
    - sg_role

Thx for the clarification.
Best,
Johnny

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.