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