Mapping Users and Groups to Rolesedit

If you authenticate users with the native or file realms, you can manage role assignment by using the User Management APIs or the users command-line tool respectively.

For other types of realms, you must create role-mappings that define which roles should be assigned to each user based on their username, groups, or other metadata.

X-Pack security allows role-mappings to be defined via an API, or managed through files. These two sources of role-mapping are combined inside of X-Pack security, so it is possible for a single user to have some roles that have been mapped through the API, and other roles that are mapped through files.

When you use role-mappings, you assign existing roles to users. The available roles should either be added using the Role Management APIs or defined in the roles file. Either role-mapping method can use either role management method. For example, when you use the role mapping API, you are able to map users to both API-managed roles and file-managed roles (and likewise for file-based role-mappings).

Using the Role Mapping APIedit

You can define role-mappings through the role mapping API.

Each role-mapping has a distinct name which is used to interact with it via the API. The name does not affect the behaviour of the mapping in any way, but it is needed so that you can update or delete an existing mapping.

A mapping has rules that determine which users should be matched by this mapping, a list of roles that will be granted to the users that match.

The rule is a logical condition that is expressed using a JSON DSL. An mapping example with a simple rule is shown below:

{
  "roles": [ "superuser" ],
  "enabled": true,
  "rules": {
    "any": [
      {
        "field": {
          "username": "esadmin"
        }
      },
      {
        "field": {
          "groups": "cn=admins,dc=example,dc=com"
        }
      }
    ]
  }
}

This mapping matches any user where either of these conditions are met:

  • the username is esadmin
  • the user is in the cn=admins,dc=example,dc=com group

The rules can be more complex and include wildcard matching:

{
  "roles": [ "superuser" ],
  "enabled": true,
  "rules": {
    "all": [
      {
        "any": [
          {
            "field": {
              "dn": "*,ou=admin,dc=example,dc=com"
            }
          },
          {
            "field": {
              "username": [ "es-admin", "es-system" ]
            }
          }
        ]
      },
      {
        "field": {
          "groups": "cn=people,dc=example,dc=com"
        }
      },
      {
        "except": {
          "field": {
            "metadata.terminated_date": null
          }
        }
      }
    ]
  }
}

The mapping above matches any user where all of these conditions are met:

  • the Distinguished Name matches the pattern *,ou=admin,dc=example,dc=com, or the username is es-admin, or the username is es-system
  • the user in in the cn=people,dc=example,dc=com group
  • the user does not have a terminated_date
The Role Mapping DSLedit

The DSL supports the following rule types:

Type Value Type (child) Description

any

An array of rules

Evaluates to true if any of its children are true

all

An array of rules

Evaluates to true if all of its children are true

field

An object

See below

except

A single rule as an object

Only valid as a child of an all rule, the except is true if its child is false (negation).

The field Ruleedit

The field rule is the primary building block for a role-mapping expression. It takes a single object as value, and that object must contains a single member with key F and value V. The field rule looks up the value of F within the user object and then tests whether the user-value matches the provided value V.

The value specified in the field rule may be one of the following types:

Type Example Description

Simple String

"esadmin"

Matches exactly the provided value

Wildcard String

"*,dc=example,dc=com"

Matches the provided value using a wildcard

Regular Expression

"/.*-admin[0-9]*/"

Matches the provided value using a Lucene regexp

Number

7

Matches an equivalent numerical value

Null

null

Matches a null, or missing value

Array

["admin", "operator"]

Tests each element in the array in accordance with the definitions above. The match is successful if any of elements match.

Available User Fieldsedit

The user object against which the rules are evaluated has the following fields:

Name Type Description

username

string

The username by which X-Pack security knows this user.

dn

string

The Distinguished Name of the user.

groups

array-of-string

The groups to which the user belongs.

metadata

object

Additional metadata for the user.

realm

object

The realm that authenticated the user. The only field in this object is the realm name.

Example:

{
  "username": "jsmith",
  "dn"      : "cn=jsmith,ou=users,dc=example,dc=com",
  "groups"  : [ "cn=admin,ou=groups,dc=example,dc=com", "cn=esusers,ou=groups,dc=example,dc=com" ],
  "metadata": { "cn": "John Smith" },
  "realm"   : { "name": "ldap1" }
}

The groups field is multi-valued - a user may belong to many groups. When a field rule is applied against a multi-valued field, it is considered to match if at least one of the member values matches. This means that the rule:

{ "field" : { "groups" : "admin" } }

will match any user who is a member of the admin group, regardless of any other groups they may belong to.

Role Mapping Examplesedit

  • Match all users
{ "field" : { "username" : "*" } }
  • Match users who authenticated against a specific realm:
{ "field" : { "realm.name" : "ldap1" } }
  • Match users within a particular LDAP sub-tree:
{ "field" : { "dn" : "*,ou=subtree,dc=example,dc=com" } }
  • Match users within a particular LDAP sub-tree in a specific realm:
{
  "all": [
    { "field" : { "dn" : "*,ou=subtree,dc=example,dc=com" } },
    { "field" : { "realm.name" : "ldap1" } }
  ]
}

Using Role Mapping Filesedit

To use file based role-mappings, you must configure the mappings in a YAML file and copy it to each node in the cluster. Tools like Puppet or Chef can help with this.

By default, role mappings are stored in CONF_DIR/x-pack/role_mapping.yml, where CONF_DIR is ES_HOME/config (zip/tar installations) or /etc/elasticsearch (package installations). To specify a different location, you configure the files.role_mapping setting in the Active Directory, LDAP, and PKI realm settings in elasticsearch.yml.

Within the role mapping file, the security roles are keys and groups and users are values. The mappings can have a many-to-many relationship. When you map roles to groups, the roles of a user in that group are the combination of the roles assigned to that group and the roles assigned to that user.

By default, X-Pack security checks role mapping files for changes every 5 seconds. You can change this default behavior by changing the resource.reload.interval.high setting in the elasticsearch.yml file (as this is a common setting in Elasticsearch, changing its value may effect other schedules in the system).

Realm Specific Detailsedit

Active Directory and LDAP Realmsedit

To specify users and groups in the role mappings, you use their Distinguished Names (DNs). A DN is a string that uniquely identifies the user or group, for example "cn=John Doe,cn=contractors,dc=example,dc=com".

X-Pack security only supports Active Directory security groups. You cannot map distribution groups to roles.

For example, the following snippet uses the file-based method to map the admins group to the monitoring role and map the John Doe user, the users group, and the admins group to the user role.

monitoring: 
  - "cn=admins,dc=example,dc=com" 
user:
  - "cn=John Doe,cn=contractors,dc=example,dc=com" 
  - "cn=users,dc=example,dc=com"
  - "cn=admins,dc=example,dc=com"

The name of a X-Pack security role.

The distinguished name of an LDAP group or an Active Directory security group.

The distinguished name of an LDAP or Active Directory user.

We can use the role-mapping API to define equivalent mappings as follows:

PUT _xpack/security/role_mapping/admins
{
  "roles" : [ "monitoring", "user" ],
  "rules" : { "field" : { "groups" : "cn=admins,dc=example,dc=com" } },
  "enabled": true
}
PUT _xpack/security/role_mapping/basic_users
{
  "roles" : [ "user" ],
  "rules" : { "any" : [
      { "field" : { "dn" : "cn=John Doe,cn=contractors,dc=example,dc=com" } },
      { "field" : { "groups" : "cn=users,dc=example,dc=com" } }
  ] },
  "enabled": true
}
PKI Realmsedit

PKI realms support mapping users to roles, but you cannot map groups as the PKI realm has no notion of a group.

This is an example using a file-based mapping:

monitoring:
  - "cn=Admin,ou=example,o=com"
user:
  - "cn=John Doe,ou=example,o=com"

And the equivalent mappings using the API:

PUT _xpack/security/role_mapping/admin_user
{
  "roles" : [ "monitoring" ],
  "rules" : { "field" : { "dn" : "cn=Admin,ou=example,o=com" } },
  "enabled": true
}
PUT _xpack/security/role_mapping/basic_user
{
  "roles" : [ "user" ],
  "rules" : { "field" : { "dn" : "cn=John Doe,ou=example,o=com" } },
  "enabled": true
}