Kibana ROR Multi tenancy with JWT

Hi Simone,

I have indexed customer data based on customer partition like follows,

perimeter-customerA-2018-11-09
perimeter-customerB-2018-11-09
perimeter-customerC-2018-11-09

So i would like to authenticate the users using JWT Token, In the documentation i have read we can pass the roles permission and the user name in the jwt token,

How can we define the indices policy per user , In my case

User john need access with perimeter-customerA-2018-11-09 and
User peter need access with perimeter-customerB-2018-11-09

In the below how can we map the user with indices

readonlyrest:
    access_control_rules:
    - name: Valid JWT token with a viewer role
      kibana_access: ro
      jwt_auth:
        name: "jwt_provider_1"
        roles: ["viewer"]
        
    - name: Valid JWT token with a writer role
      kibana_access: rw
      jwt_auth:
        name: "jwt_provider_1"
        roles: ["writer"]
        
    jwt: 
    - name: jwt_provider_1
      signature_algo: RSA
      signature_key: "your_signature"
      user_claim: email
      roles_claim: resource_access.client-app.roles # JSON-path style
      header_name: Authorization

Looking forward for your answer .

Hi @mohankumar!

You can refer to the current username as a dynamic variable within many rules, including the indices rule. To follow your requirement, something like this would probably do the trick:

readonlyrest:
    access_control_rules:
    - name: Valid JWT token with a viewer role
      kibana_access: ro
      jwt_auth:
        name: "jwt_provider_1"
        roles: ["viewer"]
      indices: [".kibana", "perimeter-@user-*"]
        
    - name: Valid JWT token with a writer role
      indices: [".kibana", "perimeter-@user-*"]
      kibana_access: rw
      jwt_auth:
        name: "jwt_provider_1"
        roles: ["writer"]
        
    jwt: 
    - name: jwt_provider_1
      signature_algo: RSA
      signature_key: "your_signature"
      user_claim: email
      roles_claim: resource_access.client-app.roles # JSON-path style
      header_name: Authorization

Notice how:

  1. You need to allow the .kibana index within the list of allowed indices for kibana users
  2. The order in which you write the rules inside an ACL block does not count (I added the indices rule in different places in two similar ACL blocks).

I got your point, I need little more clarification on the above

I have indices like

perimeter-1-2018-11-09
perimeter-2-2018-11-09
perimeter-3-2018-11-09
perimeter-4-2018-11-09
perimeter-5-2018-11-09

(The number 1,2,3,4,5 presented in the above indices are respective customer id’s)

But in user name ,i have to allow for some users to access more than one customer id’s

indices: [".kibana", "perimeter-@user-*"]

Hope in the above @user will get the details from jwt claim of the user. but i have to map the different customer indices to specific user at run time.

Is there any possible way to send the multiple customerid’s by jwt and using dynamically

     indices: [".kibana", "perimeter-@customerid-*",]

or

Is there any way to pass the indices dynamically with jwt token claim

Thanks
Mohankumar.S

Yes the @user variable comes from the value of the claim called like what you put in user_claim, that is “email” in your case.


As of today, JWT claims are not replaced as dynamic variables, but I don’t see why not to add this feature.

     indices: [".kibana", "perimeter-@{jwt:jsonpath.to.string1}-*", "perimeter-@{jwt:jsonpath.to.string2}-*"]

Would this help you?

Sure , will try this. thanks

Did this actually get implemented?

not just yet @memelet! Will add it to our internal Jira

Has this feature been implemented?

not yet, raised in priority. Do you depend on this, @ravjanga?

We are working on a multi tenant solution for our Logging cluster. This would definitely help in keeping the configuration on the readonlyrest side to the minimal and do most of the processing on our side and send the details in an encrypted JWT token.

[edit: missing explode operator according to comment below]

Hello all, this feature has been released today (ROR version 1.18.2).
As of today, you can do:

# Using JWT claims as dynamic variables
indices: [ ".kibana_@{jwt:department}", "otherIdx" ] 
#claims = { "user": "u1", "department": "infosec"}
# -> indices: [".kibana_infosec", "otherIdx"]

# Using nested values in JWT using JSONPATH as dynamic variables
indices: [ ".kibana_@{jwt:jsonpath.to.department}", "otherIdx"]  
# claims = { "jsonpath": {"to": { "department": "infosec" }}} 
# -> indices: [".kibana_infosec", "otherIdx"]

# Referencing array-typed values from JWT claims will expand in a list of strings
indices: [ ".kibana_@explode{jwt:allowedIndices}", "otherIdx"]  
# claims = {"username": "u1", "allowedIndices":  ["x", "y"] } 
# -> indices: [".kibana_x", ".kibana_y", "otherIdx"]

# Explode operator will generate an array of strings from a comma-separated string
indices: ["logstash_@explode{x-indices_csv_string}*", "otherIdx"]  
# HTTP Headers: [{ "x-indices_csv_string": "a,b"}]
# -> indices: ["logstash_a*", "logstash_b*", "otherIdx"]
1 Like
indices: [ ".kibana_@explode{jwt:allowedIndices}", "otherIdx"]  
# claims = {"username": "u1", "allowedIndices":  ["x", "y"] } 
# -> indices: [".kibana_x", ".kibana_y", "otherIdx"]

We should also use “explode” keyword in example above. “Explode” is used to split CSV variable and scatter the elements into an array (“explode” can be used only inside array context).

Without “explode” we’re going to get sth like that:

# Referencing array-typed values from JWT claims will expand in a list of strings
indices: [ ".kibana_@{jwt:allowedIndices}", "otherIdx"]  
# claims = {"username": "u1", "allowedIndices":  ["x", "y"] } 
# -> indices: [".kibana_x,y", "otherIdx"]

Thank you @coutoPL , post amended.

So if we reference a claim of type Array, it will be serialised to comma-separated string, unless we use “explode”? And this is valid also for rules that accept array values like “indices”?

yes. If you try to use “explode” in non-array context, you’ll get config malformed error on plugin and ES startup.

1 Like

documented: readonlyrest-docs/elasticsearch.md at master · beshu-tech/readonlyrest-docs · GitHub