Skip to main content

Manage users with LDAP

Pivot can be configured to use an LDAP server to authenticate users and to map the LDAP group assignment to the Pivot roles. When Pivot is connected to an LDAP server each user is created in Pivot when they first login.

There are three principle approaches to translate LDAP user groups into Pivot roles:

  1. Pivot can manage roles by itself
  2. Pivot roles can be determined based on an attribute on the user object. This is simpler and performs only a single LDAP lookup per user login.
  3. Pivot roles can be determined by doing a second LDAP lookup after getting the user object from LDAP. This is more flexible and suitable when the LDAP directory is structured with the groups being a separate object from the user.

In the examples below, we assume that an LDAP server runs on ldap://ldap_host:389 with a bind DN of cn=admin,dc=imply,dc=io (credentials JonSn0w). The examples rely on a user named scoops to test that everything is working.

The configuration settings shown reside in the Pivot configuration file, such as the quickstart configuration file at <imply-home>/conf-quickstart/pivot/config.yaml.

Let Pivot manage the user roles

In this mode, LDAP authenticates users while Pivot manages roles (as determined by the roleAuthority property value of local). See roleAuthority for more information about this setting.

userMode: ldap-authentication

roleAuthority: 'native' # Indicate that Pivot should be managing roles

defaultRole: 'user' # The Pivot role externalId that the user will be mapped to

superAdminUser: 'james' # The username of a user that will always be made super-admin; useful for bootstrapping.

ldapOptions:
url: 'ldap://ldap_host:389' # Your LDAP server
bindDN: 'cn=admin,dc=imply,dc=io' # The admin bind dn
bindCredentials: 'JonSn0w' # The password for the admin bind dn
searchBase: 'dc=imply,dc=io' # The search base where your users are located
searchFilter: '(uid={{username}})' # The search filter that specifies how to find a specific user
caseSensitive: true # Values are evaluated in a case-sensitive manner

Test this setup by running an ldapsearch command to search for an existing user scoops in this example (adjust as needed):

ldapsearch -x -h ldap_host -p 389 -D "cn=admin,dc=imply,dc=io" -w "JonSn0w" -b "dc=imply,dc=io" "(uid=scoops)"

Returns something like:

# extended LDIF
#
# LDAPv3
# base <dc=imply,dc=io> with scope subtree
# filter: (uid=scoops)
# requesting: ALL
#

# sheldon, people, imply.io
dn: cn=sheldon,ou=people,dc=imply,dc=io
givenName: Sheldon
sn: Cooper
objectClass: imAuthUser
uid: scoops
userPassword:: YmlnLmJhbmcudGhlb3J5
mail: sheldon@imply.io
description: super-admin
cn: sheldon

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

You can set verbose: true to see the keys being returned and make sure that rolesKey is set appropriately.

Translate Pivot roles from the LDAP user object

In this mode Pivot will use a property on the LDAP user object to determine the Pivot role that the user should belong to. The ldapOptions.rolesKey indicates which key on the user object should map the external ID of the Pivot role.

# Setting verbose mode to true will log the user objects received from the LDAP server.
# This can be very helpful to tune properties like rolesKey (below)
verbose: false

userMode: ldap-authentication

superAdminUser: 'james' # The username of a user that will always made super-admin, useful for bootstrapping.
ldapOptions:
url: 'ldap://ldap_host:389' # Your LDAP server
bindDN: 'cn=admin,dc=imply,dc=io' # The admin bind dn
bindCredentials: 'JonSn0w' # The password for the admin bind dn
searchBase: 'dc=imply,dc=io' # The search base where your users are located
searchFilter: '(uid={{username}})' # The search filter that specifies how to find a specific user
rolesKey: 'description' # The key on the returned member object that represents group membership

Test this setup by running an ldapsearch command to search for an existing user scoops in this example (adjust as needed):

ldapsearch -x -h ldap_host -p 389 -D "cn=admin,dc=imply,dc=io" -w "JonSn0w" -b "dc=imply,dc=io" "(uid=scoops)"

Returns something like:

# extended LDIF
#
# LDAPv3
# base <dc=imply,dc=io> with scope subtree
# filter: (uid=scoops)
# requesting: ALL
#

# sheldon, people, imply.io
dn: cn=sheldon,ou=people,dc=imply,dc=io
givenName: Sheldon
sn: Cooper
objectClass: imAuthUser
uid: scoops
userPassword:: YmlnLmJhbmcudGhlb3J5
mail: sheldon@imply.io
description: super-admin
cn: sheldon

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

You can set verbose: true to see the keys being returned and make sure that rolesKey is set appropriately. In this case the ldapOptions config will use description as the role to map to the Pivot roles via the External Role Name:

settings-role1

Translate Pivot roles from a separate LDAP query

For a separate group search set the ldapOptions as follows:

# Setting verbose mode to true will log the user objects received from the LDAP server.
# This can be very helpful to tune properties like rolesKey (below)
verbose: false

userMode: ldap-authentication

superAdminUser: 'james' # The username of a user that will always made super-admin, useful for bootstrapping.
ldapOptions:
url: 'ldap://ldap_host:389'
bindDN: 'cn=admin,dc=imply,dc=io'
bindCredentials: 'JonSn0w'
searchBase: 'dc=imply,dc=io'
searchFilter: '(uid={{username}})'
groupSearchBase: 'ou=groups,dc=imply,dc=io'
groupSearchFilter: '(member={{dn}})'
groupSearchAttributes: ['dn', 'cn']
groupKeyAttribute: 'dn'

Test this setup by running an ldapsearch to get the user like below (adjust variables as needed).

ldapsearch -x -h ldap_host -p 389 -D "cn=admin,dc=imply,dc=io" -w "JonSn0w" -b "dc=imply,dc=io" "(uid=scoops)"

Returns something like:

# extended LDIF
#
# LDAPv3
# base <dc=imply,dc=io> with scope subtree
# filter: (uid=scoops)
# requesting: ALL
#

# sheldon, people, imply.io
dn: cn=sheldon,ou=people,dc=imply,dc=io
givenName: Sheldon
sn: Cooper
objectClass: imAuthUser
uid: scoops
userPassword:: YmlnLmJhbmcudGhlb3J5
mail: sheldon@imply.io
description: super-admin
cn: sheldon

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

And then, using the dn from the result above cn=sheldon,ou=people,dc=imply,dc=io run a second ldapsearch to get the groups like below (adjust variables as needed).

ldapsearch -x -h ldap_host -p 389 -D "cn=admin,dc=imply,dc=io" -w "JonSn0w" -b "ou=groups,dc=imply,dc=io" "(member=cn=sheldon,ou=people,dc=imply,dc=io)"

Returns something like:

# extended LDIF
#
# LDAPv3
# base <ou=groups,dc=imply,dc=io> with scope subtree
# filter: (member=cn=sheldon,ou=people,dc=imply,dc=io)
# requesting: ALL
#

# boys, groups, imply.io
dn: cn=boys,ou=groups,dc=imply,dc=io
objectClass: groupOfNames
member: cn=jack,ou=people,dc=imply,dc=io
member: cn=sheldon,ou=people,dc=imply,dc=io
member: cn=marcel,ou=people,dc=imply,dc=io
cn: boys

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Then use the dn property of the returned groups to map to the Pivot roles via the External Role Name:

settings-role

For more information, see the Pivot configuration documentation.