I am well aware of the fact that DLS is a premium feature as it gives a clear exception with details in return. I have enabled the trial license. Please answer all my questions (Q) asked below.
My original question is related to API token and DLS.
Q-1. How to access Kibana dashbaord with an API token that has DLS configured?
Q-2. If API Tokens are deprecated, what is the alternative that supports DLS? Obviously I don't want to use username/password.
Please understand the question clearly, I can set the attribute based access control on ES. Means if I create a role from ES, DLS works fine. But I can not set the DLS/ABAC in the payload when trying from Kibana URL.
Why do I need to create the role/API_token from Kibana? This is because, there is no way to specify Kibana related permissions in the ES roles/API_token payload.
Providing the detailed payloads below, please try it out.
- Create a role on ES with ABAC/DLS enabled.
POST _security/role/my_policy
{
"indices": [{
"names": ["my_index"],
"privileges": ["read"],
"query": {
"template": {
"source": "{\"bool\": {\"filter\": [{\"terms_set\": {\"security_attributes\": {\"terms\": {{#toJson}}_user.metadata.security_attributes{{/toJson}},\"minimum_should_match_script\":{\"source\":\"params.num_terms\"}}}}]}}"
}
}
}]
}
This works fine.
- Create a role on Kibana with dashboard access rights. I am hitting the Kibana endpoint, not ES.
curl -X PUT --location "http://localhost:5601/api/security/role/abac_kibana_role_1" \
-H "Content-Type: application/json" \
-H "kbn-xsrf: reporting" \
-d "{
\"metadata\": {
\"version\": 1
},
\"elasticsearch\": {
\"cluster\": [
\"all\"
],
\"indices\": [
{
\"names\": [
\"*\"
],
\"privileges\": [
\"read\"
]
}
]
},
\"kibana\": [
{
\"base\": [],
\"feature\": {
\"discover\": [
\"all\"
],
\"visualize\": [
\"all\"
],
\"dashboard\": [
\"all\"
],
\"dev_tools\": [
\"read\"
],
\"advancedSettings\": [
\"read\"
],
\"indexPatterns\": [
\"read\"
],
\"graph\": [
\"all\"
],
\"apm\": [
\"read\"
],
\"maps\": [
\"read\"
],
\"canvas\": [
\"read\"
],
\"infrastructure\": [
\"all\"
],
\"logs\": [
\"all\"
],
\"uptime\": [
\"all\"
]
},
\"spaces\": [
\"*\"
]
}
]
}" \
--basic --user elastic:elastic123
This also works fine.
- Now, add the query attribute in the Kibana payload as used in the step-1 above. Note, the request fails cause it has a query template related to DLS/ABAC. I am sending the requests to Kibana endpoint.
curl -X PUT --location "http://localhost:5601/api/security/role/abac_kibana_role_2" \
-H "Content-Type: application/json" \
-H "kbn-xsrf: reporting" \
-d "{
\"metadata\": {
\"version\": 1
},
\"elasticsearch\": {
\"cluster\": [
\"all\"
],
\"indices\": [
{
\"names\": [
\"*\"
],
\"privileges\": [
\"read\"
],
\"query\": {
\"template\": {
\"source\": \"{\\\"bool\\\": {\\\"filter\\\": [{\\\"terms_set\\\": {\\\"security_attributes\\\": {\\\"terms\\\": {{#toJson}}_user.metadata.security_attributes{{/toJson}},\\\"minimum_should_match_script\\\":{\\\"source\\\":\\\"params.num_terms\\\"}}}}]}}\"
}
}
}
]
},
\"kibana\": [
{
\"base\": [],
\"feature\": {
\"discover\": [
\"all\"
],
\"visualize\": [
\"all\"
],
\"dashboard\": [
\"all\"
],
\"dev_tools\": [
\"read\"
],
\"advancedSettings\": [
\"read\"
],
\"indexPatterns\": [
\"read\"
],
\"graph\": [
\"all\"
],
\"apm\": [
\"read\"
],
\"maps\": [
\"read\"
],
\"canvas\": [
\"read\"
],
\"infrastructure\": [
\"all\"
],
\"logs\": [
\"all\"
],
\"uptime\": [
\"all\"
]
},
\"spaces\": [
\"*\"
]
}
]
}" \
--basic --user elastic:elastic123
This fails, as Kibana is unable to parse this template.
{"statusCode":400,"error":"Bad Request","message":"[request body.elasticsearch.indices.0.query]: expected value of type [string] but got [Object]"}
Q-3. How to set the ABAC/DLS configuration in the Payload here. Same worked in step-1?
- Let's create an user from Kibana console with the role abac_kibana_role_1 from step-2 as follows.
PUT _security/user/john
{
"username": "john",
"password":"john@123",
"roles": ["abac_kibana_role_1"],
"full_name": "John_Does",
"email": "john@gmail.com"
}
-
Login to the Kibana UI using the newly created username john
and password john@123
.
-
Create an API_token exactly as below.
POST /_security/api_key
{
"name": "test-api-key-1"
}
Copy and Save the token somewhere for later use. You will receive a response like this>
{
"id" : "siwOsIIBIqatl7Ky_6Iv",
"name" : "test-api-key-1",
"api_key" : "D8PvyzO5TjiCI3FAfUi4cQ",
"encoded" : "c2l3T3NJSUJJcWF0bDdLeV82SXY6RDhQdnl6TzVUamlDSTNGQWZVaTRjUQ=="
}
-
Now, logout from the Kibana-UI. Use the above token to access the dashboard.
You can see that I am using a chrome extension to inject the header. I am able to happily access the dashboard.
-
I will now add the ABAC/DLS config in the API token and try to use the same token to access the dashbaord again. So logout and Login to the Kibana dashboard using Username and Password again. Create another API token as below from Kibana console:
NOTE, now we are using the DLS/ABAC in the API token. Understand that this is a valid token.
POST /_security/api_key
{
"name": "test-api-key-2",
"role_descriptors": {
"abac_kibana_role_1": {
"cluster": ["all"],
"index": [
{
"names": ["*"],
"privileges": ["read"],
"query": {
"terms_set": {
"security_attributes": {
"terms": ["EXECUTIVE", "ACCOUNTING"],
"minimum_should_match_field": "required_matches"
}
}
}
}
]
}
}
}
You will get a response similar to this.
{
"id" : "tCwasIIBIqatl7KysqKl",
"name" : "test-api-key-2",
"api_key" : "vd8nb8PhRHiLFCideplPAw",
"encoded" : "dEN3YXNJSUJJcWF0bDdLeXNxS2w6dmQ4bmI4UGhSSGlMRkNpZGVwbFBBdw=="
}
- Now try to access the dashboard again using this new token
test-api-key-2
similar to step-7.
It is returning 403: forbidden.
Q-4: How did the token lost its Kibana access priviledge?
NOTE: Even if I remove the query
section completely from payload, still it does not work with Kibana.
Let me know if you need anything further. I have provided detailed payload in every step.
Please anwer all my question highlighted as Q-*