GitLab SCIM user provisioning with Okta or Entra ID

Automate GitLab account creation, group membership and blocking from Okta or Entra ID with SCIM, and plan how deprovisioned users return through their SAML identity. The page covers prerequisites, setup order, attribute mapping, security and failure points.

On this page

How GitLab SCIM provisioning moves accounts from your identity provider

SCIM provisioning automates account creation and blocking in self-managed GitLab, so joiners, leavers and group changes in Okta or Entra ID reach GitLab without an administrator editing users by hand. It is a separate step from SAML sign-in: SAML decides how a person proves who they are when they open GitLab, while SCIM decides whether an account exists, which groups it belongs to and whether it stays active. An organization can run one without the other, but the two are usually designed together so that a disabled identity in the directory cannot keep a working GitLab session. GitLab's authentication documentation lists SCIM user provisioning among the supported methods for self-managed instances, and the GitLab pricing page is the place to confirm which tier includes it. This topic is scoped to Premium, so confirm on the GitLab pricing page that your planned tier covers SCIM before you commit to a design. The identity provider side is equally important: the Okta and Entra ID provisioning settings, the SCIM endpoint and the token handling should be taken from the current GitLab and vendor documentation during the build, because field names and endpoint details change between releases. Before build starts, decide which directory groups should drive GitLab group membership, who owns the SCIM token and how it is rotated, and what your leaver process expects to happen to repositories and issues owned by a blocked user. Also agree how the provisioning team will test a joiner, a leaver and a group change in a non-production instance. Those decisions shape most of the work that follows.

What must be in place before you configure GitLab SCIM provisioning

SCIM provisioning only works on top of a foundation you have already built: a supported self-managed GitLab release, the right tier, and a working SAML sign-in. Settle these items before you touch the identity provider, because each one changes what the provisioning app can create, update and block.

Supported self-managed GitLab release

Confirm that your instance runs a release still covered by GitLab's maintenance policy, which currently maintains 19.5, 19.4 and 19.3. Security fixes are backported further than bug fixes, so a release outside that window is a risk to close before integration work starts. Also check that your upgrade path has passed every required upgrade stop, since an instance that skipped one cannot be configured as planned. Ask your team to record the exact version in the change ticket.

GitLab tier that includes SCIM

SCIM user provisioning is not part of the Free tier. Check the GitLab pricing page for the current tier that lists SCIM for self-managed installations before you buy or budget, and confirm the per-user rate and billing terms in the written quote. Licensing is recurring, so account for seat growth as the identity provider adds users.

Working SAML sign-in path

SCIM links provisioned accounts to existing SAML identities, so SAML sign-in must already work for the same Okta or Entra ID application. Verify that a test user can sign in through SAML, that the NameID value matches the identifier you plan to send from SCIM, and that the instance-wide SAML settings in gitlab.rb are in place. Provisioning on top of a broken SAML path produces accounts nobody can use.

Group structure decided in advance

Decide which identity provider groups map to which GitLab groups and roles before you enable group sync. Changing the mapping later can move users between groups and alter their access to projects. Document the group names, the owning team for each, and whether any group is meant to confer administrator or auditor status, which needs its own review.

Named admin owner and provisioning service account

Assign a named administrator who owns the SCIM configuration, the generated token and the rotation schedule. Create a dedicated service account for the provisioning app rather than reusing a personal login, so that offboarding the owner does not break provisioning. Record who can view or regenerate the token, since that token can create and block accounts.

HTTPS reachability and license level

Confirm that the identity provider can reach the GitLab SCIM endpoint over HTTPS through your firewalls, reverse proxy and any allow lists, and test that path from the provider side. Also confirm with your Okta or Entra ID account team which license level includes provisioning features in your tenant, because the feature may not be available on every plan.

How to configure SCIM provisioning in order, with a check at each step

This sequence connects Okta or Entra ID to self-managed GitLab so that accounts are created and blocked from the identity provider, with a verification point before each expansion. Each step builds on the one before it, so a failure is caught while only a single test user is affected.

  1. Confirm SAML sign-in works for a test user

    Before any provisioning is configured, the identity team and a GitLab administrator confirm that a pilot user can sign in to self-managed GitLab through SAML with the intended identity provider. SCIM depends on the same identity link, so this step establishes the baseline. Check the username, email and group claims that GitLab receives on the first sign-in and record them. The step is done when the test user lands in the expected GitLab account without creating a duplicate, and the identity provider's sign-in logs show a successful assertion for that user.

  2. Create the SCIM token in GitLab

    A GitLab administrator generates the SCIM token in the location the GitLab authentication documentation specifies for your installation, and stores it in the identity provider's secret field only. Confirm the scope of the token matches the group or instance level you intend to provision. Record which administrator created the token and where it is stored, because the token acts as a credential that can create and block accounts. The step is complete when the token is saved in the secrets vault or provisioning app and the administrator has confirmed the token is not visible in any shared document or ticket.

  3. Create the provisioning app in Okta or Entra ID

    The identity team creates or opens the GitLab application in Okta or Entra ID and enables provisioning, using the SAML app that already handles sign-in. Okta and Entra ID each have their own menus for enabling SCIM, so confirm the current steps in the vendor's documentation for your tenant. Keep the provisioning scope to the users and groups who should use GitLab. The step is done when the provisioning settings page is available in the identity provider and no changes are pushed yet, which you can verify by checking that the provisioning log is empty.

  4. Enter the GitLab SCIM endpoint and token

    Enter the SCIM endpoint URL for your GitLab instance and the token from step two into the provisioning settings, then use the identity provider's connection test. Confirm the endpoint uses the hostname your users reach and that the certificate chain is trusted by the identity provider's network path, especially for air-gapped or internal certificate authorities. The step is complete when the connection test reports success and the provisioning log shows a successful request without any authentication errors.

  5. Map user attributes and assign a pilot group

    Review the default attribute mappings between the identity provider profile and GitLab, and confirm that the username, primary email and display name fields match the values from the baseline sign-in in step one. Change only mappings that the GitLab SCIM documentation supports, and document each change. Then assign one small pilot group that contains the test user and a second test user who should not have access. The step is done when the mapping preview for the pilot users shows the expected username and email for each account.

  6. Run a single-user push and verify the identity link

    Trigger a single-user push from the identity provider for the test user, then confirm in GitLab that the account exists with the expected username and email, and that the account is linked to the SAML identity from step one rather than a new account. Next, unassign the second test user, or deliberately exclude them from the pilot group, and confirm that the next sync blocks their GitLab account. Record the sync result for both users. The step is complete when the first user is active with one identity and the excluded user is blocked, which shows deprovisioning works end to end.

  7. Enable group sync and scale to the full population

    Once the pilot passes, enable group sync if your design uses groups to control GitLab roles, and confirm which group attributes map to GitLab group membership. Expand the assignment in stages, adding one business unit at a time, and check the provisioning log and GitLab user list after each stage. Confirm that deprovisioned users keep their SAML identity so that reactivation returns them to the same account. Ask your GitLab administrator and identity team to agree the staging plan and the rollback steps before expanding. The step is done when the full assignment is live and each stage has a recorded check.

Which identity fields and roles map to GitLab user and group attributes

This table compares each identity provider attribute with the GitLab field it populates, and whether provisioning or sign-in controls it. Read it before you build the Okta or Entra ID attribute mappings, then confirm every row against the current GitLab SCIM documentation for your version, because field handling changes between releases.

Identity attributeGitLab fieldRole or behaviorValidation note
User name (userName)UsernameProvisioning sets the handle users sign in with and that appears in project URLsCreate a test user and confirm the username format GitLab accepts without collisions with existing accounts
Email (primary email)Primary email, used as the matching keyProvisioning matches an incoming user to an existing account by email, so a mismatch creates a duplicateCheck for existing local accounts with the same email before the first sync
Display name (formatted name)NameShown on commits, issues and merge requests; updated on later provisioning cyclesConfirm which attribute your provider sends as the name and whether it includes characters GitLab truncates or rejects
Active statusActive or blocked stateProvisioning deactivation blocks the account; reactivation restores it when the user is assigned againDeprovision a test user and confirm the account is blocked, its tokens are revoked and its projects keep their history
Group membershipGitLab group membership and access levelProvisioning adds or removes members of groups that the SCIM group sync maps; access levels are set by the mapping, not by the identity provider aloneVerify that group names match the mapping and that removing a user from the group removes the GitLab membership
SAML NameID or external identity linkSAML identity linked to the user accountSign-in-driven: the NameID must stay stable so a deprovisioned user keeps the link and can be reactivated without a duplicateConfirm the NameID format and value in your provider match the value GitLab stores before you change any SCIM attribute
Administrator, auditor and external statusAdmin, auditor and external flagsSign-in-driven: controlled through SAML group attributes and gitlab.rb settings, covered on the sibling SAML admin, auditor and external groups pageDo not assume SCIM sets these flags; confirm which settings control them in your version

Security controls to set for the SCIM token and provisioning app

The SCIM token and the identity provider app together decide who can create, change and block GitLab accounts. Treat both as privileged integrations with their own owners, scope, logs and review cycle, separate from ordinary user administration.

Scope and store the SCIM token

The SCIM token lets the identity provider create and deactivate GitLab users, so it is a credential with broad reach. Store it in the identity provider's secret field only, keep it out of tickets, chat and configuration repositories, and confirm which GitLab group or instance scope the token is generated for. Ask who can view or regenerate it in the identity provider before the app goes live.

Rotate after changes or exposure

Rotate the SCIM token when someone with access to the app leaves the team, when a token may have been pasted into a shared location, or when a vendor support engagement ends. Confirm the rotation steps in the GitLab documentation, then update the identity provider and run a test sync so provisioning does not silently fail. Record each rotation with a date and a reason.

Limit the app to required groups

Assign only the groups that should exist in GitLab to the provisioning app, instead of the whole directory. A broad assignment pulls in service accounts, contractors and shared mailboxes that do not belong in the GitLab user base. Review the assignment list each quarter and remove groups that no longer map to a GitLab group or role.

Review provisioning logs on both sides

Provisioning events appear in the identity provider's system log and in GitLab's audit records, and they do not always match. Compare creations, updates and deactivations across both sources on a set schedule, and confirm that someone outside the administrators reviews them. Ask GitLab support or your own log pipeline what retention applies to each source before you rely on it as evidence.

Least privilege for app administrators

The people who configure the provisioning app and mappings should not also be GitLab instance administrators by default. Separate the identity administrator role from the GitLab administrator role, require a second approver for changes to high-privilege group mappings, and keep the number of named app administrators small. Confirm which role names your identity provider uses for this work.

Control edits to attribute mappings

Attribute mappings decide which directory fields become GitLab usernames, emails and group memberships, so a small edit can change access for many users. Route mapping changes through a documented change request, test them in a non-production GitLab instance or with a test user, and keep a copy of the previous mapping for rollback. Check that a leaver is deprovisioned in the identity provider as well as blocked in GitLab, and include the provisioning app itself in your periodic access review.

Why deprovisioned users keep their SAML identity for reactivation

When SCIM deprovisions a user, GitLab blocks the account rather than deleting it, and the external identity link to the SAML provider stays in place. That link is what lets a later reassignment in Okta or Entra ID reactivate the same GitLab account instead of creating a second one with the same email address. The practical consequence is that the identity link, not the email address, is the thing to protect. Before go-live, confirm with the GitLab authentication documentation which attribute the SAML and SCIM configuration uses as the unique identifier, and confirm that the identity provider sends the same value on deactivation and reassignment. If the value changes between systems, you should expect duplicate accounts or accounts that cannot be reactivated.

Blocking has consequences for work the user left behind. Issues, merge requests, comments and commits remain attributed to the blocked account, so reviewers, auditors and maintainers may see a name that cannot sign in. Plan an ownership step as part of offboarding: reassign open issues and merge requests to a current maintainer, and decide whether the team needs to keep the blocked account's historical attribution visible. Commit authorship is recorded in Git itself and is not changed by blocking, so your evidence process should not assume that blocking alters history. Confirm in the current GitLab documentation what happens to group and project memberships, personal access tokens and SSH keys when an account is blocked, because those settings determine whether a reactivated user regains access automatically.

Test this with a disposable account before you rely on it for production users. Assign the account to the GitLab application in your identity provider, confirm it is provisioned, unassign it, and check the blocked state in GitLab. Then reassign it and confirm the same user record returns, with no duplicate and with the expected group roles. Repeat the test after any change to the SAML or SCIM attribute mapping, and after each GitLab upgrade, because deprovisioning and reactivation behavior depends on settings you must verify in your own version. Record the results as evidence for your access review, and keep the test account and its steps in your runbook so the check can be repeated.

How Okta and Entra ID setups differ for GitLab provisioning

In Okta, the GitLab provisioning work starts in the Okta admin console, where your team adds GitLab as an application and enables provisioning for it. Access is controlled by assigning the application to users or groups, and those assignments are what GitLab receives through SCIM. Your team should decide early whether assignments flow from individual users, from groups, or from both, because that choice determines who gets an account when they are added to a group. Confirm the current app setup steps, token handling and supported provisioning actions in Okta's own documentation before you configure anything, since connector details change.

  • Application creation: Add the GitLab app from the Okta catalog or as a custom SAML and SCIM app, depending on what your Okta edition and your GitLab setup support. Confirm the exact path in current Okta documentation.
  • Assignment model: Assign the app to a pilot group first. Confirm whether group push or group membership sync is needed to create GitLab group memberships, not only user accounts.
  • Provisioning log: Review the Okta System Log and the provisioning activity for the app to see create, update and deactivate events. Record the event IDs your team will use for troubleshooting.
  • Attribute mapping: Check how Okta populates the username, email and name fields that GitLab matches on, and how the profile is mapped for deactivation.
  • Pre-pilot checks: Confirm that test users in the pilot group are created in GitLab, that a removed user is blocked, and that the SAML identity for that user is retained for reactivation.

Before the pilot, check the Okta tenant for assignment rules, group naming and any policies that could push changes to GitLab outside the pilot group.

Why GitLab SCIM provisioning fails and how to fix each cause

This table maps common SCIM provisioning symptoms to their likely causes and the first thing to check for each. Read it from the symptom the administrator sees in the identity provider or in GitLab, then work through the listed check before changing any configuration. Most failures trace to assignment scope, attribute matching, or the token and endpoint connection rather than to GitLab itself.

SymptomLikely causeFix and first check
Users not created after assignmentThe user or group is not assigned to the GitLab app, or provisioning is paused or not enabled in the identity providerConfirm the user appears on the app's Assignments tab, then open the provisioning log in Okta or Entra ID and check the event for that user before retrying
Accounts created without a SAML linkSCIM created the account, but the SAML identity's NameID does not match the SCIM identifier GitLab storesCompare the NameID format and the value sent by SAML with the SCIM externalId or userName mapping, and align the two before re-provisioning
Users not blocked after unassignmentUnassignment was not sent as a deactivation, or the user still has an active session or a second identity that keeps access openCheck the provisioning log for a deactivate action, confirm the user's state in GitLab, and review other sign-in methods such as LDAP or personal tokens
Group membership not matchingThe group name or group ID in the identity provider differs from the group path GitLab expects, or group push was not configuredVerify the group mapping and the exact group names in the identity provider, then check whether the group was pushed and whether the members list is complete
Duplicate accounts from an email mismatchThe identity provider sends a different email case, alias or primary address than the one already in GitLabCompare the email attribute on the existing GitLab account with the value the identity provider sends, normalize casing and aliases, and merge or remove duplicates under a documented process
Token rejected or expiredThe SCIM token was rotated, revoked, or generated without the scope the connector needs, or it has expiredGenerate a new token from the GitLab group or instance settings, update the identity provider's connection, and run a test connection before saving
Endpoint unreachable from the identity providerThe SCIM URL is wrong, the instance is behind a firewall or private network the provider cannot reach, or TLS trust is incompleteConfirm the SCIM endpoint URL from GitLab's documentation, test reachability from outside your network, and check the certificate chain for a self-managed hostname
Pilot group works but the full population failsAttributes such as names, usernames or emails contain characters, lengths or formats that the rest of the population does not shareExport the provisioning log for failed users, compare their attribute values with the pilot users, and correct the attribute mapping or source data before widening scope

What buyers and engineers ask before setting up GitLab SCIM provisioning

Does GitLab SCIM provisioning require a Premium license?

This page assumes SCIM provisioning is available in Premium, so confirm that against the current tier comparison before you buy. The GitLab pricing page lists Premium at 29 US dollars per user per month billed annually, while Ultimate is custom priced and Free costs nothing. Because Premium is priced per user, the license line grows with the number of people you provision, so count the accounts that will be created and blocked by SCIM, not only your current GitLab users. When you request a quote, ask for the seat count, the billing term and whether taxes are included.

What drives the effort of a GitLab SCIM setup?

Effort follows the shape of your identity estate more than the GitLab side of the work. The main drivers are:

  • The number of groups that must map to GitLab groups and the depth of nesting between them.
  • How much attribute mapping the identity provider needs to send, including username, email and any role or external status fields.
  • Whether SAML already works cleanly, since SCIM builds on the same identity links and a broken SAML setup adds a debugging step to every test.
  • The testing scope, meaning how many lifecycle cases you check (create, update, block, reactivate, group membership changes) and in how many environments.

Ask any provider to break its quote into these four drivers so you can see which ones the scope assumes.

Can our own team set up GitLab SCIM without a partner?

Yes, a team with administrator access to both the identity provider and the GitLab instance can configure SCIM in-house, and many do. The work is configuration, controlled testing and documentation, so the question is capacity and evidence rather than capability alone. Teams that have not run identity provisioning before often underestimate the testing and the change record. A partner can take on a fixed-scope piece, such as the mapping design, the test plan, the runbook or the upgrade retest, while your staff keep ownership of the identity provider and the instance. DeployOpen implements, integrates and documents self-hosted platforms inside your own infrastructure, and most engagements are fixed-scope with the scope agreed in writing before work starts.

How long does a GitLab SCIM pilot usually take?

A pilot's length depends on the factors that drive its scope, so no general duration applies to every organization. Time usually goes to agreeing the group mapping, waiting on tenant access and change approvals, and rerunning tests after fixes. A pilot is complete when the lifecycle cases pass in a test group: a user is created, an attribute change flows through, a block takes effect and a reactivation works. Ask any provider for the planned duration in the written scope, along with the dependencies that could move it, such as approval windows and the availability of a test population.

What does our side need to provide for SCIM provisioning?

The client side supplies access, people and decisions. Plan for the following before work starts:

  • Tenant administrator access in Okta or Microsoft Entra ID to create and configure the SCIM app.
  • GitLab administrator access to the self-managed instance, including the settings that control SCIM and SAML.
  • A test population of real but low-risk accounts, plus a test group in GitLab that can hold them.
  • A named approver for the change, and a window in which production changes can be made.

Without these, testing stalls. Confirm the exact settings and access levels against the GitLab authentication documentation for your version.

Does turning on SCIM change existing GitLab accounts?

It can. Once SCIM manages a user, the identity provider's view of that user drives account state, so an account that the directory later deactivates will be blocked in GitLab. Before enabling anything, export the current user list, compare usernames and email addresses with the identity provider, and identify accounts that exist in GitLab but not in the directory. Run the first sync against a test group only. The design goal is that a deprovisioned user keeps the SAML identity link, which allows reactivation later, so confirm that behavior in your own test before relying on it. Treat the first production sync as a controlled change with a rollback plan.

How should an upgrade affect our SCIM provisioning tests?

Each upgrade is a point where provisioning can break, so retest it at every required stop. Since GitLab 17.5, required upgrade stops fall at versions x.2, x.5, x.8 and x.11, such as 18.2, 18.5, 18.8, 18.11 and 19.2, according to the GitLab upgrade paths documentation. Rehearse the full path on a staging instance that mirrors production, and after each stop run the same lifecycle cases: create, update, block, reactivate and group membership. Also confirm that the identity provider's SCIM app still matches the GitLab endpoint and token. Keep the results as part of the change record for that upgrade.

How do we get a firm quote for GitLab SCIM work?

A quote follows from a written scope, and DeployOpen does not publish a price list. Ask for a scope that lists each deliverable, such as the mapping design, the configuration, the test cases, the runbook and any upgrade retest, along with the environments covered and the client responsibilities. Ask which costs are one-time, such as the setup and the pilot, and which recur, such as support or retesting after each upgrade. Also ask how a change in group count or identity provider complexity would alter the scope. Compare providers on the same written scope, not on headline figures.

How DeployOpen works on this

DeployOpen plans, implements, tests, documents and supports self-hosted GitLab inside your own infrastructure, including the identity provider connection that drives SCIM provisioning. Each engagement starts with a written scope that names the identity provider, GitLab edition, and the groups and user populations in play.

How we scope

  • Confirm the GitLab edition and that SCIM provisioning is available on your self-managed tier before work starts
  • Inventory the Okta or Entra ID groups, attribute mappings and user populations that GitLab must receive
  • Agree in writing how deprovisioning, blocking and reactivation should behave for your joiner and leaver process

How we build

  • Configure the SAML application and the SCIM connector in the identity provider, then map attributes to GitLab identities
  • Set up SCIM group sync and test membership changes with a pilot group of named test accounts before wider rollout
  • Test deprovisioning and reactivation end to end, including the SAML identity retained for users who return

How we hand over

  • Document the configuration, attribute mappings, group rules and the steps used to verify each provisioning path
  • Provide a runbook for common failures such as token expiry, rejected payloads and users stuck in a blocked state
  • Walk your administrators through the handover so they can review provisioning activity and make routine changes

How we support

  • Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts
  • Ongoing support, GitLab upgrades that keep the SCIM integration working, and continuous testing are available as a retainer
  • Ask any quote to itemize setup, testing, documentation and retainer components so you can compare them with your internal effort

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.