OpenSearch Security Part 6: LDAP Authorization
This post explains how to use LDAP groups in OpenSearch to assign security roles to users.
Reading time: 4 minutes
Summary: This article explains how to leverage existing LDAP groups for assigning roles to users in OpenSearch, building upon the previous article about LDAP user authentication. It details the process of configuring OpenSearch to authenticate users, fetch their LDAP groups, and map these groups to OpenSearch security roles, reducing user administration by utilizing the existing LDAP structure.
In the last article, we explained how to use LDAP for user authentication in OpenSearch. Let’s explore how we can leverage existing LDAP groups for assigning roles to users. The following steps can of course also be applied to Active Directory.
Recap: User Authentication
Last time, we configured OpenSearch to connect to an LDAP server for user authentication. Since LDAP organises users (as well as any other objects) in a tree structure, we had to tell OpenSearch:
- In which LDAP subtree the users are stored
- How to query this subtree for a specific user
The query for looking up users contains a placeholder variable which is replaced with the user name before submission. If a user record was found and the password is correct, authentication is successful. We then mapped the user to a security role by user name.
Authorization: Leveraging LDAP groups
LDAP not only stores users but also groups: An LDAP user can be a member of one or more groups, and groups can also be nested (“group of groups”). So instead of assigning users directly to security roles, why not use the already existing LDAP groups? Doing so reduces the user administration by a great deal: You can add new LDAP users, assign them to LDAP groups, and the OpenSearch security roles will take effect automatically.
So we want OpenSearch to:
- First, verify that the user credentials are correct (authentication, “authc”)
- As a second step, fetch all LDAP groups of the authenticated user (authorization, “authz”)
In our example, we have two LDAP groups, “devops” and “qa”. LDAP groups are similar to users. Usually, they are stored in an LDAP subtree and are identified by their Distinguished Name. For example:
copy
dn: cn=devops,ou=groups,dc=example,dc=com
dn: cn=admin,ou=groups,dc=example,dc=com
Users are usually assigned to LDAP groups by the uniqueMember attributes, like:
copy
dn: cn=devops,ou=groups,dc=example,dc=com
uniqueMember: cn=Peter Scott,ou=people,dc=example,dc=com
uniqueMember: ...
dn: cn=qa,ou=groups,dc=example,dc=com
uniqueMember: cn=Peter Scott,ou=people,dc=example,dc=com
uniqueMember: ...
Our goal is to retrieve all LDAP groups a user is a member of and then map these groups to security roles.
Enabling LDAP Authorization
LDAP authorization is very similar to authentication. We need to tell OpenSearch:
- How to connect to LDAP
- In which subtree the roles are stored
- Which LDAP query we want to use for looking up the groups for a particular user
The authz section of config.yml defines the authorization backends. Lets add an authorization backend with type ldap and enable it:
copy
config:
dynamic:
...
authc:
...
authz:
my_ldap_authenticator:
http_enabled: true
authorization_backend:
type: ldap
config:
...
Next, we need to define the connection settings. The possible values are identical to the authc section discussed in our last article. Example:
copy
authz:
my_ldap_authenticator:
http_enabled: true
authorization_backend:
type: ldap
config:
hosts:
- primary.ldap.example.com:389
- secondary.ldap.example.com:389
bind_dn: cn=admin,dc=example,dc=com
password: "password"
enable_ssl: true
pemtrustedcas_filepath: /full/path/to/trusted_cas.pem
Configuring the Roles Subtree and the Roles Query
Similar to authentication, we now need to tell OpenSearch where our LDAP roles are stored and what query should be used to look up all user groups.
copy
authz:
my_ldap_authenticator:
...
authorization_backend:
...
config:
...
rolebase: 'ou=groups,dc=example,dc=com'
rolesearch: '(uniqueMember={0})'
The
rolebase
parameter defines the LDAP groups subtree. As in the authc section, for the actual LDAP query (rolesearch
) we can use placeholders: The placeholder {0}
is replaced with the DN of the authenticated user.So if this would be an SQL server instead of an LDAP server, the query would roughly look like this:
copy
SELECT * FROM ou=groups,dc=example,dc=com WHERE uniqueMember= '<DN of the authenticated user>'
Let’s have a look again at the example above. The user “Peter Scott” is a member of the LDAP group
cn=devops,ou=groups,dc=example,dc=com
and cn=qa,ou=groups,dc=example,dc=com
. Executing the LDAP query would thus return both the devops and the qa LDAP group records.Mapping LDAP Groups to OpenSearch Security Roles
We can now use these LDAP groups to assign OpenSearch security roles. This is done in roles_mapping.yml. Instead of specifying the usernames directly, this time use the LDAP groups retrieved in the authorization step:
role_mapping.yml:
copy
devops_security_role:
backend_roles:
- "cn=devops,ou=groups,dc=example,dc=com"
qa_security_role:
backend_roles:
- "cn=qa,ou=groups,dc=example,dc=com"
This assigns the security role
devops_security_role
to all users that are part of the cn=devops,ou=groups,dc=example,dc=com
LDAP group. All users in the LDAP group cn=qa,ou=groups,dc=example,dc=com
are assigned to the security role qa_security_role
.We can now manage our users and their groups in our LDAP server, and do not need to touch the OpenSearch security configuration again. Mission accomplished!
Outlook
An LDAP directory structure can be quite complex, and there are many ways users and groups may be structured. Luckily, OpenSearch security supports a wide range of LDAP use cases. For example, OpenSearch can work with multiple LDAP servers, resolve nested groups, and also retrieve roles directly from an LDAP user record. We will discuss some of these in a follow-up article. Stay tuned!
Ready to get started?!
Let's work together to navigate your OpenSearch journey. Send us a message and talk to the team today!
Get in touch