GitLab LDAP and Active Directory group sync

Map Active Directory or LDAP groups to GitLab roles in Premium, plan sync timing for large directories, and verify access before you rely on it for every team.

On this page

How GitLab LDAP group sync decides who gets which role

A self-managed GitLab instance has to follow the directory for two things: who can sign in and which group memberships and privileged roles those users receive. GitLab Self-Managed supports LDAP as an authentication method, and the group-based part of that setup is controlled through LDAP group settings, namely group_base, admin_group and audit_group. Those settings decide which directory groups GitLab reads and which of them grant administrator or auditor status. Group-driven role mapping for LDAP sits in the Premium tier, which the GitLab pricing page lists at 29 US dollars per user per month billed annually. Confirm the current price and billing terms with GitLab before budgeting, because your quote will depend on your user count and contract.

Before you configure anything, decide which system owns each decision. LDAP answers the question of who exists and which groups they belong to, so an LDAP directory such as Active Directory is the source for those attributes. If you also run SAML single sign-on, GitLab can take role claims from the identity provider instead, and running both methods for the same users creates two places where privilege can change. Document one owner for administrator and auditor status, and check how that owner interacts with SCIM provisioning if you plan to use it. Those choices shape the rest of the work more than the individual settings do.

This page covers LDAP group mapping only. SAML attribute mapping, SCIM provisioning, enforced two-factor authentication and the handling of users blocked after directory outages are covered on sibling pages, so treat those topics as separate design decisions. Within LDAP group mapping, ask your directory team to confirm the exact distinguished names of the groups you plan to use, who can change their membership, and how nested groups are represented. Those answers determine whether a group change in the directory produces the expected GitLab role the next time the sync runs.

What you need in place before you touch gitlab.rb

LDAP group sync fails quietly when any one of these foundations is missing, so confirm each before editing configuration. The cards cover the GitLab version and license, the directory access, the group design, the lifecycle of the domain controllers, the TLS trust and the people who can make the change.

A supported GitLab version

Confirm your instance runs on the current minor line or one of the two before it, as set out in the maintenance policy. Bug fixes are backported only to the current stable release, so a version outside that window may lack directory fixes you need. Check whether your next move crosses a required upgrade stop before you change LDAP settings, because the stops are a separate project.

A Premium license

LDAP group sync that maps directory groups to GitLab group roles is a Premium capability, so Free installations cannot use it. Confirm the license covers the full user count you plan to sync, since directory growth affects seat counts. Ask your GitLab account team or reseller to confirm the current Premium terms for your instance type.

Read-only directory bind account

GitLab needs a service account that can bind to the directory and read users and groups, and nothing more. Give it read-only rights scoped to the search bases GitLab will query, and store its password in a managed secret store rather than in plain text in gitlab.rb. Ask the directory team to confirm that password expiry and account lockout policies will not silently break the bind.

Documented directory group structure

Write down how groups are built before you pick values for group_base and the admin and audit group settings. Record whether groups are nested, which object class they use (for example, groupOfNames or group), and whether membership is stored in the member attribute or derived from the user's memberOf attribute. Mismatches here are the most common reason a sync returns no members.

Domain controller lifecycle check

If Active Directory is the source, confirm the domain controllers run a Windows Server release still in support. Windows Server 2022 mainstream support ended October 14, 2026, and extended support ends October 15, 2031, so plan any upgrade on that timeline. Ask your Windows team which domain controllers serve LDAP queries, because GitLab will bind to whichever server you name.

TLS trust and an administrator

LDAP traffic carrying bind credentials should use TLS, so confirm the directory certificate chain is trusted by the GitLab host and export the root CA you need. Also confirm that one administrator can edit gitlab.rb, run gitlab-ctl reconfigure and read the logs, and that a second person can cover that role. A change that cannot be applied or rolled back on a weekday is a risk on its own.

Configuration sequence for LDAP group mapping

This sequence takes an LDAP or Active Directory group structure from a directory review to verified GitLab role changes, with a check at each step so a misconfigured group filter is caught before it reaches users.

  1. Confirm the directory and bind account

    The directory administrator confirms the LDAP host, port, base DN and the service account GitLab will use to query the directory, and confirms that the account has read access to the user and group objects in the search scope. Record the exact distinguished names of the admin and audit groups as they appear in the directory, because GitLab matches them as written. Test the bind from the GitLab host with a standard LDAP query tool before touching GitLab. You are done when the query returns the expected test user and the expected group members from the GitLab server itself, not from a workstation.

  2. Enable TLS for the LDAP connection

    In the LDAP server block of gitlab.rb, the GitLab administrator sets the encryption and verification options so that bind credentials and directory data travel over an encrypted channel, and points GitLab at the certificate authority that signed the domain controller certificate. Confirm the exact key names for your version in the GitLab authentication documentation before editing the file, because these settings are version-sensitive. You are done when a test connection from the GitLab host succeeds with certificate verification enabled, and a failed verification (for example, against the wrong host name) is rejected rather than silently accepted.

  3. Define group base and role groups

    The administrator adds the group_base setting so GitLab knows where to search for groups, and sets admin_group and audit_group to the distinguished names confirmed in step one. Keep the group base narrow enough to limit query time but broad enough to contain both role groups. Use the same key names the authentication documentation lists for your GitLab version. You are done when the configuration file parses without errors and the values match the directory exactly, checked by comparing each string against the output of the directory query.

  4. Run reconfigure and check the logs

    The GitLab administrator runs the reconfigure command on the instance, which applies the gitlab.rb changes and restarts the affected services. Review the output for LDAP-related errors and confirm the services return to a healthy state. If the instance is part of a multi-node layout, apply the change on each node that serves web or Sidekiq traffic, following your documented procedure. You are done when reconfigure completes without error and the application logs show LDAP initialization without bind or certificate errors.

  5. Sign in with test accounts in each group

    Using three test accounts, one in the admin group, one in the audit group and one in neither, the administrator signs in through the LDAP login path. Confirm that the admin test account can open the Admin Area, that the audit test account has read-only auditor access, and that the third account has no elevated access. Use accounts created for this purpose and remove them after testing. You are done when each account lands with exactly the access its directory group implies, and any mismatch is traced back to a group distinguished name before going further.

  6. Verify role changes after the next sync

    Move a test user into the admin group in the directory, then wait for GitLab's next group sync to run and check the user's role in the Admin Area without signing in again. Repeat the check when removing the user from the group. Review the sync output or log entries for the user to confirm the change was detected. Confirm the actual sync timing for your version in the GitLab authentication documentation, because the interval is a configuration point and not a value to assume. You are done when both the grant and the removal appear in GitLab within the documented interval, and the log shows the change applied.

  7. Record the configuration and baseline

    The administrator saves the final gitlab.rb excerpt, the directory group names, the test results and the sync log lines in the change record, with the GitLab version and the date of the change. Store the bind account credentials in your approved secrets store rather than in the configuration file where possible, and document who owns the directory group membership. Confirm the stored procedure matches the version currently running. You are done when a second administrator can reproduce the checks from the record alone.

How sync timing and directory size change the rollout plan

Group membership changes reach GitLab on the sync schedule, not the moment someone is removed from an Active Directory group. The topic's documented timing is hourly, so a user removed from a mapped group can keep that role until the next pass. For admin_group and audit_group, that window matters most. Before go-live, confirm the sync interval in your configuration, document the maximum delay you accept for privileged roles, and decide how deprovisioning and sign-in blocking handle the gap. Then tell administrators that a removal in Active Directory is not an instant revocation in GitLab.

Directory size drives the cost of the first sync and the load it places on your domain. The first pass has to read every user under group_base and resolve every mapped group, so the work grows with the number of users in scope, the number of mapped groups, and how deeply groups nest inside each other. Nested groups require the sync to follow more membership links, which adds directory queries. Ask your directory team how many queries a sync generates, which service account runs them, and whether the domain controllers you point GitLab at can absorb that load alongside normal traffic. Measure the first full pass in a test environment before you schedule production.

A large directory should start with a narrow group_base, such as one organizational unit holding a small set of pilot groups. Verify that roles land correctly, that removals take effect on the next pass, and that the sync logs show no unexpected errors. Then widen the scope in steps. GitLab's reference architectures generally recommend a high availability strategy at 3,000 or more users, which applies to GitLab's own components. It also moves more weight onto the identity dependency. Active Directory replicates to every domain controller, so confirm that GitLab can fail over to another controller or LDAP endpoint, and that a directory outage is monitored and tested before it can lock out users.

Directory attributes and GitLab roles mapped side by side

This table pairs each directory object or attribute with the GitLab setting it feeds, who owns the value on each side, and the check to run before go-live. Read it as a checklist: confirm each attribute name against the current GitLab LDAP documentation and your directory schema, since names differ between Active Directory and other LDAP directories. The main takeaway is that most sync failures come from a value that exists in the directory but is owned by a different team than the one assuming it is correct.

Directory itemGitLab settingOwnerCheck to run
User login attributeGitLab username (login attribute in ldap configuration)Directory team sets the value, GitLab admins set the attribute nameSample three accounts and confirm the GitLab username matches the expected sign-in name
Group search base (distinguished name of the OU or container)group_baseDirectory team provides the distinguished name, GitLab admins enter itConfirm the search returns only the intended groups and no nested OUs with stale groups
Administrator group (group object)admin_groupIdentity owner approves membership, GitLab admins map the groupConfirm only named administrators are members and that a test admin receives admin rights after sync
Auditor group (group object)audit_groupCompliance or security owner approves membership, GitLab admins map the groupConfirm auditors gain read-only oversight and no write permissions after sync
Account state (disabled flag or expiry on user object)GitLab account blocking after syncDirectory team controls the account state, GitLab reflects it at the next syncDisable a test account in the directory and confirm it is blocked in GitLab within the expected sync window
Group membership (member or memberOf attributes)Group role mapping in GitLab groupsDirectory team owns membership, GitLab group owners own the role assignedConfirm each mapped group gives the intended access level on a sample project

Security settings for directory-backed admin roles

A directory group change can grant GitLab administrator rights to the wrong account within one sync cycle. The cards below set out the controls that keep admin_group and audit_group membership narrow, traceable and reversible, so a directory mistake does not become a platform compromise.

Keep the bind account read-only

The bind account is the identity GitLab uses to query the directory, so its permissions define how much an attacker could read or change if the credential leaks. Grant it read access to the users and groups GitLab needs, scoped to the relevant organizational unit, and nothing that allows writes. Ask your directory team to confirm the account cannot modify group membership, and rotate its password on a documented schedule.

Require TLS for directory traffic

LDAP credentials and directory results travel over the network between GitLab and your domain controllers. Configure GitLab to connect over LDAPS or StartTLS, and verify the certificate chain against your internal certificate authority rather than disabling verification to get a connection working. Check this setting after every GitLab upgrade, since a misconfigured connection can silently fail sync and leave roles unchanged.

Keep admin_group small and reviewed

Every member of the directory group named in admin_group becomes a GitLab administrator at the next sync. Limit that group to named platform owners, and make membership changes go through the same approval process as production access. Export the current membership on a regular schedule and compare it with the approved list, because a single inherited nested group can add far more people than anyone intended.

Separate audit access from admin rights

Auditor access lets people review projects, settings and audit events without changing them, and it should not be a stepping stone to administration. Map audit_group to a directory group owned by compliance or security, distinct from the administrator group. Confirm in a test instance that a user in audit_group cannot reach administrative settings before you rely on the mapping.

Log sign-in and role changes

Without a record of role changes, a wrongly granted administrator can act before anyone notices. Forward GitLab authentication and audit events to your central log platform, and alert on any new administrator or auditor status. Also keep directory-side change logs for the groups GitLab reads, so you can match a directory edit to the GitLab role change that followed it.

Apply hardening in stages

GitLab's hardening guidance covers application settings, configuration files such as gitlab.rb, and the operating system, and the documentation states that it is a work in progress to be rolled out gradually. Start with the controls that protect directory-backed access, such as the LDAP settings and administrator restrictions, then test each change in a staging instance before production. Record which recommendations you adopted, deferred or rejected, and why.

Why group roles do not match the directory

This table lists the failures teams most often see when LDAP or Active Directory group mappings do not produce the expected GitLab roles. Each row gives the likely cause, how to confirm it on the instance, and the fix. Work through the rows in order, since a bind or TLS failure can look like a missing role.

FailureLikely causeHow to confirmFix
User has the wrong role after a group changeSync runs on a timer, so a group change made in the directory is not reflected in GitLab until the next sync cycleCompare the user's directory group membership with their GitLab role and note the time of the change against the last sync in the logsWait for the next sync or trigger a single-user sync, then confirm the mapping in the group settings and document the expected lag for admins
Admin rights not grantedadmin_group value does not match the group's distinguished name, or the group sits outside the configured search baseSearch the directory for the admin group DN and compare it character by character with the value in gitlab.rb, then check the search base covers that OUCorrect the admin_group DN or widen group_base, reconfigure, and reconcile the user's status
Users locked out after a directory outage or rate limitGitLab marks accounts as blocked when the directory is unreachable or refuses queriesCheck whether affected users show a blocked state and whether sync errors cluster around the outage windowClear the state and resync affected users. The full procedure is covered in the sibling topic on blocked LDAP users
TLS handshake errorsCertificate chain is not trusted by GitLab, the hostname does not match, or the port and encryption mode are wrongReview production.log and the LDAP logs for certificate or handshake messages and test the chain from the GitLab host with opensslInstall the internal CA chain where GitLab trusts it, match the hostname in the certificate, and confirm the port and encryption setting
Bind failure from service accountWrong bind DN, expired or changed password, or an account locked or lacking read access to the directoryTest the bind from the GitLab host with the same DN and password using an LDAP client and check for invalid credential errorsCorrect the bind DN or password, rotate the account through your secrets process, and grant read access to the required OUs
Nested groups not resolvedMembership is inherited through nested groups, but the configured lookup does not follow nesting or the nested group is outside the search basePick a user who gets the role through a nested group and check whether that group appears in the membership results from the directoryConfirm the lookup method in the configuration supports nested membership in your directory and verify the nested group is within scope
Role applied in wrong direction after an editMultiple mappings overlap, so a user in both groups receives an unexpected roleList every mapped group for the affected user and compare the roles they hold in GitLabRemove overlapping mappings and document a precedence rule for admins and auditors before enabling sync

Questions buyers ask before they hire help with LDAP group sync

What does LDAP group sync work cost, and what drives the price?

Cost depends on how much of the directory and GitLab configuration is in scope, so the written scope is what sets the quote. The main drivers are the number of directory groups you map to GitLab group roles, how messy the directory structure is (nested groups, duplicate names, service accounts), the TLS and network work needed to reach the directory from GitLab, and how much testing you want on a non-production instance before the change reaches users. Premium is a recurring per-user subscription paid to GitLab, separate from any services fee. Ask a partner to price the discovery, configuration, testing, cutover and handover as separate line items, and to state which parts are one-time and which are ongoing support.

Can our own team set up LDAP group sync without a partner?

Yes, if you have people who understand both the directory and GitLab administration and you have a test instance to work on first. The work involves reading directory group structure, setting group_base and admin_group values in gitlab.rb, checking how group membership maps to GitLab roles, and verifying sign-in for real accounts. Teams without that combination often use a partner for the design and verification steps, then keep the configuration in their own hands. Either way, test against a copy of your directory data or a limited set of accounts before enabling sync for everyone.

How long does LDAP group sync take to plan and deploy?

Duration depends on the size of the directory, how many groups need mapping, and whether the environment is a single self-managed instance or a larger deployment with several GitLab nodes. Discovery takes longer when group ownership is unclear, because someone must confirm which groups are still used. Testing and the change window are usually the longest parts for large directories, since sync runs on a schedule and results need time to observe. Ask a partner for a timeline built from your group inventory and environment, and ask which milestones depend on your team's availability.

What do we need to provide before the work starts?

Plan to provide directory administrator access, or a read-only service account with the rights needed to query groups and users, plus the LDAP host names, port and TLS certificate details. You also need a group inventory: a list of the directory groups that should grant GitLab administrator, auditor or group roles, with the owner who approves each one. Confirm a change window with your GitLab and directory owners, and confirm who will receive alerts if sign-in fails after the change. Missing group ownership is the most common reason discovery runs long.

Do we need GitLab Premium for LDAP group sync?

Yes. Group sync from LDAP groups to GitLab group roles is a Premium capability, so the instance must run Premium or Ultimate. GitLab Premium is listed at 29 US dollars per user per month billed annually on the GitLab pricing page, and that figure is a list price that varies with your contract. Confirm the current subscription terms with GitLab or your reseller before budgeting, and count the users who will be provisioned, not only the active users today.

What should we ask a partner to include in a fixed-scope quote?

Ask for a written scope that names the directory and GitLab versions in use, the number of groups to map, the GitLab roles covered (administrator, auditor and group membership), and the TLS and network changes required. Request the testing approach, including which accounts will be tested and where, the cutover steps and rollback plan, and the handover documents. Also ask what is excluded, such as SCIM provisioning or SAML setup, and how changes to scope after signature are priced and approved. Ask for named deliverables and acceptance criteria so both sides can tell when the work is finished.

What typically breaks during LDAP group sync, and how do we check for it?

Common problems include a wrong group_base that matches no groups, admin_group values that do not match the directory's group name or distinguished name format, and nested group membership that the sync does not resolve the way you expect. TLS certificate mismatches and blocked network paths also cause sync failures. Verify the sync by checking a small set of test accounts after each scheduled run, reviewing the GitLab logs for LDAP errors, and confirming that roles change only for the groups you approved. Plan monitoring for directory outages so a temporary failure does not lock users out.

How DeployOpen works on this

DeployOpen plans and implements GitLab LDAP and Active Directory group sync inside your own infrastructure, starting from a written map of which directory groups should grant which GitLab roles. The work is fixed-scope, so the mapping, test plan and handover are agreed before any configuration changes reach a production instance.

How we scope

  • Inventory the AD or LDAP groups that must map to GitLab group roles, plus the group_base, admin_group and audit_group decisions.
  • Confirm your GitLab edition, since group sync depends on Premium features, and record which instance settings live in gitlab.rb.
  • Agree in writing which directory sizes, nested group rules and sync timing are in scope, and what is excluded.

How we build

  • Configure LDAP settings in a staging instance, then test group-to-role mappings with a set of named pilot accounts before production.
  • Verify how the sync behaves with nested groups, disabled accounts and large directories, and document the query load it places on domain controllers.
  • Check that a directory outage or a blocked account does not lock out administrators, using a recorded test plan.

How we hand over

  • Deliver a written mapping table that ties each directory group to its GitLab role, owner and approval path.
  • Provide runbooks for resyncing a single user, reviewing blocked LDAP states and changing a group mapping under change control.
  • Walk your administrators and identity team through the configuration, test results and rollback steps before sign-off.

How we support

  • Offer ongoing support, upgrade testing across GitLab releases and periodic re-checks of mappings as directory structures change, as a retainer.
  • Review sync logs and directory changes with your team when group membership or role behavior looks wrong.
  • Ask any provider to confirm which directory, GitLab version and identity component each support task covers before work starts.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.