Enforce SAML for our company user's accounts on gitlab.com (GitLab Cloud)

How do we enforce SAML for every each of the company’s user accounts on gitlab.com (GitLab Cloud)?

History: We are in the process of migrating from the GitLab Onprem to the GitLab cloud offering. We are creating user accounts and setting up SAML. The issue with gitlab.com is that a user can use 2 different passwords to login. one with the regular url and one with the SSO url. How do we enforce users to always use the SSO url?


I’ve gone through this same migration :slight_smile:

Under the SAML settings for your namespace, there are a couple of checkboxes for enforcing SSO signon:
This is documented here if you want to read more…

Selecting these doesn’t stop a user from being able to log into gitlab.com through the ‘standard’ login pages, but if they try to access your namespace - they are required to have a valid SAML session. If they don’t have a current one, they will get bounced to the SSO portal when attempting to access resources under your namespace.

The second ‘enforce’ checkbox (Git activity) ensures that the user has a recent, active SAML/SSO session (through the web interface) before allowing git (https and/or ssh) activity.

There is (I can’t quite find the issue right now) plans to extend this enforcement to API requests, too.

Hope this helps!


@stingrayza thank you so much for your response. there is one more challenge we are currently facing right now bringing users on board. for gitlab onprem, we had the ability to add or remove users without having to involving them . for gitlab cloud, there is an email that goes out to each of the newly registered users. they have to click on the email to confirm their account. Also to enable saml, there are a few things only the user can do such as “authorize” saml. It would be nice if the admins had complete control of adding or removing/configuring users on gitlab cloud such as gitlab on prem. I am wondering how you guys created/migrated the users on gitlab cloud.

Yeah, provisioning users can be a bit of a pain on gitlab.com. There is some mitigation, though.

It helps to understand that (at least currently) the user database on gitlab is only linked to your corporate directory.

I can fully recommend enabling SCIM provisioning If possible with your directory provider. You may want to test it in a test namespace first (our first attempt provisioned every single user in our AD - 3500 of them, rather than the 30 we wanted at the time) - make sure you have it constrained to the membership of a limited group before enabling! I can also suggest adding a .companyname to the username created to ensure uniqueness.

Because of the public nature of gitlab.com, there is still a requirement to validate email, its something we’ve learned to live with.

Finally, there are further improvements in the pipeline - since the release of 14, scim provisioned users are tagged with ‘Enterprise’ which is nice. I’m sure additional enhancements are enroute, too.

It’s an exciting time, though not without its challenges! Feel free to hit me up further if you have any more questions.

1 Like

@stingrayza changing the username by appending a company name to it is a great idea to ensure it’s unique on gitlab.com. the reason i didn’t try changing the username is because it has to match it with one of the attributes such as samAccountName in the active directory or we may have to create an entirely new attribute just for this purpose in the active directory. I thought changing the attribute in the active directory may impact other applications that might be using it and adding a new attribute needs some additional work and support from the active directory team.
Using SCIM is also a great idea but our active directory is not very organized. I was afraid that we may not have complete control on the users access.
let me know your thoughts on using or changing attributes in the active directory to match with the gitlab’s username.

@akaiserk as part of the SCIM setup (and somewhere in the SAML itself, too), in your directory you should be able to configure the attribute that gets mapped to userName in GitLab. This field, for us at least, allowed a configurable value, and we used Join(".", [mailNickname], "companyname") which ended up creating a @firstname.lastname.companyname username when creating the account. Using this, you shouldn’t need to make any changes in your directory - just use the attributes that make the most sense. (our samAccountName was a no-go - basing things off mailNickname was far more effective)
(For the record, I’m not a part of my IT team - and therefore only have ‘read’ access to the directory myself. I configured this - my first SAML integration - with the help of them - but we did it over a screen share and I was in the driver’s seat)

The best way to test SCIM without affecting your existing users is to create a test namespace, pop a trial on it, and set it up as a separate enterprise application/SAML auth system. You may need to test with a couple of ‘test’ users from your AD - a single user in Gitlab can’t be mapped to multiple SAML providers. This will give you an opportunity to ‘fiddle’ and ‘fine tune’ the settings before turning it on in your main namespace.
Strictly controlling the user groups that are exposed to that enterprise application on the directory side allows you to finely control which users are auto provisioned. As an added bonus - you can also start to make use of SAML Group Sync and then add users to specific subgroups inside Gitlab based on AD groups. (We use this sparingly, but it’s pretty effective)
Hmm. :thinking: I’ve been looking for a good topic to write a comprehensive blog post… /me adds to todo list

1 Like

@stingrayza good morning and thank you again for sharing the details. Yes, a blog post would be really helpful for anyone who are in the same boat as me. I have a follow up question. Sorry, these keep coming up. While I was working on onboarding some of our most active users/developers using SAML to GitLab Cloud, I found out that a few of them already had free tier accounts on GitLab Cloud. I am guessing they might be putting stuff into their personal namespace. Since GitLab cloud works only at the Group Level, I am really concerned if this is going to create any security issues. Is it possible to restrict your company users to your company’s group thereby restricting them from putting anything into their personal namespaces on GitLab Cloud?

No worries - happy to help out.
There is nothing (that I know of) that will stop a user from creating projects in their personal spaces - or for that matter even creating a new (top level) namespace and putting files/projects there.
You can set your namespace to not allow any projects to be forked outside of your namespace - but that doesn’t prohibit a user from pushing something to another upstream. That said, there’s nothing to stop a user pushing something up to github or any other public code repository, either. Remember that your corporate policies that prohibited people from pushing something into a private namespace on GitLab before you migrated there all still apply.

The way we have dealt with this is twofold:

  1. User education - this piece is incredibly important. Explaining (and reminding) users that corp IP lives under the corp namespace is a good start. Perhaps building a body of (internal - ours is hosted in GitLab pages) documentation for your users to help reinforce this.
  2. Offering a substitute location. We created a gitlab.com/corpnamespace/users subgroup. Any user that wants one (we could do it for all - I just need to get around to the automation :wink: ) can request a ‘personal’ subgroup under this location. This gives them a target for forks, personal code, tests and POCs that users may be otherwise looking to push into their personal namespaces. A benefit (and something to sell to your users) is that this location - because it falls under the corp namespace - benefits from all the licensed features that their personal namespace doesn’t. That, coupled with access to any corporate self-managed runners, etc.

A note on SCIM - when faced with an account that already exists, SCIM can’t auto-link them. In these cases the user will need to log into the SSO portal and click the ‘Authorize’ button. If they don’t want to link their accounts, removing their corporate email address from their existing gitlab account will allow the SCIM provisioner to create them a ‘corp’ account on its next run.

1 Like

@stingrayza Thank you so much for your detailed response.

SCIM seems to be a viable option and takes out lot of the manual stuff. Right now we are just going with SAML and reaching out individual users as needed to complete their setup. The reason is to reduce dependency on other teams such as active directory. Once we complete our migration to the cloud, we will come back and look at using SCIM. Coming back to security, it sounds like a lot depends on user education and company policies. Security seems to be a challenge with gitlab cloud.

For the data migration piece, right now, we are developing the following API calls to migrate the group and project data in a big bang fashion and later setup repo mirroring to capture/perform incremental updates.

I would love to hear your thoughts on migrating data to the gitlab cloud.

group export/download/import:
Group Import/Export API | GitLab

	api: export
	curl --request POST --header "PRIVATE-TOKEN: <PRIVATE-TOKEN>" 


	api: download
	curl --header "PRIVATE-TOKEN: <PRIVATE-TOKEN>" --remote-header-name --remote-name "https://gitlabdev.company1.com/api/v4/groups/94/export/download"

	api: import
	curl --request POST --header "PRIVATE-TOKEN: <PRIVATE-TOKEN>" \
		 --form "name=<name>" --form "path=<path>" --form "parent_id=<parent_id>" \
		 --form "file=@/c/Projects/12021/GitLab_Upgrade/import_export_test/dev/2021-06-28_17-11-554_parent_group_test_export.tar.gz" \

project export/download/import:
Project import/export API | GitLab

	api: export
	curl --request POST --header "PRIVATE-TOKEN: <PRIVATE-TOKEN>" "https://gitlabdev.company1.com/api/v4/projects/170/export"
	api: export status
	curl --header "PRIVATE-TOKEN: <PRIVATE-TOKEN>" "https://gitlabdev.company1.com/api/v4/projects/170/export"
	api: download
	curl --header "PRIVATE-TOKEN: <PRIVATE-TOKEN>" --remote-header-name --remote-name "https://gitlabdev.company1.com/api/v4/projects/170/export/download"
	api: import
	curl --request POST --header "PRIVATE-TOKEN: <PRIVATE-TOKEN>" \
		 --form "namespace=<namespace_di>" --form "path=<path>" \
		 --form "file=@/c/Projects/12021/GitLab_Upgrade/import_export_test/dev/2021-06- 29_16-48-635_company1_parent_group_test1_su_export.tar.gz" \

Hey @akaiserk I’ve just realised I never posted this reply:

We’re moving away somewhat from the original topic, but that’s not an issue :slight_smile:

From a migration point of view, you’ve got all the API calls you need right there :+1: - If you like python (or even if you don’t - the gitlab-cli provided by the project is incredibly powerful, too), I’d recommend taking a look at https://python-gitlab.readthedocs.io/ - a fantastic tool to take a lot of the pain (not that there is much) out of the GitLab REST API.

Hello @stingrayza ,

Thanks for getting back to me. We have completed the migration to the GitLab cloud over the last weekend. It was a little tedious at some times. But overall it went well.

Right now, we are trying to resolve some post migration access issues for end users. Some users were coming back to us with different errors.

  1. SSL certificate problem: unable to get local issuer certificate
  2. Invalid Url

The SSL problem seems to be widespread. I am seeing solutions to turn off the SSL as a quick fix but at the same time it’s not recommended as it’s not secure.

Do you have any insights on we could resolve the SSL certificate issue without actually turning it off?

Hi @akaiserk
You really shouldn’t be getting an SSL cert issue on any of the gitlab.com endpoints… If you do they’d be something I’d want to unpick (with a bit more error output). There isn’t an internal DPI proxy or anything resigning the external URLs, is there? (Cisco Umbrella or similar)
If so, you’d either want them to bypass the gitlab.com domain, or you’ll need to ‘trust’ that internal cert on your endpoints.

Hello, Thanks for getting back. It’s been resolved. But now we have something new going on. Our CI jobs have been failing since we migrated to the cloud. We are using self-hosted gitlab-runner. The runner looks “online” on the gui and the logs are not giving much.

I tried troubleshooting in debug mode. It seems to be looking for jobs but can’t find any.
Checking for jobs… nothing runner=Xkkllyspps
Feeding runners to channel builds=0

But the error on the GUI says below:
This job is stuck because the project doesn’t have any runners online assigned to it.

The configuration file ( and the gitlab-ci.yml files doesn’t seem to have any issues.

Any thoughts or ideas?