As a follow-on to the recent blog, The ultimate guide to securing your code on GitLab.com, we recommended enabling SAML (Security Assertion Markup Language) and SSO (single sign-on) to enable tighter control over code access. Let’s take a deep dive into how to enable SAML and SSO on GitLab.com.
What are SAML and SSO?
SAML is an open standard, which service providers (like GitLab.com) and identity providers (commonly referred to as IdPs) use to communicate authentication data. SSO is provided by IdPs, such as Okta and Entra ID (formerly Azure AD), and enables users to log into multiple systems or service providers through a single interface with a single set of credentials.
As with any configuration, there should be thoughtful and careful planning when enabling SSO.
What are the benefits of SSO?
In general, enabling SSO streamlines the user experience by unifying the login process and reducing the account and password bloat required for multiple enterprise applications. Enabling SSO also adds an extra layer of security and management efficiency for identity management teams by providing a single source of truth for authentication. Below, you’ll learn how SAML SSO applies specifically to GitLab.com.
Configuring SSO and SAML for GitLab.com
Premium and Ultimate tiers can enable SSO in the settings available at the namespace or top level group.
Enabling SSO at the group level
Before getting started, you’ll need a few key pieces of information from your chosen IdP:
- The IdP SSO URL
- The certificate fingerprint provided by the IdP application
Once these key pieces are entered, check the “Enable SAML authentication for this group” box.
How user accounts are linked
Before we proceed further into configuration, let’s take a look at how GitLab authenticates against the IdP.
For GitLab.com, each user who requires access to the system must have an account on GitLab.com. By default, when a user first attempts logging into GitLab via SSO, GitLab will receive the SAML assertion and validate if the identity (specifically the email address) is linked to a GitLab.com account. If not, GitLab will request the user either login to an existing account or create a new account. In most instances, this may not be desired behavior; however, we will address this later in the process. We’ve provided a flowchart below to help you navigate the provisioning flow.
Enforcing SSO
To further increase security, there are two options available for enforcing SSO. Assuming neither are checked, users with access to the namespace can log in with either the SSO credentials or the GitLab.com credentials.
Here is a working example that we can use to follow along as we discuss how the
configuration options affect our baseline. Let’s consider a user in the IdP
where the username is idpusername
and contains a super secret password:
idppassword
(apologies, security professionals). Taking into account the
information we just learned about account linking, let us also assume our demo
user created a new account following the prompt from an SSO login with a
username of gitlabusername
and gitlabpassword
as an even more secure
password.
Enforcing SSO only for web
When enabling the “Enforce SSO-only authentication for web activity for this
group” setting, all members must now access all groups and projects under the
hierarchy using the configured SSO login regardless of whether they have an
existing SAML identity. As we mentioned prior, with this flag disabled, our
idpusername
user will be able to log into the GitLab namespace with either
the idpusername
or gitlabusername
credential sets. When we enable this
setting for web-based activity (further details in
docs),
our group is now only accessible by the idpusername
credential set.
Enforcing SSO only for Git proxy
Very similar to enforcing SSO for web, when the “Enforce SSO-only authentication for Git and Dependency Proxy” activity for this group option is enabled, a few things happen:
- Calling an API endpoint that involves Git activity requires SSO.
- For Git activity over SSH and HTTPS, users must have at least one active session signed-in through SSO before they can push to or pull.
There is a strong recommendation to enable both of these settings to take full advantage of the benefits of SSO for users and administrators through centralized authentication.
Enterprise user support
Now that we know how some of the configuration options can help secure access,
let’s take a deeper dive into user management. Consider the following scenario:
Our idpusername
user has decided to pursue another opportunity outside of the
domain. Based on what we have configured now, once the account has been
deprovisioned from the IdP, it should no longer have access to anything secured
behind it on GitLab.com. However, while the user will not have access, the
associated user ID and roles still remain until manually removed. This is where
Enterprise users come in.
What are Enterprise users in GitLab?
If you look closely, any user that has a linked SSO account will carry a SAML
badge in the member list. GitLab also has an associated Enterprise
badge
that grants additional management functionality through SSO. For a user to
carry the Enterprise
badge, the user must either have the initial GitLab.com account creation initiated by a SAML SSO login or have the initial GitLab.com account created by SCIM.
What is SCIM?
SCIM, or System for Cross-domain Identity Management, is another standard used in conjunction with SAML, primarily for provisioning and deprovisioning across multiple systems. By enabling SCIM for your GitLab.com group (which is currently supported with Entra ID and Okta), you can enable automatic provisioning and deprovisioning of accounts.
If we look back at some of our scenarios, without SCIM, our idpusername
user
was prompted to create or link a GitLab.com account on first login. With SCIM
enabled, this process is handled automatically based on information provided
and managed by the IdP and is completely transparent to the end user. The
second half of our scenario, where our idpusername
user is deprovisioned from
the IdP, also is solved with automation via SCIM. In this instance, when the
user is removed on the IdP side, SCIM automatically disconnects the SAML
identity from the GitLab.com account and removes the user from the GitLab.com
group.
Protecting your intellectual property
Another important feature of Enterprise users is the ability to control two
very important user settings that are not accessible to group administrators on
GitLab.com. Since all users require an account on GitLab.com, they are also
granted access to a personal user namespace. For example, our idpusername
will have access to our Acme Corp. group at .com/acmecorp
, and will also have
access to their own personal space at .com/idpusername
. One common concern with this is the ability for users to take code out of the organization
namespace and commit to their own personal namespace.
With Enterprise users, we have two settings that we can control based on attributes received in the SAML
response. These keys are projects_limit
and can_create_group
. The
projects_limit
is an integer value that sets the amount of projects a user
can create in their personal namespace. When set to 0
, this effectively
disables project creation in that space. Similarly, can_create_group
is a
boolean true
or false
value that indicates whether a user can create new
groups.
Managing roles with SAML
Now that we know the ins and outs of creating and removing users with SAML and SCIM, how can we leverage our work to help manage our active users? In this final section, we’ll take a look at why we recommend setting default membership to "Minimal Access" and how to leverage group memberships in the IdP.
Why Minimal Access?
In the Ultimate guide to securing your code on GitLab, we recommend setting the default membership role to Minimal Access, and operating with the concept of least privilege. Roles can be elevated as needed in subgroups or individual projects while preventing visibility to projects or subgroups where the user is not explicitly granted another role. By default, this option is set to Guest, which will allow all provisioned users guest access to the repositories. Default membership controls are available at the top-level group, along with the SAML and SSO settings. For automation at the subgroup level, we can leverage SAML Group Sync.
Configuring SAML Group Sync with SAML Group Links
Before we dive into the configuration, there is one very important step we need
to take. The configured SAML assertion that is sent MUST include an attribute
named Groups
or groups
. If SAML Group Links are present without the
attribute in the assertion, users may be removed from the group or reverted to
Minimal Access.
After we ensure our assertions contain the necessary information, we can start
using SAML Group Links to automatically assign membership roles to GitLab
groups based on group membership in the IdP. Let’s build on our demo user
idpusername
by considering the following:
idpusername
is a maintainer on the acme-web project.- The
acme-web
project exists under theacme-corp
namespace, under subgroupacme-com
. - The full path to the project would be
.com/acme-corp/acme-com/acme-web
. idpusername
should also be granted developer access for theacme-db
project, which is also under theacme-com
group.- In our IdP,
idpusername
is a member of the IdP groupidp-acme-com
.
SAML group links allow us to map IdP group memberships to role assignments at
the GitLab group level. In this scenario, we can create a group link at the
acme-com
group in GitLab that maps the IdP group idp-acme-com
to the
developer role to the acme-com
group.
Due to inheritance, our idpusername
user will be granted developer access and associated visibility to every
project and group that falls under the GitLab acme-com
group automatically by
virtue of the IdP group membership, because we’re working under the concept of
least privilege for the acme-web
project.
The idpusername
user’s role can
be elevated to maintainer directly in the project. From a user perspective,
idpusername
would still carry the Minimal Access role at the acme-corp
group as well. This allows a separation of access management between
engineering and identity management teams and allows role management to be
flexible with guardrails.
With this approach, it’s important to find that balance between what is managed
in the IdP and what is managed in GitLab. It’s possible to have hundreds of
group mappings to roles in the IdP and almost completely remove role management
within GitLab and vice versa. The flexibility that GitLab allows enables you to
find the best solution that works for you. Building on our example, if we hire
another engineer for the acme-com
project, they can be added to the GitLab
application in the IdP, and added to the idp-acme-com
group. This
automatically assigns them the developer role at the acme-com
group and for
all projects under it, while limiting access to any other groups outside of
acme-com
in the namespace.
Learn more
We’ve covered how to get started with enabling SAML and SSO on your GitLab.com group, along with how to leverage the features to programmatically manage users and roles with real examples. For more information, see the full SAML SSO for GitLab.com groups documentation.
Cover image by Towfiqu barbhuiya on Unsplash