RoR Enterprise: Kibana access vs index access

Hi,
RoR Enterprise 1.19.4
Elastic and Kibana 6.8.0

Lets say we have a config like:

  - name: "RO access to kibana_test"
    indices: [".kibana_test"]
    kibana_access: ro
    kibana_index: ".kibana_test"
    groups: ["kibana_test_RO"]
  - name: "READ access to logstash"
    indices: ["logstash*"]
    actions: ["indices:data/read/*"]
    groups: ["READ_logstash"]
  users:
  - username: test_ro_user
    auth_key: test_ro_user:xxx
    groups: ["kibana_test_RO", "READ_logstash"]

I would expect that when test_ro_user would login he goes into the .kibana_test with RO rights on that Kibana (because he has the group kibana_test_RO as only group with a kibana index).
This also happens.

And because he is a member of the group READ_logstash he is allowed to read any index starting with logstash*.
This doesn’t happen :frowning:

If I try this, the audit log gives a message “INDEX NOT EXIST” with this logic trail.

 RESOLVED:[group=kibana_test_RO]]
 [RO access to kibana_test-> RULES:[groups->true
 kibana_access->true
 indices->false]
 RESOLVED:[user=test_ro_user;group=kibana_test_RO;av_groups=kibana_test_RO]]
 [READ access to logstash-> RULES:[groups->false]
 RESOLVED:[group=kibana_test_RO]]

The group READ_logstash doesn’t match while the user is a member of this group.
The user doesn’t have the possibility to switch to a different context (the dropdown menu isn’t present).
So it seems only the active group counts for the rights?

Why would I want this?
We run a multitenancy platform where multiple tenants should have read access to the same indices (and most users are also members of multiple tentants :slight_smile: )
I would like to define one set of access rules where I define which groups have access to which kibana tentants.
And a seperate set of access rules where I can give access to certain data sets.

For example:
user1 has a group list like:
[“ro_kibana_tentant1”, “ro_kibana_tenant2”, “rw_kibana_tenant3”, “READ_salesdata”, “READ_visitors”]
And in tentant1, 2 and 3 the user would have access to salesdata and visitors (if the relevant index patterns are created ofcourse).

user2 has a group list like:
[“ro_kibana_tentant1”, “rw_kibana_tenant2”, “READ_salesdata”]
And in tenant1 and 2 this user only has access to salesdata

Is this possible?
Am I thinking completely wrong?
How would you approach this?
I am open for great suggestions because I am at the point “Can’t see the Wood for the Trees” :thinking:

Hi @ronald.vanboven, excellent question! I will do my best to explain it clearly:

When ROR Kibana queries Elasticsearch, it also sends a header “x-ror-group-current” that forces the current group to the one selected in the drop down menu (tenancy selector).
So on the ES side, the ACL will be pre-filtered to retain only the blocks that apply for the current group; effectively, like if that user only belonged to that single group.

This allows us to have a user belonging to both a high privileges tenancy and a low privileges tenancy at the same time and being able to impersonate either of the two roles without permissions leaks.

What you are trying to do is role based access control (RBAC) which requires an entirely different ACL syntax, and we didn’t implement it yet. We should though, by the end of the year.

a thing that could be done, is using the groups names as a dynamic variable to compose the indices rule.

Please @coutoPL can confirm they could do something like the following?

indices: [ ".kibana_tenancy", "@{acl:groups}-*" ]

and have it converted dynamically to:

indices: [ ".kibana_tenancy", "logstash-*", "other_group_name-*" ]

Hi,
Your first message makes perfect sense and was a bit what I was expecting.
Good to hear you are making something towards this.

The second message would require a bit more explenation for me to fully understand.

I do have a different question then.
If I define a group like:

  - name: "RO access to kibana_test"
    indices: [".kibana_test", "logstash*"]
    kibana_access: ro
    kibana_index: ".kibana_test"
    groups: ["kibana_test_RO"]

And user connects directly to elasticsearch HTTP with a user with only this group and only this accessrule.
What kind of actions would this user be allowed to do to the logstash* index?
Only read? Or also write actions?

And for completeness:

  - name: "RW access to kibana_test"
    indices: [".kibana_test", "logstash*"]
    kibana_access: rw
    kibana_index: ".kibana_test"
    groups: ["kibana_test_RW"]

What access would the user get here? Only read or also write?

The kibana_access rule is a macro rule that allows you some write privileges on your current kibana index, and no write access to any other indices. This is true for any value of kibana_access (ro_strict, ro, rw, admin).

The reason is that normally, a Kibana session is made to interact with data indices in read only mode, and it’s the interest of the administrator that the user don’t accidentally change the data indices (think: delete a logstash index accidentally).

The kibana_access rule is not particularly recommended if the client is not interacting with Kibana via the browser. If your client is a HTTP user agent connecting directly to ES, you might as well use actions and indices rule directly to explicitly allow or forbid certain requests.

all read action, and some write actions will be allowed for .kibana_test index, only some read actions are going to be allowed for logstash* indices.
Which ones? the ones that we observe Kibana needs to function, we hard code them in our kibana_access rule. They are a few, you can see the code if you need to know more.

Makes sense. The users are not supposed to connect directly to Elasticsearch.
I was just curious about the what if scenario.
I was concerned the users would get full access to indices once they somehow connect to Elasticsearch.
Good to hear this is not the case.

I will work out my permission scheme based on all the above info.
Very helpfull, thank you!

By the way, if the user belongs to multiple groups, and these groups are associated to multiple blocks/tenancies, when a user connects to ES directly, the x-ror-group-current will not be present (unless they include it in purpose) so all the blocks will be evaluated (as you expected in your first comment).

yes, we support groups, but it should be configured like this:

indices: [ ".kibana_tenancy", "@explode{acl:available_groups}-*" ]

1 Like

OK amazing, so if the current user belongs to groups “logstash”, “readonlyrest”, the above will be equivalent to:

indices: [ ".kibana_tenancy", "logstash-*", "readonlyrest-*" ]

@ronald.vanboven this is what I meant above, I hope this explanation helped. Thanks @coutoPL

Ah yes, elegant solution.
This way you can define what indices a user has access to on a user level.

I am not sure if it is the path where I myself would want to go on, but I understand it’s usecase, thanks.
I am more working based on teams and a user is part of 1 or more teams.

I am going to let this all sink in for a bit and then work out my solution.
Once I have it worked out, I will post a anonimized version here for future reference for other users.

@ronald.vanboven, and for anybody else coming from Google in the future: another possibility is to keep your groups unchanged, and start using JWT based authentication. Then you can do the “@explode” expansion on a custom JSON claim (provided as an array of strings), instead of “exploding” the groups list.

indices: [ “.kibana_tenancy”, “@explode{jwt:metadata.allowed_indices}-*” ]

The same can be done with an extra field in the SAML assertion, which is fact translated as JWT, and can be referenced as JWT claims as above, using JSONPath syntax.