# Associating LDAP Roles to Tags

**URL:** <https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246>\
**Category:** Elasticsearch\
**Created:** [November 10, 2017, 9:19pm UTC](https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246 "2017-11-10T21:19:33Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![djtecha](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/djtecha/32/54011_2.png) [@djtecha](https://discuss.elastic.co/u/djtecha)\
**Post date:** [November 10, 2017, 9:19pm UTC](https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246/1 "2017-11-10T21:19:33Z")

</div>

I'm trying to use the list of Roles associated to an ldap user as a DLS security option. Currently we mark logs with tags upstream and I'm trying to use the template that's in your docs. I have gotten certain things to match such as \_user.username or \_user.metadata.cn when I passed the data through, but believe this has something to do with Roles being an array.

roles.yml

```
engineer_user:
  cluster: []
  indices:
    - names: ['engineer-*']
      privileges: ['read']
      query: '{
                "template": {
                  "source": {
                   "term": { "tags.keyword": "{{_user.roles}}" }
                 }
                }
              }'

```

And here is my associated user:

```
{
  "username" : "test",
  "roles" : [
    "kibana_user",
    "engineer_user",
    "Engineering-SysOps",
    "Engineering-jenkins-ci-users"
  ],
  "full_name" : null,
  "email" : null,
  "metadata" : {
    "ldap_dn" : "uid=test,ou=Users",
    "ldap_groups" : [
      "cn=Engineering-misc-vpn,ou=Users
    ]
  },
  "enabled" : true
}

```

And finally a topic that should return:

```
  {
    "_index": "engineer-2017.11.10",
    "_type": "doc",
    "_id": "AV-nWAXqJXNbdGXr7alm",
    "_score": 2.4451666,
    "_source": {
      "input_type": "log",
      "pid": "32539",
      "source": "/var/log/test.log",
      "message": "REDACTED",
      "type": "log",
      "tags": ["Engineering-SysOps"],
      "hostname": "ip-10-10-1-232",
      "@timestamp": "2017-11-10T19:11:22.577Z",
      "beat": {
        "hostname": "ip-10-10-1-232"
      },
      "Level": "DEBUG",
      "time_of_event": "2017-11-10T19:11:22.407085+00:00"
    }
```

---

<div class="post-metadata">

**Author:** ![djtecha](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/djtecha/32/54011_2.png) [@djtecha](https://discuss.elastic.co/u/djtecha)\
**Post date:** [November 10, 2017, 10:39pm UTC](https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246/2 "2017-11-10T22:39:23Z")

</div>

Kind of feels like {{\_user.roles}} is being passed as a sting, or I'm trying to compare 2 arrays (the tags.keyword array and the \_users.roles array). Is there a good way to do this comparison here to find if ANY elements match?

---

<div class="post-metadata">

**Author:** ![djtecha](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/djtecha/32/54011_2.png) [@djtecha](https://discuss.elastic.co/u/djtecha)\
**Post date:** [November 10, 2017, 10:46pm UTC](https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246/3 "2017-11-10T22:46:09Z")

</div>

So with templating, shouldn't this be creating 4 queries here? one for each role? So the expanded role would be more like this?

```
engineer_user:
  cluster: []
  indices:
- names: ['engineer-*']
  privileges: ['read']
  query: '{
            "template": {
              "source": {
               "term": { "tags.keyword": "kibana_user" }
             }
            }
          }'
  query: '{
            "template": {
              "source": {
               "term": { "tags.keyword": "engineer_user" }
             }
            }
          }'
  query: '{
            "template": {
              "source": {
               "term": { "tags.keyword": "Engineering-SysOps" }
             }
            }
          }'
  query: '{
            "template": {
              "source": {
               "term": { "tags.keyword": "Engineering-jenkins-ci-users" }
             }
            }
          }'
```

---

<div class="post-metadata">

**Author:** ![djtecha](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/djtecha/32/54011_2.png) [@djtecha](https://discuss.elastic.co/u/djtecha)\
**Post date:** [November 11, 2017, 12:14am UTC](https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246/4 "2017-11-11T00:14:45Z")

</div>

Ok, figured it out. It might help to add an example of a query that uses roles btw in your docs. For others that get stuck this is how I got it working, using the match vs term part of the query:

```
engineer_user:
  cluster: []
  indices:
- names: ['engineering-*']
  privileges: ['read']
  query: '{
            "template": {
              "source": {
               "match": { "tags": "{{_user.roles}}" }
             }
            }
          }'
```

---

<div class="post-metadata">

**Author:** ![Mike.Barretta](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mike.barretta/32/16688_2.png) [@Mike.Barretta](https://discuss.elastic.co/u/Mike.Barretta)\
**Post date:** [November 13, 2017, 2:53pm UTC](https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246/5 "2017-11-13T14:53:43Z")

</div>

Actually a bit surprised if this is working as you intend. As far as I know, `{{_user.roles}}` is being expanded as `[0=<tag1>, 1=<tag2>, ...]`. To get a nice list, you can use features of the [search template](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-template.html) semantics, giving you the ability to do

```auto
{{#toJson}}_user.roles{{/toJson}}

```

That should result in your lists rendering as you want.

Your match query is currently masking this difference because you're doing a full text search instead of a keyword match.

However! The way the term/s query works, you essentially are doing an OR: if any `_user.roles` exist in `tags`, you'll get a match. Is that the behavior you seek? Or rather, are you looking to say "this document can only be viewed by users with all of the tagged roles? If the former, good! If the latter, things are more complicated. Thankfully, a change is coming (hopefully) in release 6.1 which [exposes a new Lucene query](https://github.com/elastic/elasticsearch/issues/26915) allowing the AND logic as well as more complete control of the number/percentage of terms that must match for the whole document to match. With that, you'll be doing a `terms_set` query in the role template vs a plain `terms`.

---

<div class="post-metadata">

**Author:** ![djtecha](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/djtecha/32/54011_2.png) [@djtecha](https://discuss.elastic.co/u/djtecha)\
**Post date:** [November 13, 2017, 7:20pm UTC](https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246/6 "2017-11-13T19:20:43Z")

</div>

Do you have a working role you could provide for me here? And you are correct It does match part of the values but turns out it's also matching on things it shouldn't be. I'm trying to just say if there's any tag that exists in the users role array then they should have access to the document.

---

<div class="post-metadata">

**Author:** ![Mike.Barretta](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mike.barretta/32/16688_2.png) [@Mike.Barretta](https://discuss.elastic.co/u/Mike.Barretta)\
**Post date:** [November 13, 2017, 8:52pm UTC](https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246/7 "2017-11-13T20:52:11Z")

</div>

Using your role definition, you should be fine doing:

```auto
engineer_user:
  cluster: []
  indices:
- names: ['engineering-*']
  privileges: ['read']
  query: '{
     "template": {
         "source": {\"constant_score\": {\"filter\": {\"terms\": {\"tags\": {{#toJson}}_user.roles{{/toJson}} } } } }
     }
  }'

```

Couple things to note:

- The query is "embedded" under `source` due to the fact that your `_user.roles` is a list (mustache template will render it like `["role1", "role2"]`) and lists can't be surrounded by quotes. Unescaped quotes mean quotes around your list: `"["role1","role2"]"`
- I used a constant score filter mostly for performance reasons. I'm guessing your role match logic is not meant to contribute to result scoring (i.e. it's a filter), so `constant_score` forces the terms match to happen in a [filter context](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html); much faster!

---

<div class="post-metadata">

**Author:** ![djtecha](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/djtecha/32/54011_2.png) [@djtecha](https://discuss.elastic.co/u/djtecha)\
**Post date:** [November 13, 2017, 9:48pm UTC](https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246/8 "2017-11-13T21:48:59Z")

</div>

ahh thank you. I was so close 🙂 Also, I had to change tags to tags.keyword (but that's just a note for me in the future).

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [December 11, 2017, 9:49pm UTC](https://discuss.elastic.co/t/associating-ldap-roles-to-tags/107246/9 "2017-12-11T21:49:00Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
