Groups rule : dynamic group names


(Ronan GUILLOU) #1

Intro
I’m a pure newby in ROR. I have read all the docs and your product seems to fit my needs :
"Displaying my metrics in a multi-tenant in order to guaranty privacy.

I would like to adopt these plugins but i see that groups are defined statically. This could be a showstopper for my project.

Problem
Today groups rule is defined like this :
`groups: [“group1”, “group2”]
Group name are statically defined.

My question : can we define a dynamic group names based on the value of a field.

Exemple :
Let’s take an exemple of an enterprise broken down into departments (hr,sales,ops)

Here is a doc (a metric )
“prometheus”: {
“labels”: {
"enterprise": “nike”,
“department”: “hr”,
},
“metrics”: {
“number_of_employees_on_vaccation”: 10
}
}

access_control_rules:
- name: Enterprise HR generic rule.
type: allow
groups: [field.prometheus.labels.enterprise_field.prometheus.labels.department_administrator]
indices: [“metrics*”]

so that all adlinistrators that are part of the group : “nike_hr_administrators” are authorized to read this doc.


(Simone Scarduzio) #2

Hello @rguillou, and welcome to ReadonlyREST Forum!

The ACL rules are evaluated before ES evaluates requests. A set of document is the result of the execution of a search request. Evaluating each document’s field and re-run the ACL for every document would defeat this logic.

What you could do, is using a mix of dynamic variables and filter rule:

- name: "Each user named after a company can see their documents (filtered reads)"
  filter: '{"query_string":{"query":"enterprise:@{user}"}}'
  indices: [".kibana", "enterprises_data-*"]

In the above example, the user “nike” can access all enterprise indices, with the condition that the field “enterprise” equals “nike”.

NB: the block above will only allow read requests, as the filter rule cannot apply to write requests.


(Ronan GUILLOU) #3

Thank you Simone for your prompt answer !!
Hum, unfortunately, nobody at ‘nike’ is called ‘nike’.

One alternative would be to include into each metric doc a new field called ‘authorized users’. This list would contain all the authorized user that are authorized to access (read) , like this :
“prometheus”: {
“labels”: {
“enterprise”: “nike”,**
“department”: “hr”,
allowed_users”: “user1,user2,user3”
},
“metrics”: {
“number_of_employees_on_vaccation”: 10
}
}
and then configuring a filter similar to this :
filter: ‘{“bool”: { “must”: { “match”: { allowed_users :"@{user}" }}}}’

so that if i log as ‘user1’ or ‘user2’ or ‘user3’ then i can have access to this metric doc.

This solution is quite heavy and if i add a new user, say user4, user4 will have access new metric but not metric older than the user creation date.
That why, the notion of dynamic group was absolutely perfect.

Simone any other idea ? I want to prove to my management that ROR is the right tool to address this multi-tenancy need. But i’m still a bit short to motivate it.


(Ronan GUILLOU) #4

Still thinking about an alternative solution …
Does the ACL have at least the value of the index or not ?

if yes, then …
If i make sure that my metric documents use an index with a format that contain enough info to describe an authorization domain.
Exemple :
metric_enterprise=nike_department=hr_26-02-2019

then :
if ROR is capable to request my “JSON external group provider” by providing as input :

  1. this index : metric_enterprise=nike_department=hr_26-02-2019
  2. the user : jdoe

then the logic of my “JSON external group provider” will be able to assess if jdoe is authorized to access the domain enterprise=nike & department=hr. It will then return a generic group name, let’s call it “group_matched”. This will match the rule :
groups: [“group_matched"]
… and we are done.
Of course if ROR decides to cache this resolution (jdoe is part of group_matched) then this logic is not good.


(Simone Scarduzio) #5

You can use dynamic variables to populate the indices rule. You can use as dynamic variables HTTP headers of the request, the name of the user, (soon) the JWT claims, but we could easily merge response headers from the JSON external group provider.

The caching of the external groups provider is there, but not sure how it would represent a problem?

- name: "Allow indices using HTTP response headers from JSON group service"
  user_groups_provider: "GroupsService"
    groups: ["group3"]
  indices: [".kibana", "@{x-belongs-to-enterprise}_hr*"]

Would this be ok?


(Ronan GUILLOU) #6

Hum, not yet but we are getting closer. I’m preparing an answer…
Fyi, in the meantime today, my collegue Adrien has installed the enterprise version as trial.


(Ronan GUILLOU) #7