A request can be assigned to one or more Search Guard roles. If a request is mapped to more than one role, the permissions of these roles are combined.
I understand two things from this sentence :
An http request e.g. a _search can be assigned to one specific role
If no role is specified in the request, all roles will be merged
So that raises two questions the answers to which I didn’t find :
a. How can one specify the role to be used in the request ?
b. How is the merge done ?
How did your roles look like? Also, on which version of Search Guard did you observe the behavior?
If roles don’t use DLS, FLS or exclude_* rules, roles should work in a purely additive fashion. Thus, in such a case, the behavior you observed should not happen. If it does, it would indicate a bug.
Only DLS, FLS and exclude_* rules use different logics:
As soon as a user has a role with an exclude_* rule for a specific permission, they cannot gain this permission via any other role. An exclude_* rule thus takes precedence over anything else.
For DLS, it depends on the version and configuration: For Search Guard FLX, DLS is also supposed to be additive. As soon as a user has a role without any DLS restrictions for a particular index, they get full access despite any other DLS rules. If a user has several roles with DLS restrictions, these are “or’ed” together.
For older versions, the behavior was dependent on the configuration. See for details:
For FLS, you can choose whether you design your rules in an additive or subtractive fashion by choosing either field inclusion rules or exclusion rules.
I believe this is not the correct interpretation. There is no way to choose a role to be used for a request. When processing a request, Search Guard kind of follow these rules:
First, determine the effective roles. The effective roles are a union of:
For all configured role mappings: Keys of the role mapping rules that match the current user based on backend roles, user name, host IP.
If the user comes from the internal user database: All roles specified in the attribute search_guard_roles
Determine required privileges for request
For each of the required privileges:
For each of the effective roles:
Check whether an exclusion matches the request. If yes: Abort with 403.
For each of the effective roles:
If effective role grants the privilege, mark the privilege as available for the current request
If all privileges are marked as available: pass request
Otherwise: abort
Note: In reality, other algorithms are employed. Also DLS/FLS makes it a bit more complicated.
Thanks @nils for this thorough explanation! We’re using 7.10.2-53.1.0 and the roles I was referring to were using both fls and dls. Moreover we have the default value for searchguard.dfm_empty_overrides_all which is false if I understood correctly. This explains the behaviour I was seeing, thank you !