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 licence 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