TeamCity 8.0 Help

LDAP Integration

LDAP integration in TeamCity has two levels: authentication (login) and synchronization.

LDAP integration might be not trivial to configure, so it might require some trial and error approach to get the right settings. It is recommended to configure LDAP on a test server before switching it on on the production one. LDAP logs should give you enough information to understand possible misconfigurations. If you are experiencing difficulties configuring LDAP integration after going through this document and investigating the logs, please contact us and let us know your LDAP settings with a detailed description of what you want to achieve and what you currently get.

Authentication

If you need to limit the users who can log into TeamCity to LDAP (e.g. Active Directory) users, you need to configure LDAP settings and enable LDAP authentication for the server (refer to Authentication Settings page for details).

Manual auth-config.xml Configuration

You only need to use this approach if editing via Web UI is not appropriate (e.g. you need to change the authentication settings before the first TeamCity server start).

Configure <TeamCity data directory> /config/auth-config.xml as follows:

<auth-config> <auth-modules> <auth-module type="LDAP"> <!-- "allowCreatingNewUsersByLogin" property specifies what TeamCity must do when user specifies correct LDAP username and password, but does not yet exist in TeamCity (so on first successful login via LDAP). "true" (default) means to allow login and create such TeamCity user, while "false" means to deny login for such user. --> <property key="allowCreatingNewUsersByLogin">true</property> </auth-module> <!-- Another authentication modules can be configured here as well --> </auth-modules> <!-- Welcome message displayed to users on login form --> <login-description>Welcome to TeamCity, your team building environment!</login-description> <!-- Whether anonymous "view-only" logins are allowed (true|false) --> <guest-login allowed="true" /> </auth-config>

On each user login, authentication is performed by direct login into LDAP with the credentials entered in the login form. TeamCity does not store the user passwords in this case.

If the Allow creating new users on the first login option is selected (allowCreatingNewUsersByLogin property is set to true in the XML file), a new user account will be created on the first successful login. All newly created users belong to the User Group group and have all roles assigned to this group. If some specific roles are needed for the newly registered users, these roles should be granted via the All Users group.

TeamCity stores user details and settings in its own database. Refer to #Synchronization section below for information on ability to retrieve common user properties from LDAP.

ldap-config.properties Configuration

LDAP connection settings are configured in <TeamCity data directory> /config/ldap-config.properties file. See also the TeamCity Data Directory as an example.

ldap-config.properties file is re-read on any modification so you do not need to restart the server to apply changes in the file. Please make sure you always back up previous version of the file: if you misconfigure LDAP integration, you may no longer be able to log in into TeamCity. Already logged-in users are not affected by the modified LDAP integration settings because users are authenticated only on login.

The mandatory property in ldap-config.properties file is java.naming.provider.url that configures the server and root DN. The property stores URL to the LDAP server node that is used in following LDAP queries. For example, ldap://dc.example.com:389/CN=Users,DC=Example,DC=Com. Please note that the value of the property should use URL-escaping if necessary. e.g. use %20 if you need space character.

Configuring User Login

You might want to configure the integration so that users enter only the username in TeamCity login form, but LDAP server can require prefixes or suffixes to the name. This can be addressed with teamcity.auth.formatDN property (Since TeamCity 4.5, previous versions require "formatDN" as the property name). The property defines the transformation that is applied to the entered username before the LDAP login is tried. The property should reference the entered username as $login$. Note that TeamCity store the username for the user in unmodified form as entered by the user. This is necessary to allow mapping of LDAP user back to TeamCity user, refer to the teamcity.users.username property description below.

Example:

teamcity.auth.formatDN=uid=$login$,ou=people,dc=company,dc=com

Some LDAP servers support multiple formats of username. Usually, you would want to restrict the users from entering different variations of the username (otherwise, a new TeamCity user will be created for each variation). The restriction can be configured via the help of teamcity.auth.loginFilter property (Since TeamCity 4.5, previous versions require "loginFilter" as the name of the property). The property configures regular expression that entered username should comply to.

Example (allow any username):

teamcity.auth.loginFilter=.+

By default, login format is restricted to a name without "\", "/" and "@" characters. This format applies only Since TeamCity 4.5, in previous versions the pattern is to match DOMAIN\name patterns.

By default, TeamCity stores the entered login as the username in database. This value is important if you want to synchronize user information, e.g. display name or e-mail, with LDAP data (see the details below). That's why it can be useful to configure the login filter so that user may login with the username stored in LDAP only.

If LDAP server accepts several variations of the login name and they cannot be filtered by teamcity.auth.loginFilter (or it is undesirable to limit the login names to particular format), TeamCity provides ability to automatically fetch the username from LDAP. If teamcity.users.acceptedLogin property is configured, it will be used to find a user by the entered login name in LDAP and then the user will be stored/matched in TeamCity database with the username that will be retrieved from the attribute defined by teamcity.users.username property.

This logic is automatically turned on if teamcity.users.acceptedLogin property is defined. In this case teamcity.users.base (root DN for users serach) and teamcity.users.username are mandatory.

Also, you can define a teamcity.users.login.filter property with a filter to apply when searching for a user in LDAP. The property may have a $login$ substring that will be substituted with the actual login name entered by the user on TeamCity login form.

Provided these options are configured, on each login attempt TeamCity will perform a look-up in LDAP searching for the entered login and retrieve the username.

Please note that in certain configurations (for example, with java.naming.security.authentication=simple) login information will be sent to the LDAP server in not-encrypted form. For securing the connection you can refer to corresponding Sun documentation. Another option is to configure communications via ldaps protocol.

Related external link: How To Set Up Secure LDAP Authentication with TeamCity by Alexander Groß.

Active Directory

The following template enables authentication against active directory:

Add the following code to the < >/config/ldap-config.properties file (assuming the domain name is "Example.Com" and domain controller is "dc.example.com").

java.naming.provider.url=ldap://dc.example.com:389/DC=Example,DC=Com java.naming.security.principal=<username> java.naming.security.credentials=<password> teamcity.users.login.filter=(sAMAccountName=$capturedLogin$) teamcity.users.username=sAMAccountName java.naming.security.authentication=simple java.naming.referral=follow

Advanced Configuration

If you need to fine-tune LDAP connection settings, you can add java.naming options to the ldap-config.properties file: they will be passed to underlying Java library. Default options are retrieved using java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory. Refer to the Java documentation page for more information about property names and values.

You can use an LDAP explorer to browse LDAP directory and verify the settings (for example, http://www.jxplorer.org/ or http://www.ldapbrowser.com/softerra-ldap-browser.htm).

There is an ability to specify failover servers using the following pattern:

java.naming.provider.url=ldap://ldap.mycompany.com:389 ldap://ldap2.mycompany.com:389 ldap://ldap3.mycompany.com:389

The servers are contacted until any of them responds. There is no particular order in which the address list is processed.

Synchronization

LDAP synchronization is only available since TeamCity 4.5.

LDAP synchronization allows to:

  • Retrieve user's profile data from LDAP

  • Update user groups membership based on LDAP groups

  • Automatically create and remove users in TeamCity based on information retrieved from LDAP

Periodically, TeamCity fetches data from LDAP and updates users in TeamCity. You can review the last synchronization run statistics and schedule new synchronization in LDAP Synchronization section of server settings.

Common Configuration

You need to have LDAP authentication configured for the synchronization to function.

By default, the synchronization is turned off. To turn it on, add the following option to ldap-config.properties file:

teamcity.options.users.synchronize=true

You also need to specify the following mandatory properties: java.naming.security.principal and java.naming.security.credentials (they specify user credentials which are used by TeamCity to connect to LDAP and retrieve data), teamcity.users.base and teamcity.users.filter (specify the settings to search for users), and teamcity.users.username (the name of LDAP attribute containing the username).

TeamCity should be able to fetch users from LDAP and map them to the existing TeamCity users. Mapping between the LDAP user and TeamCity user is configured by teamcity.users.username property.

Example:

teamcity.users.username=sAMAccountName

User Profile Data

When properly configured, TeamCity can retrieve user-related information from LDAP (e-mail, full name, or any custom property) and store it as TeamCity user's details. If updated in LDAP, the data will be updated in TeamCity user's profile. If modified in user's profile in TeamCity, the data will no longer be updated from LDAP for the modified fields.

The user's profile synchronization is performed on user creation and also periodically for all users.

All the user fields synchronization properties store the name of LDAP field to retrieve the information from.

The list of supported user settings:

  • teamcity.users.username

  • teamcity.users.property.displayName

  • teamcity.users.property.email

  • teamcity.users.property.plugin:notificator:jabber:jabber-account

  • teamcity.users.property.plugin:vcs:<VCS type>:anyVcsRoot — VCS username for all <VCS type> roots. The following VCS types are supported: svn, perforce, jetbrains.git, cvs, tfs, vss, clearcase, starteam.

Example properties can be seen by configuring them for a user in web UI and then listing the properties via REST API.

Since TeamCity 8.0, there is an experimental feature which allows mapping user profile properties in TeamCity to a formatted combination of LDAP properties rather than to a specific property on user synchronization. To enable the mapping, add teamcity.users.properties.resolve=true into ldap-config.properties. Then you can use the %-references to LDAP attributes in the form of %ldap.userEntry.<attribute>% in the user property definitions, e.g.

teamcity.users.property.plugin\:notificator\:jabber\:jabber-account=%ldap.userEntry.name%@jabber.my.domain.com

User Group Membership

TeamCity can automatically update users membership in groups based on the LDAP-provided data. You will need to create groups in TeamCity manually and then specify the mapping on LDAP groups in <TeamCity data directory> /config/ldap-mapping.xml file. Use the TeamCity Data Directory as an example.

In the file you need to specify correspondence between TeamCity user group (determined by group id) and LDAP group (specified by group DN). For user group membership to work you also need to set the following properties in ldap-config.properties file: teamcity.options.groups.synchronize (enables user group synchronization), teamcity.groups.base and teamcity.groups.filter (specify where and how to find the groups in LDAP) and teamcity.groups.property.member (specifies the LDAP attribute holding the members of the group).

On each synchronization run, TeamCity updates the membership of users in groups that are configured in the mapping. Please note that TeamCity synchronizes membership only for users residing directly in the groups. Subgroups are not processed.

If either LDAP group or TeamCity that is configured in the mapping is not found, an error is reported. You can review the errors occurred during last synchronization run in "LDAP Synchronization" section of server settings.

See also example settings for Active Directory synchronization.

Creating and Deleting User

TeamCity can automatically create users in TeamCity, if they are found in one of the mapped LDAP groups.

By default, automatic user creation is turned off. To turn it on, set teamcity.options.createUsers property to true in ldap-config.properties file.

TeamCity can automatically delete users in TeamCity if they cannot be found in LDAP or do not belong to an LDAP group that is mapped to predefined "All Users" group. By default, automatic user deletion is turned off as well; set teamcity.options.deleteUsers property to turn it on.

Username migration

The username for the existing users can be updated upon first successful login. For instance, suppose the user had previously logged in using 'DOMAIN\user' name, thus the string 'DOMAIN\user' had been stored in TeamCity as the username. In order to synchronize the data with LDAP user can change the username to 'user' using the following options:

teamcity.users.login.capture=DOMAIN\\\\(.*) teamcity.users.login.filter=(cn=$login$) teamcity.users.previousUsername=DOMAIN\\\\$login$

The first property allows you to capture the username from the input login and use it to authenticate the user (can be particularly useful when the domain 'DOMAIN' isn't stored anywhere in LDAP). The second property teamcity.users.login.filter allows you to fetch the username from LDAP by specifying the search filter to find this user (other mandatory properties to use this feature: teamcity.users.base and teamcity.users.username). The third property allows to find the 'DOMAIN\user' username when login with just 'user', and replace it with either captured login, or with the username from LDAP.

Note that if any of these properties are not set, or cannot be applied, the username isn't changed (the input login name is used). More configuration examples are available on here.

Debugging LDAP Integration

Internal LDAP logs are stored in logs/teamcity-ldap.log file in server logs. If you encounter an issue with LDAP configuration it is advised that you look into the logs as the issue can often be figured out from the messages in there. To get detailed logs of LDAP login and synchronization processes, please use "debug-ldap" logging preset. See TeamCity Server Logs for details.

Last modified: 20 April 2023