LDAP setup example

Configuring identity and access management is complex, and each enterprise has a different LDAP directory structure. While your implementation will be based on the specific structure and needs of your organization, the principles and processes outlined here will enable you to:

  • Reduce the number of users that need to be mapped into Anaconda Enterprise (by mapping a functional role—AE5 User—to an LDAP group). This also simplifies license management through a single group membership.
  • Reduce the number of groups that are mapped into Anaconda Enterprise (by filtering groups to include only relevant functional roles and team memberships).
  • Automate the import of new groups for team memberships based on filters.
  • Automate the provision of AE5 roles to users based on group membership of functional roles.

Roles are used to determine the types of objects in Anaconda Enterprise that users with the role can access using the platform, such as packages or projects. This example is provided to help guide you through the process of mapping default Anaconda Enterprise roles to the following common functional business roles:

  • Business Analyst
  • Data Scientist
  • Data Engineer
  • DevOps
  • Administrator

Follow the general processes outlined below for your specific implementation:

  1. Retrieving directory structures and user attributes
  2. Setting up user federation
  3. Testing your identity provider setup
  4. Configuring group mappers
  5. Mapping group roles

Retrieving directory structures and user attributes

The organizational structure of your enterprise is represented in LDAP by a directory structure or tree. You’ll need to request the bind user credentials from your Security Administrator.

While you can make assumptions about the directory structure based on the bind user credentials, it’s extremely difficult to setup an identity provider without the complete structure. For example, if the bind user credentials are uid=binduser,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io, we can deduce that the root or base of the tree is dc=tools,dc=continuum,dc=io.

Tools are available to help you visualize your organization’s directory structure. For example, phpldapadmin generated the following view:

../../_images/ldap-tree.PNG

The rest of the bind user credentials become apparent after looking at the directory structure. In this example, we can see that users live under cn=accounts > cn=users, and groups live under cn=accounts > cn=groups

Now that you know the directory structure, you can gather information about the user and group entries that you’ll need later.

You can use the ldapsearch tool—along with the binduser credentials—to learn details about an individual user based on their uid. Here’s a sample command for the user gandalf:

ldapsearch -D 'uid=binduser,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io' -W -H ldap://ipa.tools.continuum.io -b dc=tools,dc=continuum,dc=io "(uid=gandalf)"

Results will resemble the following:

# gandalf, users, compat, tools.continuum.io
dn: uid=gandalf,cn=users,cn=compat,dc=tools,dc=continuum,dc=io
objectClass: posixAccount
objectClass: ipaOverrideTarget
objectClass: top
gecos: gandalf the grey
cn: gandalf the grey
uidNumber: 1666600031
gidNumber: 1666600031
loginShell: /bin/sh
homeDirectory: /home/gandalf
ipaAnchorUUID:: OklQQTp0b29scy5jb250aW51dW0uaW86OTEyYTMwNjgtZDhmYy0xMWU4LTgzYT
UtMTIyYTE3YWNlMzJh
uid: gandalf

# gandalf, users, accounts, tools.continuum.io
dn: uid=gandalf,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
displayName: gandalf the grey
uid: gandalf
krbCanonicalName: gandalf@TOOLS.CONTINUUM.IO
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
loginShell: /bin/sh
initials: gt
gecos: gandalf the grey
sn: the grey
homeDirectory: /home/gandalf
mail: gandalf@tools.continuum.io
krbPrincipalName: gandalf@TOOLS.CONTINUUM.IO
givenName: gandalf
cn: gandalf the grey
ipaUniqueID: 912a3068-d8fc-11e8-83a5-122a17ace32a
uidNumber: 1666600031
gidNumber: 1666600031
krbPasswordExpiration: 20181026085310Z
krbLastPwdChange: 20181026085310Z
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io
memberOf: cn=grp-ae5-user,cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io
memberOf: cn=grp-ae5-wizards,cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io
memberOf: cn=grp-lord-of-the-rings,cn=groups,cn=accounts,dc=tools,dc=continuum
,dc=io

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2

Within these results, you’ll find the information you need to set up user federation for LDAP.


Setting up LDAP user federation

You’ll use the Anaconda Enterprise Administrative Console’s Authentication Center to add LDAP as your identity provider:

  1. Login to Anaconda Enterprise, click the Menu icon icon in the top right corner, then click the Administrative Console link in the bottom of the slideout menu.
  1. Click Manage Users and login to the Authentication Center using the Administrator credentials configured after installation.
../../_images/auth-center.png

  1. In the Configure menu on the left, select User Federation.
  2. Select ldap from the Add provider selector to display the Add user federation provider Required Settings.
  3. Configure the fields as follows: (Bold items are described in more detail below the table.)
Field Setting
Enabled ON
Console Display Name ldap(tools.continuum.io)
Priority 0
Import Users ON
Edit Mode READ_ONLY
Sync Registration OFF
Vendor Red Hat Directory Server
Username LDAP attribute uid
RDN LDAP attribute uid
UUID LDAP attribute uidNumber
User Object Classes person,organizationalperson,inetorgperson
Connection URL ldap://ipa.tools.continuum.io:389
Users DN cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
Authentication Type simple
Bind DN uid=binduser,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
Bind Credential  
Custom User LDAP Filter (&(objectClass=person)(uid=*)(memberOf=cn=grp-ae5-user,cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io))
Search Scope One level
Validate Password Policy OFF
User Truststore SPI Only for ldaps
Connection Pooling ON
Connection Timeout  
Read Timeout  
Pagination ON
Allow Kerberos authentication OFF
User Kerberos for Password Authentication OFF
Batch Size 1000
Periodic Full Sync OFF
Periodic Changed Users Sync OFF
Cache Policy DEFAULT

Vendor

When you select a vendor from the drop-down list, defaut values for the the most commonly used attributes will be prefilled. Be sure to select the correct one, and note that the default values may not match the way your organization has set up their application. Our example uses Red Hat Directory Server, which is based on Free IPA.

Username, RDN, UUID, User Object Classes, Users DN and Bind DN

Locate the values for these fields in the results of the ldapsearch command you ran previously. The following table outlines how the fields map to the relevant values from our gandalf user example:

Field LDAP Search Value Description
Username uid: gandalf The unique ID used to identify the user.
RDN uid: gandalf Usually the same as the Username, but may default to something else depending on the vendor selected
UUID uidNumber: 1666600031 Unique identifier
User Object Classes

objectClass: person objectClass: organizationalperson

objectClass: inetorgperson

User object classes combined in a single field
Users DN dn: uid=gandalf,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io The dn less the uid entry
Bind DN uid=binduser,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io Usually provided by Security Admin

Custom User LDAP Filter

You can use a custom filter to restrict which users are returned from LDAP. In this case, we want only those persons (objectClass=person) with any uid (uid=*) that are a member of group grp-ae5-user (memberOf=cn=grp-ae5-user,cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io). No other users will be able to log in, thereby preventing unauthorized access. This is also useful for managing licences, as users will have to be explicitly added to this group to be able to access the platform.

Filters also limit the need to synchronize a large number of objects from LDAP, which will help prevent out of memory errors in the auth pod.

Note

Avoid the temptation to add new groups into the Custom User LDAP Filter. LDAP search criteria are notorious for their complexity, and if it’s implemented incorrectly, all user access could be suspended or functionality disabled.


Testing your provider setup

Use the Test connection and Test authentication buttons to verify that the platform can connect to the provider with the credentials provided. You’ll need to resolve any errors before continuing.

By default, users will not be synced from LDAP until they log in. To test whether the Custom User LDAP Filter is working correctly, you can add or remove users in LDAP, then enable the sync settings to see if your changes are picked up and user authentication works as expected.

After you save the Required Settings, the provider is listed under User Federation:

../../_images/auth-user-federation.PNG

Configuring group mappers

After you have sucessfully set up user federation, set up a group mapper for your identify provider using the Mappers tab. For example, you can create one called ldap-group-mapper and configure it based on the results generated by the ldapsearch command. In this case, we ran the command against a known group to retrieve additional information needed:

ldapsearch -D 'uid=binduser,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io' -W -H ldap://ipa.tools.continuum.io -b dc=tools,dc=continuum,dc=io "(cn=grp-ae5-user)"

With the following results:

# grp-ae5-user, groups, compat, tools.continuum.io
dn: cn=grp-ae5-user,cn=groups,cn=compat,dc=tools,dc=continuum,dc=io
objectClass: posixGroup
objectClass: ipaOverrideTarget
objectClass: ipaexternalgroup
objectClass: top
gidNumber: 1666600026
memberUid: czhang
memberUid: dlawrence
memberUid: edill
memberUid: escissorhands
memberUid: gcavanaugh
memberUid: jsandhu
memberUid: rbarthelmie
memberUid: vghadban
memberUid: gandalf
ipaAnchorUUID:: OklQQTp0b29scy5jb250aW51dW0uaW86NGFhOTQ4NzYtZDg4YS0xMWU4LWE2ZD
ctMTIyYTE3YWNlMzJh
cn: grp-ae5-user

# grp-ae5-user, groups, accounts, tools.continuum.io
dn: cn=grp-ae5-user,cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
objectClass: ipausergroup
objectClass: ipaobject
objectClass: posixgroup
cn: grp-ae5-user
ipaUniqueID: 4aa94876-d88a-11e8-a6d7-122a17ace32a
gidNumber: 1666600026
member: uid=czhang,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
member: uid=dlawrence,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
member: uid=edill,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
member: uid=escissorhands,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
member: uid=gcavanaugh,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
member: uid=jsandhu,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
member: uid=rbarthelmie,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
member: uid=vghadban,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io
member: uid=gandalf,cn=users,cn=accounts,dc=tools,dc=continuum,dc=io

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2
Field LDAP Search Value
Name * ldap-group-mapper
Mapper Type group-ldap-mapper
LDAP Groups DN cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io
Group Name LDAP Attribute cn
Group Object Classes groupOfNames
Preserve Group Inheritance ON
Ignore Missing Groups OFF
Membership LDAP Attribute member
Membership Attribute Type DN
Membership User LDAP Attribute uid
LDAP Filter (cn=grp-ae5*)
Mode READ_ONLY
User Groups Retrieve Strategy LOAD_GROUPS_BY_MEMBER_ATTRIBUTE
Member-Of LDAP Attribute memberOf
Mapped Group Attributes  
Drop non-existing groups during sync OFF

Note

Avoid the temptation to add new groups into the LDAP Filter in the Group Mapper. LDAP search criteria are notorious for their complexity, and if it’s implemented incorrectly all user access could be suspended or functionality disabled.

LDAP Groups DN

Derived from the ldapsearch field: dn: cn=grp-ae5-user,**cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io**

Group Name LDAP Attribute

Derived from the ldapsearch field: cn: grp-ae5-user

Group Object Classes

A default should have been selected. In this case it is objectClass: groupofnames.

LDAP Filter

All relevant groups—whether they are based on functional role or team membership–have been set up with the prefix grp-ae5-. This prefix is used to filter the relevant groups from the User Federation provider, preventing any unnecessary groups from being pulled into the AE platform.

For example, the user Gandalf is a member of the following groups:

memberOf: cn=ipausers,cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io
memberOf: cn=grp-ae5-user,cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io
memberOf: cn=grp-ae5-wizards,cn=groups,cn=accounts,dc=tools,dc=continuum,dc=io
memberOf: cn=grp-lord-of-the-rings,cn=groups,cn=accounts,dc=tools,dc=continuum

If you perform a group synchronisation, only the groups in bold will be imported. Additionally, when Gandalf logs in, only the grp-ae5-prefixed groups from his profile will be imported. You can test this by deleting the grp-ae5-wizards group, then login as the user gandalf. His team membership group grp-ae5-wizards will be visible in the Auth Center, but the group grp-lord-of-the-rings will be filtered out and therefore not imported.


Mapping group roles

As a final step, you can map Anaconda Enterprise roles to the LDAP groups that are imported into the platform.

In this example, we’ll assign functional role groups the default roles that will allow them to interact with the platform in a way that makes sense for the business. You can also create custom roles, if needed.

LDAP Group ae-admin ae-creator ae-deployer ae-uploader offline_access uma_authorization Description
grp-ae5-biz-analyst         X   Business Analysts can access the system. They cannot create projects or grant others access to the system.
grp-e5-data-scientist   X X X X X Data Scientists can create and share projects, but cannot deploy them.
grp-ae5-data-engineer   X   X X X Data Engineers can additionally deploy projects, as well as grant access to others.
grp-ae5-devops     X X X   DevOps can deploy projects and upload packages, but cannot create projects.
grp-ae5-sec-admin             This group should be used to administer user access within the system. Therefore, no roles should be defined in the AnacondaPlatform realm. If required, roles can be defined and access granted in the Auth Center Master realm.
grp-ae5-sysadmin X           By default, the ae-admin role is a superuser for all other roles.
grp-ae5-sysacct             The roles for system accounts are yet to be defined. These could be used for automated CI/CD tasks.
grp-ae5-user             This is used as a coarse-grained control for access to AE5, so no roles are defined.
grp-ae5-wizards             This is a team membership role, so no AE roles are defined for it.

Note

Functional role groups should be setup once and left alone.

Use the Role Mappings tab to assign the appropriate role(s) to each group:

../../_images/group-role-mapper.png