1--- 2stage: Manage 3group: Access 4info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments 5--- 6 7# LDAP synchronization **(PREMIUM SELF)** 8 9If you have [configured LDAP to work with GitLab](index.md), GitLab can automatically synchronize 10users and groups. This process updates user and group information. 11 12You can change when synchronization occurs. 13 14## User sync 15 16Once per day, GitLab runs a worker to check and update GitLab 17users against LDAP. 18 19The process executes the following access checks: 20 21- Ensure the user is still present in LDAP. 22- If the LDAP server is Active Directory, ensure the user is active (not 23 blocked/disabled state). This check is performed only if 24 `active_directory: true` is set in the LDAP configuration. 25 26In Active Directory, a user is marked as disabled/blocked if the user 27account control attribute (`userAccountControl:1.2.840.113556.1.4.803`) 28has bit 2 set. 29 30<!-- vale gitlab.Spelling = NO --> 31 32For more information, see [Bitmask Searches in LDAP](https://ctovswild.com/2009/09/03/bitmask-searches-in-ldap/). 33 34<!-- vale gitlab.Spelling = YES --> 35 36The user is set to an `ldap_blocked` state in GitLab if the previous conditions 37fail. This means the user cannot sign in or push or pull code. 38 39The process also updates the following user information: 40 41- Email address 42- SSH public keys (if `sync_ssh_keys` is set) 43- Kerberos identity (if Kerberos is enabled) 44 45The LDAP sync process: 46 47- Updates existing users. 48- Creates new users on first sign in. 49 50### Adjust LDAP user sync schedule 51 52By default, GitLab runs a worker once per day at 01:30 a.m. server time to 53check and update GitLab users against LDAP. 54 55You can manually configure LDAP user sync times by setting the 56following configuration values, in cron format. If needed, you can 57use a [crontab generator](http://www.crontabgenerator.com). 58The example below shows how to set LDAP user 59sync to run once every 12 hours at the top of the hour. 60 61**Omnibus installations** 62 631. Edit `/etc/gitlab/gitlab.rb`: 64 65 ```ruby 66 gitlab_rails['ldap_sync_worker_cron'] = "0 */12 * * *" 67 ``` 68 691. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect. 70 71**Source installations** 72 731. Edit `config/gitlab.yaml`: 74 75 ```yaml 76 cron_jobs: 77 ldap_sync_worker_cron: 78 "0 */12 * * *" 79 ``` 80 811. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. 82 83## Group sync 84 85If your LDAP supports the `memberof` property, when the user signs in for the 86first time GitLab triggers a sync for groups the user should be a member of. 87That way they don't have to wait for the hourly sync to be granted 88access to their groups and projects. 89 90A group sync process runs every hour on the hour, and `group_base` must be set 91in LDAP configuration for LDAP synchronizations based on group CN to work. This allows 92GitLab group membership to be automatically updated based on LDAP group members. 93 94The `group_base` configuration should be a base LDAP 'container', such as an 95'organization' or 'organizational unit', that contains LDAP groups that should 96be available to GitLab. For example, `group_base` could be 97`ou=groups,dc=example,dc=com`. In the configuration file it looks like the 98following. 99 100**Omnibus configuration** 101 1021. Edit `/etc/gitlab/gitlab.rb`: 103 104 ```ruby 105 gitlab_rails['ldap_servers'] = { 106 'main' => { 107 # snip... 108 'group_base' => 'ou=groups,dc=example,dc=com', 109 } 110 } 111 ``` 112 1131. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure). 114 115**Source configuration** 116 1171. Edit `/home/git/gitlab/config/gitlab.yml`: 118 119 ```yaml 120 production: 121 ldap: 122 servers: 123 main: 124 # snip... 125 group_base: ou=groups,dc=example,dc=com 126 ``` 127 1281. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. 129 130To take advantage of group sync, group Owners or users with the [Maintainer role](../../../user/permissions.md) must 131[create one or more LDAP group links](#add-group-links). 132 133### Add group links 134 135For information on adding group links by using CNs and filters, refer to the 136[GitLab groups documentation](../../../user/group/index.md#manage-group-memberships-via-ldap). 137 138### Administrator sync 139 140As an extension of group sync, you can automatically manage your global GitLab 141administrators. Specify a group CN for `admin_group` and all members of the 142LDAP group are given administrator privileges. The configuration looks 143like the following. 144 145NOTE: 146Administrators are not synced unless `group_base` is also 147specified alongside `admin_group`. Also, only specify the CN of the `admin_group`, 148as opposed to the full DN. 149Additionally, if an LDAP user has an `admin` role, but is not a member of the `admin_group` 150group, GitLab revokes their `admin` role when syncing. 151 152**Omnibus configuration** 153 1541. Edit `/etc/gitlab/gitlab.rb`: 155 156 ```ruby 157 gitlab_rails['ldap_servers'] = { 158 'main' => { 159 # snip... 160 'group_base' => 'ou=groups,dc=example,dc=com', 161 'admin_group' => 'my_admin_group', 162 } 163 } 164 ``` 165 1661. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure). 167 168**Source configuration** 169 1701. Edit `/home/git/gitlab/config/gitlab.yml`: 171 172 ```yaml 173 production: 174 ldap: 175 servers: 176 main: 177 # snip... 178 group_base: ou=groups,dc=example,dc=com 179 admin_group: my_admin_group 180 ``` 181 1821. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. 183 184### Global group memberships lock 185 186> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1793) in GitLab 12.0. 187 188"Lock memberships to LDAP synchronization" setting allows instance administrators 189to lock down user abilities to invite new members to a group. 190 191When enabled, the following applies: 192 193- Only administrator can manage memberships of any group including access levels. 194- Users are not allowed to share project with other groups or invite members to 195 a project created in a group. 196 197To enable it, you must: 198 1991. [Configure LDAP](index.md#configure-ldap). 2001. On the top bar, select **Menu > Admin**. 2011. On the left sidebar, select **Settings > General**. 2021. Expand the **Visibility and access controls** section. 2031. Ensure the **Lock memberships to LDAP synchronization** checkbox is selected. 204 205### Adjust LDAP group sync schedule 206 207By default, GitLab runs a group sync process every hour, on the hour. 208The values shown are in cron format. If needed, you can use a 209[Crontab Generator](http://www.crontabgenerator.com). 210 211WARNING: 212Do not start the sync process too frequently as this 213could lead to multiple syncs running concurrently. This concern is primarily 214for installations with a large number of LDAP users. Review the 215[LDAP group sync benchmark metrics](#benchmarks) to see how 216your installation compares before proceeding. 217 218You can manually configure LDAP group sync times by setting the 219following configuration values. The example below shows how to set group 220sync to run once every two hours at the top of the hour. 221 222**Omnibus installations** 223 2241. Edit `/etc/gitlab/gitlab.rb`: 225 226 ```ruby 227 gitlab_rails['ldap_group_sync_worker_cron'] = "0 */2 * * * *" 228 ``` 229 2301. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect. 231 232**Source installations** 233 2341. Edit `config/gitlab.yaml`: 235 236 ```yaml 237 cron_jobs: 238 ldap_group_sync_worker_cron: 239 "*/30 * * * *" 240 ``` 241 2421. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. 243 244### External groups 245 246Using the `external_groups` setting allows you to mark all users belonging 247to these groups as [external users](../../../user/permissions.md#external-users). 248Group membership is checked periodically through the `LdapGroupSync` background 249task. 250 251**Omnibus configuration** 252 2531. Edit `/etc/gitlab/gitlab.rb`: 254 255 ```ruby 256 gitlab_rails['ldap_servers'] = { 257 'main' => { 258 # snip... 259 'external_groups' => ['interns', 'contractors'], 260 } 261 } 262 ``` 263 2641. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure). 265 266**Source configuration** 267 2681. Edit `config/gitlab.yaml`: 269 270 ```yaml 271 production: 272 ldap: 273 servers: 274 main: 275 # snip... 276 external_groups: ['interns', 'contractors'] 277 ``` 278 2791. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect. 280 281### Group sync technical details 282 283This section outlines what LDAP queries are executed and what behavior you 284can expect from group sync. 285 286Group member access are downgraded from a higher level if their LDAP group 287membership changes. For example, if a user the Owner role in a group and the 288next group sync reveals they should only have the Developer role, their 289access is adjusted accordingly. The only exception is if the user is the 290last owner in a group. Groups need at least one owner to fulfill 291administrative duties. 292 293#### Supported LDAP group types/attributes 294 295GitLab supports LDAP groups that use member attributes: 296 297- `member` 298- `submember` 299- `uniquemember` 300- `memberof` 301- `memberuid` 302 303This means group sync supports (at least) LDAP groups with the following object 304classes: 305 306- `groupOfNames` 307- `posixGroup` 308- `groupOfUniqueNames` 309 310Other object classes should work if members are defined as one of the 311mentioned attributes. 312 313Active Directory supports nested groups. Group sync recursively resolves 314membership if `active_directory: true` is set in the configuration file. 315 316##### Nested group memberships 317 318Nested group memberships are resolved only if the nested group 319is found in the configured `group_base`. For example, if GitLab sees a 320nested group with DN `cn=nested_group,ou=special_groups,dc=example,dc=com` but 321the configured `group_base` is `ou=groups,dc=example,dc=com`, `cn=nested_group` 322is ignored. 323 324#### Queries 325 326- Each LDAP group is queried a maximum of one time with base `group_base` and 327 filter `(cn=<cn_from_group_link>)`. 328- If the LDAP group has the `memberuid` attribute, GitLab executes another 329 LDAP query per member to obtain each user's full DN. These queries are 330 executed with base `base`, scope 'base object', and a filter depending on 331 whether `user_filter` is set. Filter may be `(uid=<uid_from_group>)` or a 332 joining of `user_filter`. 333 334#### Benchmarks 335 336Group sync was written to be as performant as possible. Data is cached, database 337queries are optimized, and LDAP queries are minimized. The last benchmark run 338revealed the following metrics: 339 340For 20,000 LDAP users, 11,000 LDAP groups, and 1,000 GitLab groups with 10 341LDAP group links each: 342 343- Initial sync (no existing members assigned in GitLab) took 1.8 hours 344- Subsequent syncs (checking membership, no writes) took 15 minutes 345 346These metrics are meant to provide a baseline and performance may vary based on 347any number of factors. This benchmark was extreme and most instances don't 348have near this many users or groups. Disk speed, database performance, 349network and LDAP server response time affects these metrics. 350