Configuring SAML SSO for GitLab: A Comprehensive Beginner’s Guide
In today’s collaborative software development landscape, managing user access across multiple tools can quickly become cumbersome and introduce security risks. GitLab, a leading DevOps platform, offers robust features, but managing user accounts directly within it, especially for larger organizations, can be inefficient. This is where Single Sign-On (SSO) comes into play, and Security Assertion Markup Language (SAML) is the gold standard protocol for implementing it in enterprise environments.
Integrating GitLab with your organization’s central Identity Provider (IdP) via SAML allows users to log in using their existing corporate credentials. This streamlines the login process, enhances security by centralizing authentication, simplifies user lifecycle management (onboarding/offboarding), and improves the overall user experience.
This comprehensive guide is designed for beginners, including GitLab administrators and IT professionals, who want to understand and configure SAML SSO for their GitLab instance (both Self-Managed and, where applicable, GitLab.com). We will break down the concepts, walk through the configuration steps in detail, provide examples, and cover common troubleshooting scenarios.
Table of Contents:
- Introduction to SAML SSO
- What is Single Sign-On (SSO)?
- What is SAML?
- Why Use SAML SSO with GitLab? (Benefits)
- Key SAML Terminology (IdP, SP, Assertion, etc.)
- Prerequisites
- GitLab Instance (Self-Managed vs. GitLab.com)
- Identity Provider (IdP) Account
- Administrative Access
- Basic Understanding of Your IdP
- Understanding the SAML Flow with GitLab
- The SP-Initiated Flow (Typical for GitLab)
- The IdP-Initiated Flow
- Key Information Exchange: Metadata
- Core SAML Concepts Explained
- Identity Provider (IdP)
- Service Provider (SP)
- SAML Assertions (Attributes, Conditions, Authentication Statements)
- SAML Bindings (HTTP POST, HTTP Redirect)
- SAML Metadata (The “Phonebook” of SAML)
- NameID Format
- Digital Signatures and Certificates
- General Configuration Steps Overview
- Step 1: Prepare Your Identity Provider (IdP)
- Step 2: Prepare Your GitLab Instance (SP)
- Step 3: Exchange Metadata Between IdP and SP
- Step 4: Configure Attribute Mapping
- Step 5: Test the Configuration
- Configuring GitLab (Service Provider)
- Accessing SAML Configuration (Self-Managed vs. GitLab.com)
- Self-Managed GitLab Configuration (
gitlab.rb
)- Enabling SAML
- Assertion Consumer Service (ACS) URL
- Issuer (Entity ID)
- IdP SSO Target URL (Single Sign-On URL)
- IdP Certificate Fingerprint / Certificate
- Name Identifier Format
- Attribute Mapping (
uid
,email
,name
,first_name
,last_name
) - Group SAML / SAML Group Sync (Introduction)
- Other Important Settings (
auto_link_saml_user
,allow_single_sign_on
,block_auto_created_users
) - Applying Changes (
gitlab-ctl reconfigure
)
- GitLab.com Configuration (Group Level)
- Navigating to Group SAML SSO Settings
- Key Configuration Fields (Similar to Self-Managed but via UI)
- User Provisioning and Linking
- Enforcing SAML SSO
- Configuring the Identity Provider (IdP) – Example with Okta
- Disclaimer: Steps vary by IdP
- Creating a New SAML Application in Okta
- General Settings (App Name, Logo)
- SAML Settings Configuration:
- Single sign on URL (GitLab’s ACS URL)
- Audience URI (SP Entity ID – GitLab’s Issuer ID)
- Default RelayState (Optional)
- Name ID Format (e.g., EmailAddress)
- Application username (e.g., Okta username or Email)
- Attribute Statements (Mapping IdP attributes to SAML Assertions)
- Mapping
email
,firstName
,lastName
- Mapping Groups (Crucial for Group Sync)
- Mapping
- Obtaining IdP Metadata (Identity Provider metadata URL or XML file)
- Assigning Users and Groups to the Application
- Connecting the Dots: Exchanging Metadata
- Providing IdP Metadata to GitLab
- Using Metadata URL (Recommended where supported)
- Manual Configuration (SSO URL, Issuer ID, Certificate)
- Providing GitLab (SP) Metadata to the IdP
- Finding GitLab’s Metadata URL (
/users/auth/saml/metadata
) - Providing ACS URL and Entity ID manually
- Finding GitLab’s Metadata URL (
- Providing IdP Metadata to GitLab
- Testing and Verification
- The User Login Experience (SP-Initiated)
- Initial Login and Account Linking/Provisioning
- Testing with Different User Roles
- Verifying User Attributes in GitLab
- Advanced Configuration and Features
- Just-in-Time (JIT) Provisioning: Automatically creating GitLab users on first SAML login.
- SAML Group Links / Group Sync: Automatically managing GitLab group membership based on IdP groups.
- Configuring
groups_attribute
ingitlab.rb
- Creating SAML Group Links in GitLab Groups
- Benefits and Use Cases
- Configuring
- Required Groups: Restricting SAML login to members of specific IdP groups.
- Session Duration and Timeouts: Configuring session length (
session_duration
). - Customizing Attribute Mappings: Fine-tuning how IdP attributes populate GitLab user profiles.
- Single Logout (SLO): Configuring logout propagation (more complex, often IdP-dependent).
- Troubleshooting Common SAML Issues
- Tools:
- SAML Tracer Browser Extensions (SAML-tracer, SAML Chrome Panel)
- GitLab Production Logs (
/var/log/gitlab/gitlab-rails/production.log
) - IdP Logs
- Common Errors and Solutions:
Invalid Signature / Digest
: Certificate mismatch, ensure correct IdP cert in GitLab.Invalid Audience
: Audience URI in IdP doesn’t match GitLab’s Issuer ID.Invalid Destination
: ACS URL in IdP doesn’t match GitLab’s ACS URL.NameID not found / format incorrect
: Check NameID configuration on both sides.User Not Found / Access Denied (IdP Side)
: User not assigned to the application in the IdP.Clock Skew Error
: Time difference between IdP and SP servers exceeds tolerance (allowed_clock_drift
). Ensure NTP is configured.Missing Required Attributes
: JIT provisioning fails because required attributes (like email) are not sent by the IdP.500 Internal Server Error
after redirect: Check GitLab production logs for specific errors. Could be configuration parsing issues, database problems, etc.User already exists
errors during linking.
- Tools:
- Security Considerations
- Secure Your IdP (MFA, Strong Policies)
- Use HTTPS Everywhere
- Certificate Management and Rotation
- Regularly Audit User Access and Group Mappings
- Understand
block_auto_created_users
setting - Consider Enforcing SSO (Carefully!)
- Conclusion
1. Introduction to SAML SSO
Before diving into configuration, let’s establish a foundational understanding of SAML SSO and its relevance to GitLab.
What is Single Sign-On (SSO)?
Single Sign-On is an authentication scheme that allows a user to log in with a single set of credentials (typically their primary corporate username and password) to multiple independent software systems. Instead of remembering dozens of different passwords for different applications (email, CRM, HR portal, GitLab, etc.), the user authenticates once against a central authority and is then granted access to various connected services without needing to log in again.
What is SAML?
Security Assertion Markup Language (SAML) is an open standard XML-based protocol used for exchanging authentication and authorization data between parties, primarily between an Identity Provider (IdP) and a Service Provider (SP).
- Identity Provider (IdP): The system that authenticates the user and holds their identity information (e.g., Okta, Azure Active Directory, Google Workspace, Active Directory Federation Services – ADFS).
- Service Provider (SP): The application or service the user wants to access (in our case, GitLab).
SAML enables SSO by allowing the IdP to securely “assert” the user’s identity and relevant attributes (like email address, name, group memberships) to the SP after successful authentication.
Why Use SAML SSO with GitLab? (Benefits)
Integrating SAML SSO with GitLab offers significant advantages:
- Enhanced Security: Centralizes authentication to the IdP, which typically has robust security policies like Multi-Factor Authentication (MFA), password complexity rules, and conditional access policies. Reduces the risk associated with managing separate GitLab passwords.
- Improved User Experience: Users log in with familiar credentials they already use daily. No need to remember (or forget) another password. Seamless access after authenticating once with the IdP.
- Simplified User Management: User onboarding and offboarding are managed centrally at the IdP level. When an employee joins or leaves the company, their access to GitLab (and other SAML-connected apps) can be granted or revoked automatically by managing their account in the central directory.
- Increased Productivity: Less time spent on login prompts and password resets.
- Compliance and Auditing: Centralized authentication logs in the IdP provide a single point for auditing access across multiple applications, aiding compliance efforts.
Key SAML Terminology (IdP, SP, Assertion, etc.)
Get comfortable with these terms, as you’ll encounter them frequently:
- Identity Provider (IdP): The authority that verifies the user’s identity (e.g., Okta, Azure AD).
- Service Provider (SP): The application the user wants to access (e.g., GitLab).
- User (or Principal): The individual trying to log in.
- SAML Assertion: An XML document generated by the IdP containing statements about the authenticated user. It typically includes:
- Authentication Statement: Confirms how and when the user authenticated.
- Attribute Statement: Contains user attributes (e.g., email, name, groups).
- Authorization Decision Statement: (Less common in basic SSO) Indicates if the user is authorized for a specific resource.
- Conditions: Specifies the validity period of the assertion and the intended audience (the SP).
- SAML Request (AuthnRequest): Sent by the SP to the IdP to initiate the authentication process.
- SAML Response: Sent by the IdP back to the SP, usually containing the SAML Assertion after successful user authentication.
- Binding: Defines how SAML messages (Requests/Responses) are transported over protocols like HTTP (e.g., HTTP POST, HTTP Redirect).
- Metadata: An XML file describing an IdP or SP’s SAML configuration details (URLs, certificates, supported formats). Used to establish trust and configure the connection.
- Assertion Consumer Service (ACS) URL: The SP’s endpoint (URL) where it receives SAML Responses from the IdP.
- Single Sign-On (SSO) URL: The IdP’s endpoint where it receives SAML Requests from the SP and where the user is redirected for authentication.
- Entity ID (or Issuer ID): A unique identifier for the IdP or SP. Often a URL, but doesn’t necessarily need to be resolvable.
- NameID: An identifier within the SAML Assertion that represents the user (e.g., email address, username). The format needs to be agreed upon by the IdP and SP.
- Digital Signature: Used to ensure the integrity and authenticity of SAML messages. The IdP signs the assertion or response using its private key, and the SP verifies it using the IdP’s public key (usually obtained from metadata).
2. Prerequisites
Before you begin the configuration process, ensure you have the following:
- GitLab Instance:
- Self-Managed GitLab: You need a working GitLab instance (Community Edition or Enterprise Edition). SAML is available in all tiers, but some advanced features like SAML Group Sync require a Premium/Ultimate license (or Gold/Silver for older versions).
- GitLab.com: You need a Group on GitLab.com with a Premium/Ultimate subscription (or Gold/Silver) to configure SAML SSO at the group level. Free tier users cannot configure SAML SSO.
- Identity Provider (IdP) Account: Access to an existing SAML 2.0 compliant IdP. Common examples include:
- Okta
- Microsoft Azure Active Directory (Azure AD)
- Google Workspace
- Active Directory Federation Services (ADFS)
- OneLogin
- Ping Identity
- Auth0
- Keycloak
- Administrative Access:
- GitLab: You need administrator access to your Self-Managed GitLab instance (to edit
gitlab.rb
or use the Admin Area UI) or Owner permissions for the specific Group on GitLab.com. - IdP: You need administrative permissions within your IdP to create and configure SAML applications.
- GitLab: You need administrator access to your Self-Managed GitLab instance (to edit
- Basic Understanding of Your IdP: Familiarity with your IdP’s interface for managing applications and user attributes will be helpful.
3. Understanding the SAML Flow with GitLab
The most common SAML flow used with web applications like GitLab is the SP-Initiated Flow.
The SP-Initiated Flow (Typical for GitLab)
- User Access Request: The user navigates to the GitLab instance URL (e.g.,
https://gitlab.example.com
). - Login Option: The user sees the GitLab login page, which now includes a button like “Sign in with SAML” or “Sign in with [Your IdP Name]”. The user clicks this button.
- SAML Request: GitLab (the SP) generates a SAML Authentication Request (AuthnRequest) and redirects the user’s browser to the IdP’s Single Sign-On (SSO) URL, sending the AuthnRequest (often via HTTP Redirect binding).
- IdP Authentication: The IdP receives the request. If the user doesn’t already have an active session with the IdP, the IdP presents its login page. The user authenticates using their corporate credentials (username, password, potentially MFA).
- SAML Response: After successful authentication, the IdP generates a SAML Response containing the SAML Assertion (with user identity, attributes, and signature).
- Response to SP: The IdP sends the SAML Response back to GitLab’s Assertion Consumer Service (ACS) URL via the user’s browser (typically using HTTP POST binding). This usually involves an auto-submitting HTML form.
- SP Verification: GitLab (SP) receives the SAML Response. It verifies:
- The signature using the IdP’s public certificate.
- The conditions (e.g., timestamp, audience restriction).
- The destination matches its ACS URL.
- Session Creation: If verification succeeds, GitLab extracts the user’s identity (NameID) and attributes from the assertion.
- If the user already exists (matched by email or NameID) and linking is enabled, GitLab logs them in.
- If Just-in-Time (JIT) provisioning is enabled and the user doesn’t exist, GitLab creates a new account based on the received attributes and logs them in.
- If the user doesn’t exist and JIT is disabled, login fails.
- Access Granted: The user is redirected to their GitLab dashboard, now logged in.
The IdP-Initiated Flow
While less common for direct GitLab access, some IdPs allow users to click on an application tile (like a GitLab tile) within the IdP’s portal.
- User logs into the IdP portal.
- User clicks the GitLab application icon.
- The IdP generates a SAML Response directly (without receiving a SAML Request first) and sends it to GitLab’s ACS URL via the user’s browser.
- GitLab receives and verifies the Response (steps 7-9 above).
GitLab supports both flows, but SP-initiated is the standard way users interact directly with the GitLab login page.
Key Information Exchange: Metadata
The foundation of a SAML connection is Metadata. Both the IdP and the SP publish metadata files (XML documents) containing crucial information needed by the other party:
- IdP Metadata: Contains its Entity ID, SSO URL, SLO (Single Logout) URL (if applicable), and its public signing certificate.
- SP Metadata (GitLab): Contains its Entity ID (Issuer), ACS URL, SLO URL (if applicable), and potentially its public certificate (if signing requests or encrypting assertions).
Exchanging this metadata (either by providing URLs or uploading files) is how the IdP and SP learn how to communicate securely.
4. Core SAML Concepts Explained
Let’s delve a bit deeper into the core components of SAML. Understanding these will make the configuration process much clearer.
- Identity Provider (IdP): Think of the IdP as the “passport office.” It’s the trusted authority responsible for verifying who a user is. It manages user identities, credentials, and authentication methods (passwords, MFA). When a user successfully authenticates, the IdP issues a “passport” (the SAML Assertion) vouching for their identity. Examples: Okta, Azure AD, ADFS.
- Service Provider (SP): Think of the SP as the “country” the user wants to enter. It’s the application (GitLab) that relies on the IdP to handle authentication. It trusts the “passport” (SAML Assertion) issued by the IdP. It needs to know which “passport office” (IdP) to trust and how to validate the passports it receives.
- SAML Assertions: This is the core XML document exchanged. It’s the “passport” containing information about the authenticated user. Key parts:
- Subject: Identifies the user (the
NameID
). - Conditions: Specifies the assertion’s validity period (
NotBefore
,NotOnOrAfter
) and the intended audience (AudienceRestriction
– must match the SP’s Entity ID). This prevents replay attacks and ensures the assertion is used only by the intended SP. - Authentication Statement: Describes how (
AuthnContext
) and when (AuthnInstant
) the user authenticated at the IdP. - Attribute Statement: Contains specific details (attributes) about the user, sent as key-value pairs (e.g.,
<Attribute Name="email"><AttributeValue>[email protected]</AttributeValue></Attribute>
). GitLab uses these attributes to populate user profiles (email, name) and manage group memberships.
- Subject: Identifies the user (the
- SAML Bindings: These define how SAML messages travel between the SP and IdP using underlying protocols like HTTP. The two main ones:
- HTTP-Redirect Binding: Used typically for sending SAML Requests (AuthnRequest) from SP to IdP. The message is encoded, compressed, and included as a URL parameter in an HTTP GET request. The user’s browser is simply redirected.
- HTTP-POST Binding: Used typically for sending SAML Responses from IdP to SP. The message (base64 encoded) is embedded within an HTML form that auto-submits using JavaScript in the user’s browser via an HTTP POST request. This handles potentially larger assertion sizes.
- SAML Metadata: This is critical for setup. It’s an XML file that acts like a configuration cheatsheet or “phonebook” for a SAML entity (IdP or SP).
- IdP Metadata tells the SP: “Here’s my unique name (Entity ID), here’s where you should send users to log in (SSO URL), and here’s my public key (certificate) so you can verify messages I send you.”
- SP Metadata tells the IdP: “Here’s my unique name (Entity ID), here’s where you should send authentication responses (ACS URL), and here’s the format I expect the username in (NameID Format).”
- Using metadata URLs simplifies configuration and updates (like certificate rotation).
- NameID Format: Specifies the format of the user identifier (
NameID
) within the SAML Subject. Common formats include:urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
(User’s email address)urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
(A persistent, opaque identifier unique to the user and SP)urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
(Allows the IdP to choose the format)- GitLab needs to know which format the IdP will use, and the IdP needs to be configured to send the
NameID
in that format. Email address is very common and often easiest for matching existing users.
- Digital Signatures and Certificates: SAML relies on public-key cryptography for security.
- The IdP uses its private key to sign the SAML Assertion or the entire Response.
- The SP uses the IdP’s corresponding public key (obtained from the IdP’s metadata) to verify the signature.
- This ensures Integrity (the message wasn’t tampered with) and Authentication (the message genuinely came from the trusted IdP).
- Certificates have expiration dates, so managing certificate rotation is important for maintaining the connection.
5. General Configuration Steps Overview
Configuring SAML involves steps on both the IdP and SP sides. Here’s a high-level overview:
- Step 1: Prepare Your Identity Provider (IdP): Create a new SAML application configuration within your IdP specifically for GitLab. You’ll need some information from GitLab (like the ACS URL and Entity ID) to complete this step, so it’s often iterative.
- Step 2: Prepare Your GitLab Instance (SP): Configure the SAML settings within GitLab. You’ll need information from the IdP (like its SSO URL, Entity ID, and certificate) for this.
- Step 3: Exchange Metadata Between IdP and SP: Ensure both systems have the necessary configuration details from the other. This is often done by providing the IdP with GitLab’s metadata URL (or specific values) and configuring GitLab with the IdP’s metadata URL (or specific values).
- Step 4: Configure Attribute Mapping: Define which attributes the IdP should send in the SAML assertion (e.g., email, first name, last name, groups) and how GitLab should map these attributes to its user profile fields and group memberships.
- Step 5: Test the Configuration: Perform test logins using different user accounts to ensure the SSO flow works correctly, accounts are linked or provisioned as expected, and attributes are populated correctly.
6. Configuring GitLab (Service Provider)
The method for configuring SAML in GitLab depends on whether you are using a Self-Managed instance or GitLab.com.
Accessing SAML Configuration
- Self-Managed GitLab: Configuration is primarily done by editing the main GitLab configuration file:
/etc/gitlab/gitlab.rb
. After editing, you must runsudo gitlab-ctl reconfigure
for changes to take effect. Some settings might also be visible or adjustable in the Admin Area -> Settings -> General -> Single sign-on section of the UI, butgitlab.rb
is the source of truth and required for initial setup. - GitLab.com: Configuration is done at the Group level. Navigate to your Group -> Settings -> SAML SSO. You need Owner permissions for the group and a Premium/Ultimate subscription.
Self-Managed GitLab Configuration (gitlab.rb
)
Open /etc/gitlab/gitlab.rb
with root privileges using a text editor (like nano
or vim
). Find the gitlab_rails['omniauth_providers']
section or add it if it doesn’t exist.
“`ruby
/etc/gitlab/gitlab.rb
Enable OmniAuth and specify providers
gitlab_rails[‘omniauth_enabled’] = true
gitlab_rails[‘omniauth_allow_single_sign_on’] = [‘saml’] # Can add other providers like ‘google_oauth2’, ‘github’
gitlab_rails[‘omniauth_auto_link_saml_user’] = true # Automatically link SAML users with existing GitLab accounts if emails match
gitlab_rails[‘omniauth_block_auto_created_users’] = false # Set to true to block automatically created users until approved by an admin
gitlab_rails[‘omniauth_auto_sign_in_with_provider’] = ‘saml’ # Optional: Automatically redirect to IdP from GitLab login page
— SAML Provider Configuration —
Replace ‘main’ with a unique identifier for your IdP config if needed,
but ‘saml’ is the typical key when you only have one SAML IdP.
gitlab_rails[‘omniauth_providers’] = [
{
name: ‘saml’, # Do not change ‘saml’ here
label: ‘Sign in with MyOrg SSO’, # This is the text displayed on the login button
args: {
# Assertion Consumer Service (ACS) URL: How the IdP sends the response back to GitLab.
# Replace ‘https://gitlab.example.com’ with your actual GitLab instance URL.
assertion_consumer_service_url: ‘https://gitlab.example.com/users/auth/saml/callback’,
# Issuer (SP Entity ID): Unique identifier for your GitLab instance.
# Can be anything, but using the GitLab URL is common practice. Must match IdP config.
issuer: 'https://gitlab.example.com',
# IdP Single Sign-On (SSO) Target URL: Where GitLab sends the user for authentication.
# Get this URL from your IdP configuration.
idp_sso_target_url: 'https://your-idp.example.com/app/your-org/exkabcdefg1234567/sso/saml',
# IdP Certificate Fingerprint OR full Certificate: Used by GitLab to verify the IdP's signature.
# Get this from your IdP. Using the fingerprint is generally easier.
# Find the SHA1 fingerprint of the IdP's signing certificate. Remove colons if present.
# idp_cert_fingerprint: 'AB:CD:EF:01:23:45:67:89:AB:CD:EF:01:23:45:67:89:AB:CD:EF:01',
# OR provide the full PEM-formatted certificate:
idp_cert: "-----BEGIN CERTIFICATE-----\nMIID...EXAMPLE...Qf5s=\n-----END CERTIFICATE-----",
# Using idp_cert is generally preferred over fingerprint if your IdP provides it easily.
# Name Identifier Format: Tells the IdP what format GitLab expects for the user's unique ID.
# Common options:
# 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress' (Recommended if using email to match users)
# 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
# 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'
# Must match the NameID format configured in the IdP.
name_identifier_format: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
# Attribute Mapping: Define how IdP attributes map to GitLab user fields.
# The keys ('email', 'name', etc.) are what GitLab expects.
# The values ('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress', 'groups', etc.)
# are the *exact* Attribute Names sent by your IdP in the SAML assertion.
# Check your IdP's attribute statement configuration or use a SAML tracer to find the correct names.
attribute_statements: {
email: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress', 'urn:oid:0.9.2342.19200300.100.1.3'], # List multiple possible attribute names for email
name: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'],
first_name: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'],
last_name: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname'],
# 'nickname' or 'username' can be mapped if needed, often defaults to part of email or NameID if not provided
# nickname: ['username']
# Group Attribute (for SAML Group Sync - Premium/Ultimate feature):
# groups_attribute: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/groups', # Example for ADFS/Azure AD
groups_attribute: 'groups', # Example for Okta if attribute name is 'groups'
},
# Optional: Define specific IdP groups required to log in via SAML (Premium/Ultimate).
# If set, only users who are members of *at least one* of these groups in the IdP
# (sent via the groups_attribute) can log in via SAML.
# required_groups: ['gitlab-users', 'developers'],
# Optional: Allowed Clock Skew (in seconds) between IdP and SP servers. Default is usually fine unless you see clock errors.
# allowed_clock_drift: 60,
# Optional: Set user attributes like 'external' status or 'admin' based on SAML attributes
# uid_attribute: 'uid', # If NameID isn't the primary identifier you want to use internally
# external_groups: ['contractors'], # Groups whose members should be marked as 'external' users in GitLab
# sync_profile_attributes: true, # Update profile attributes on each login? (Default: true)
# sync_profile_email: true, # Update profile email on each login? (Default: true)
}
}
# You can add configurations for other providers here, e.g., Google, GitHub
# { name: ‘google_oauth2’, app_id: ‘YOUR_APP_ID’, app_secret: ‘YOUR_APP_SECRET’ }
]
“`
Explanation of Key Settings:
omniauth_enabled: true
: Globally enables OmniAuth, GitLab’s authentication framework.omniauth_allow_single_sign_on: ['saml']
: Specifies which OmniAuth providers can be used for login.omniauth_auto_link_saml_user: true
: Crucial for existing users. If a user logs in via SAML and their email address matches an existing GitLab account’s primary email, GitLab automatically links the SAML identity to that account. Iffalse
, users would need to manually link accounts or might end up with duplicates.omniauth_block_auto_created_users: false
: Iftrue
, users created via SAML JIT provisioning are blocked and must be manually unblocked by a GitLab administrator. Useful for controlled onboarding. Defaultfalse
allows immediate access.name: 'saml'
: Internal identifier for the SAML provider. Do not change this.label: '...'
: Text for the SSO button on the login page. Customize as needed.args: {...}
: Contains the specific SAML configuration parameters.assertion_consumer_service_url
: Your GitLab instance’s callback URL. Usuallyhttps://your.gitlab.domain/users/auth/saml/callback
. You provide this to your IdP.issuer
: Your GitLab instance’s unique identifier (Entity ID). This must exactly match the “Audience URI” or “SP Entity ID” configured in your IdP. Using your GitLab base URL is common.idp_sso_target_url
: The IdP’s login endpoint URL. GitLab redirects users here. Get this from your IdP setup.idp_cert_fingerprint
oridp_cert
: The IdP’s public signing certificate (or its fingerprint). GitLab uses this to verify the IdP’s signature on the SAML response. Get this from your IdP. Use one or the other.idp_cert
(the full PEM format) is often considered slightly more robust than the fingerprint, especially if the IdP might use different keys for signing. Ensure the certificate includes the-----BEGIN CERTIFICATE-----
and-----END CERTIFICATE-----
markers and newlines (\n
).name_identifier_format
: Specifies the format expected for the user’s unique ID (NameID
) in the SAML assertion’s Subject. Must match the IdP’s configuration.emailAddress
is frequently used.attribute_statements
: Crucial for mapping. Defines how attributes received from the IdP (identified by their full name/URI/OID) map to GitLab’s internal user attributes (email
,name
,first_name
,last_name
,groups_attribute
). You must find the exact attribute names your IdP sends. Use a SAML tracer tool during a test login if unsure.groups_attribute
: Specifies the name of the SAML attribute that contains the user’s group memberships from the IdP. Required for SAML Group Sync (Premium/Ultimate).required_groups
: (Premium/Ultimate) An array of IdP group names. If defined, users must belong to at least one of these groups in the IdP to be allowed to sign in via SAML.
Applying Changes:
After saving changes to /etc/gitlab/gitlab.rb
, you must run:
bash
sudo gitlab-ctl reconfigure
This command reads the configuration file and applies the changes to the various GitLab components. It might take a few minutes. A restart might sometimes be necessary, although reconfigure often handles it: sudo gitlab-ctl restart
.
GitLab.com Configuration (Group Level)
For GitLab.com, SAML SSO is configured within the settings of a specific Group.
- Navigate to your Group on GitLab.com.
- On the left sidebar, go to
Settings
->SAML SSO
. - You will see fields corresponding to the settings in
gitlab.rb
:- Enable SAML authentication for this group: Checkbox to turn SSO on/off.
- Identity provider single sign-on URL: Enter the
idp_sso_target_url
from your IdP. - Certificate fingerprint: Enter the SHA1
idp_cert_fingerprint
from your IdP (colons are usually optional/ignored). Alternatively, some IdPs might provide the full certificate to paste here. - Default membership role: (Not directly SAML) Assigns a default GitLab role (e.g., Developer, Reporter) to users provisioned via SAML for this group.
- Enforce SSO-only authentication for web activity for this group: (Use with caution!) If checked, users must use SAML SSO to access the group’s resources via the web UI. They cannot use their GitLab.com username/password. This does not apply to Git activity over SSH or HTTPS with tokens initially.
- Enforce SSO-only authentication for Git activity for this group: (Use with caution!) If checked, users must use SAML SSO credentials or specific token types for Git operations.
- User provisioning and linking: GitLab.com automatically links users based on email address. New users will be provisioned upon first login.
- Assertion Consumer Service URL: GitLab provides this URL (e.g.,
https://gitlab.com/groups/your-group/-/saml/callback
). You need to enter this into your IdP configuration. - Identifier (Entity ID): GitLab provides this unique identifier for your group’s SAML config (e.g.,
https://gitlab.com/groups/your-group
). You need to enter this as the Audience URI / SP Entity ID in your IdP configuration.
- Fill in the required fields obtained from your IdP configuration (SSO URL, Certificate Fingerprint).
- Click Save changes.
GitLab.com’s configuration is UI-driven and specific to a single group, whereas self-managed configuration is file-based and instance-wide (though access can be restricted using required_groups
or Group Sync).
7. Configuring the Identity Provider (IdP) – Example with Okta
Configuring the IdP side varies significantly depending on which IdP you use (Azure AD, Google Workspace, ADFS, etc.). However, the concepts and information required are generally the same. We’ll use Okta as a detailed example.
Disclaimer: IdP interfaces change. These steps are illustrative based on Okta’s typical flow but always refer to the current documentation for your specific IdP.
Goal: Create a SAML 2.0 application in Okta that represents your GitLab instance.
- Log in to Okta: Access your Okta admin dashboard.
- Navigate to Applications: Go to
Applications
->Applications
. - Create App Integration: Click
Create App Integration
. - Select SAML 2.0: Choose
SAML 2.0
as the sign-on method and clickNext
. - General Settings:
- App name: Enter a descriptive name, e.g.,
GitLab Self-Managed
orGitLab MyGroup (GitLab.com)
. - App logo (Optional): Upload a GitLab logo for better visibility in the Okta dashboard.
- App visibility: Choose whether to show the app icon to users. Click
Next
.
- App name: Enter a descriptive name, e.g.,
- Configure SAML (The Core Step): This is where you provide information about your GitLab instance (the SP) to Okta (the IdP).
- A. SAML Settings:
- Single sign on URL: Enter GitLab’s Assertion Consumer Service (ACS) URL.
- Self-Managed:
https://gitlab.example.com/users/auth/saml/callback
(Use your actual domain) - GitLab.com Group:
https://gitlab.com/groups/your-group/-/saml/callback
(Find this in GitLab’s SAML SSO settings page for your group) - Check the
Use this for Recipient URL and Destination URL
box unless you have specific reasons not to.
- Self-Managed:
- Audience URI (SP Entity ID): Enter GitLab’s Issuer / Entity ID. This must exactly match the
issuer
value ingitlab.rb
or the Identifier shown in GitLab.com’s group settings.- Self-Managed:
https://gitlab.example.com
(Use the value you set ingitlab.rb
) - GitLab.com Group:
https://gitlab.com/groups/your-group
(Use the value provided by GitLab)
- Self-Managed:
- Default RelayState: Leave blank unless you have a specific use case to redirect users to a particular page within GitLab after login.
- Name ID format: Select the format that matches what you configured in GitLab (
name_identifier_format
).EmailAddress
is common. - Application username: Choose what Okta attribute should be used as the NameID value.
Email
is often the best choice if you selectedEmailAddress
as the format. Other options likeOkta username
might be available. Ensure this value uniquely identifies the user. - Update application username on: Choose whether Okta should update the username if it changes (
Create and update
).
- Single sign on URL: Enter GitLab’s Assertion Consumer Service (ACS) URL.
- B. Attribute Statements (Required): This maps Okta user profile attributes to the SAML attributes GitLab expects. You defined the expected names in GitLab’s
attribute_statements
. Now you tell Okta to send them. ClickAdd Another
for each mapping.- Name: Enter the attribute name exactly as expected by GitLab (from your
gitlab.rb
attribute_statements
values, or standard URIs). - Name format: Usually
Unspecified
is fine unless GitLab requires a specific format (rare). - Value: Select the corresponding Okta user attribute from the dropdown (e.g.,
user.email
,user.firstName
,user.lastName
). - Example Mappings:
| Name (Expected by GitLab, fromattribute_statements
value) | Name Format | Value (Okta Attribute) |
| :——————————————————— | :———— | :——————— |
|email
(if using simple names) ORhttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
|Unspecified
|user.email
|
|name
ORhttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
|Unspecified
|user.firstName + ' ' + user.lastName
(You might need to use Okta expressions here, or map first/last separately) |
|first_name
ORhttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
|Unspecified
|user.firstName
|
|last_name
ORhttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
|Unspecified
|user.lastName
| - Important: Check the exact attribute names required by your specific GitLab configuration. Simple names like
email
,first_name
might work if configured that way ingitlab.rb
, but using the full schema URI is often more standard.
- Name: Enter the attribute name exactly as expected by GitLab (from your
- C. Group Attribute Statements (Optional, for SAML Group Sync): If you want to use GitLab’s SAML Group Sync feature (Premium/Ultimate), you need to send group information.
- Name: Enter the attribute name you specified in GitLab’s
groups_attribute
setting (e.g.,groups
). - Name format:
Unspecified
. - Filter: Choose how to send groups.
Matches regex
with.*
as the value is common to send all groups the user belongs to. Alternatively, you can use filters likeStarts with
orEquals
to send only specific groups relevant to GitLab access (e.g., groups namedgitlab-
something). This is highly recommended to avoid sending excessive group information. - Value: Select
Groups
.
- Name: Enter the attribute name you specified in GitLab’s
- A. SAML Settings:
- Feedback (Optional): Provide feedback to Okta if desired. Click
Next
. - Finish: Select “I’m an Okta customer adding an internal app” and check any relevant boxes. Click
Finish
.
Obtaining IdP Metadata from Okta:
Once the application is created, Okta provides the necessary information for GitLab:
- Go to the
Sign On
tab of the newly created GitLab application in Okta. - Look for a section like
SAML Signing Certificates
. There might be anActions
dropdown next to the active certificate allowing you toView IdP metadata
orDownload certificate
. - Option 1 (Metadata URL – Preferred): Find the “Identity Provider metadata” link. This URL (ending in
/metadata
) contains all the necessary info (SSO URL, Issuer ID, Certificate). If your GitLab version supports it (most recent self-managed versions do viaidp_metadata_url
ingitlab.rb
, though not shown in the example above, or GitLab.com), using this URL is the easiest way. - Option 2 (Manual Details): If you need the individual pieces:
- Identity Provider Single Sign-On URL: Find this URL (this is your
idp_sso_target_url
forgitlab.rb
). - Identity Provider Issuer: Find this URL/URN (this is the IdP’s Entity ID, you usually don’t need this for the GitLab config itself, but good to note).
- X.509 Certificate: Download the signing certificate (usually PEM format). You can either:
- Calculate its SHA1 fingerprint (e.g., using
openssl x509 -noout -fingerprint -sha1 -inform pem -in your_cert.pem
) and useidp_cert_fingerprint
ingitlab.rb
. Remove any colons from the output. - Copy the entire content of the certificate file (including
-----BEGIN CERTIFICATE-----
and-----END CERTIFICATE-----
) and paste it into theidp_cert
field ingitlab.rb
(remembering the\n
for newlines). For GitLab.com, paste the fingerprint into the corresponding field.
- Calculate its SHA1 fingerprint (e.g., using
- Identity Provider Single Sign-On URL: Find this URL (this is your
Assigning Users and Groups:
Finally, you need to grant users or groups in Okta permission to use this GitLab application:
- Go to the
Assignments
tab of the GitLab application in Okta. - Click
Assign
->Assign to People
orAssign to Groups
. - Select the users or groups who should be able to log into GitLab via SAML.
- Confirm assignments. Users not assigned here will not be able to authenticate via Okta for this application.
8. Connecting the Dots: Exchanging Metadata
Now you need to ensure both systems have the other’s information.
Providing IdP Metadata to GitLab
- Self-Managed (
gitlab.rb
):- Enter the
idp_sso_target_url
obtained from Okta (or your IdP). - Enter either the
idp_cert_fingerprint
or the fullidp_cert
obtained from Okta. - Ensure
issuer
andassertion_consumer_service_url
ingitlab.rb
match what you told Okta. - Ensure
name_identifier_format
matches Okta’s setting. - Configure
attribute_statements
to match the attributes Okta is sending. - Run
sudo gitlab-ctl reconfigure
.
- Enter the
- GitLab.com (Group Settings -> SAML SSO):
- Enter the
Identity provider single sign-on URL
obtained from Okta. - Enter the
Certificate fingerprint
obtained from Okta. - Save changes.
- Enter the
Providing GitLab (SP) Metadata to the IdP
- Find GitLab’s Metadata URL: GitLab automatically generates metadata describing its SAML configuration. The URL is typically:
- Self-Managed:
https://gitlab.example.com/users/auth/saml/metadata
(replace with your domain) - GitLab.com Group: This isn’t usually exposed as a direct metadata URL. You provide the individual values.
- Self-Managed:
- Configure the IdP (Okta Example):
- ACS URL: Ensure the
Single sign on URL
in Okta matches GitLab’s ACS URL (assertion_consumer_service_url
fromgitlab.rb
or the one shown in GitLab.com settings). - Entity ID: Ensure the
Audience URI (SP Entity ID)
in Okta matches GitLab’sissuer
(fromgitlab.rb
or the Identifier shown in GitLab.com settings). - Some IdPs allow you to upload or point to the SP metadata URL directly, which can simplify setup. Okta typically uses manual field entry.
- ACS URL: Ensure the
Double-check these URLs and identifiers carefully. Mismatches are a very common source of errors.
9. Testing and Verification
With both sides configured, it’s time to test!
- Open a New Browser/Incognito Window: This ensures you don’t have existing sessions interfering.
- Navigate to GitLab: Go to your GitLab instance URL (
https://gitlab.example.com
) or the specific group URL on GitLab.com. - Find the SAML Login Button: On the login page, you should now see the button with the label you configured (e.g., “Sign in with MyOrg SSO”). Click it.
- Redirect to IdP: You should be redirected to your IdP’s login page (Okta, Azure AD, etc.).
- Authenticate at IdP: Log in using the credentials of a user who has been assigned the GitLab application in the IdP. You might need to complete MFA if configured.
- Redirect Back to GitLab: After successful IdP authentication, the IdP should redirect you back to GitLab’s ACS URL (
/users/auth/saml/callback
). - GitLab Session Created: GitLab will process the SAML response.
- Existing User: If
omniauth_auto_link_saml_user
is true (self-managed) or by default on GitLab.com, and the email address from the SAML assertion matches an existing GitLab user’s primary email, you should be logged into that account. - New User (JIT Provisioning): If the user doesn’t exist in GitLab,
omniauth_block_auto_created_users
is false, and the required attributes (like email) were provided in the assertion, GitLab should create a new account and log you in. If blocking is enabled, the account is created but blocked. - Login Failed: If something went wrong, you might see a GitLab error page (e.g., 404, 422, 500) or an error message from the IdP. Proceed to troubleshooting.
- Existing User: If
- Verify Access: Once logged in, check if you landed on the expected GitLab dashboard.
- Verify User Profile (Optional): Go to your GitLab user profile settings. Check if the name and email address were populated correctly from the SAML assertion based on your attribute mappings.
- Test with Different Users: Test with both existing GitLab users (to check linking) and users who only exist in the IdP (to check provisioning). Test with a user who is not assigned the application in the IdP to ensure they are correctly denied access.
- Test Group Sync (If configured): If you set up SAML Group Links, verify that users are automatically added to the correct GitLab groups based on their IdP group memberships after logging in via SAML.
10. Advanced Configuration and Features
Beyond basic login, SAML integration with GitLab offers powerful features:
Just-in-Time (JIT) Provisioning
- What it is: Automatically creates a GitLab user account the first time a user successfully logs in via SAML, if they don’t already have an account.
- Configuration:
- Enabled by default when SAML is configured.
- Requires the IdP to send necessary attributes defined in
attribute_statements
(at minimumemail
, oftenname
,first_name
,last_name
). - Control immediate access using
omniauth_block_auto_created_users
(true
= requires admin approval,false
= immediate access).
- Benefit: Simplifies onboarding – no need to pre-create GitLab accounts manually.
SAML Group Links / Group Sync (Premium/Ultimate)
- What it is: Automatically manages membership in GitLab Groups based on a user’s group memberships in the IdP. When a user logs in via SAML, GitLab checks the groups sent in the designated
groups_attribute
from the assertion. If a received group name matches a configured SAML Group Link in a GitLab Group, the user is added to that GitLab Group with a specified role. Membership is typically re-evaluated on each SAML login. - Configuration:
gitlab.rb
(Self-Managed): Define thegroups_attribute
within theargs.attribute_statements
section, specifying the SAML attribute name your IdP uses to send group memberships (e.g.,groups_attribute: 'groups'
). Rungitlab-ctl reconfigure
.- GitLab Group Settings: Navigate to the desired GitLab Group -> Settings -> SAML Group Links.
- Click
Add SAML Group Link
. - Enter the exact name of the IdP group as it appears in the SAML assertion’s
groups_attribute
. - Select the Access Level (Guest, Reporter, Developer, Maintainer, Owner) the user should receive in this GitLab Group if they are a member of the corresponding IdP group.
- Save the link. Create multiple links for different IdP groups mapped to this GitLab group or other groups.
- Benefit: Automates GitLab group permissions based on centralized IdP group management. Ensures users have appropriate access based on their roles defined in the directory. Greatly simplifies access management in large organizations.
Required Groups (Premium/Ultimate)
- What it is: Restricts SAML login only to users who are members of specific IdP groups.
- Configuration (
gitlab.rb
only): Add therequired_groups: ['group-a', 'group-b']
array within theargs
section. The values must be the exact names of the IdP groups sent in thegroups_attribute
. - Behavior: If a user authenticates successfully at the IdP but is not a member of any group listed in
required_groups
(as reported by the IdP via thegroups_attribute
), their GitLab SAML login will be denied. - Benefit: Provides an extra layer of authorization, ensuring only relevant personnel can access the GitLab instance via SAML, even if they have an account in the IdP.
Session Duration and Timeouts
- GitLab Session: By default, GitLab user sessions have their own duration (configurable in Admin Area -> Settings -> Preferences).
- SAML Session: The IdP also manages its own session. A user might stay logged into the IdP for hours or days.
- Interaction: If the GitLab session expires but the IdP session is still active, clicking the SAML login button should seamlessly log the user back into GitLab without requiring password entry again (as the IdP confirms the active session).
allowed_clock_drift
: Configurable ingitlab.rb
. Defines the maximum allowed time difference (in seconds) between the IdP and SP server clocks for SAML assertions to be considered valid. Default is usually sufficient, but adjust if you see errors related to assertion timestamps (NotBefore
,NotOnOrAfter
). Ensure servers use NTP.session_duration
: (Less commonly used for SAML directly, more IdP controlled) Potentially influences how long the IdP assertion is considered valid by GitLab.
Customizing Attribute Mappings
- Review the
attribute_statements
ingitlab.rb
carefully. Ensure you are mapping all desired attributes (likeusername
/nickname
if needed) using the correct attribute names sent by your IdP. Use SAML tracer tools to inspect the assertion and confirm the names and values being sent.
Single Logout (SLO)
- What it is: A mechanism where logging out of one application (either GitLab or the IdP) triggers logout from all other applications connected via the SAML session.
- Configuration: More complex. Requires both IdP and SP (GitLab) to support SLO and exchange SLO endpoint URLs and potentially signing certificates for logout messages. Configuration involves settings like
idp_slo_target_url
ingitlab.rb
and corresponding settings in the IdP. - Note: SLO implementation can be tricky and depends heavily on IdP capabilities and specific configuration. It’s often considered an advanced setup.
11. Troubleshooting Common SAML Issues
SAML configuration can be finicky. Here’s how to diagnose problems:
Tools
- SAML Tracer Browser Extensions: Essential! Install extensions like “SAML-tracer” (Firefox) or “SAML Chrome Panel” (Chrome). These intercept the SAML Request and Response as they pass through the browser, allowing you to inspect the XML content in detail. You can see:
- The exact
AuthnRequest
GitLab sends. - The exact
Response
andAssertion
the IdP sends back. - Destination URLs, Issuer values, Audience Restrictions, NameID format and value, Attribute Statements (names and values), Conditions (timestamps), and Signature status.
- This is often the fastest way to spot mismatches in URLs, IDs, formats, or missing attributes.
- The exact
- GitLab Production Logs (Self-Managed): Check the main Rails application log:
sudo gitlab-rails 'production.log'
orsudo tail -f /var/log/gitlab/gitlab-rails/production.log
- Look for entries related to OmniAuth, SAML, and the timestamp around the failed login attempt. Error messages here can provide specific clues (e.g., “Could not authenticate you from Saml because ‘Invalid ticket'”, “Fingerprint mismatch”, attribute processing errors).
- IdP Logs: Check the system or application logs within your IdP. They often record successful and failed login attempts, including reasons for failure (e.g., user not assigned, invalid SP configuration).
Common Errors and Solutions
- Error:
Invalid Signature
/Digest mismatch
/Certificate invalid
- Cause: The IdP certificate configured in GitLab (
idp_cert
oridp_cert_fingerprint
) doesn’t match the certificate the IdP actually used to sign the response. This can happen if the IdP rotated its certificate. - Solution: Obtain the current signing certificate (or its SHA1 fingerprint) from the IdP and update the configuration in
gitlab.rb
or GitLab.com settings. Ensure you have the correct certificate (signing vs. encryption if applicable). Runreconfigure
if self-managed.
- Cause: The IdP certificate configured in GitLab (
- Error:
Invalid Audience
/Audience Restriction Condition Error
- Cause: The
Audience
value within the SAML Assertion’sConditions
doesn’t exactly match theissuer
value configured in GitLab (gitlab.rb
or GitLab.com Identifier). - Solution: Ensure the “Audience URI (SP Entity ID)” configured in the IdP exactly matches GitLab’s
issuer
value. Check for typos, HTTP vs. HTTPS mismatches, or trailing slashes.
- Cause: The
- Error:
Invalid Destination
- Cause: The
Destination
attribute in the SAML Response (usually at the top level) doesn’t exactly match GitLab’sassertion_consumer_service_url
. - Solution: Ensure the “Single sign on URL” (or ACS URL) configured in the IdP exactly matches GitLab’s ACS URL (
https://gitlab.example.com/users/auth/saml/callback
or the GitLab.com group equivalent). Check for typos, HTTP vs. HTTPS, etc.
- Cause: The
- Error:
NameID not found
/Invalid NameID Policy
/NameID format incorrect
- Cause: Mismatch in the
NameID
configuration. Either the IdP isn’t sending aNameID
in the expected format, or GitLab is requesting a format the IdP doesn’t support or isn’t configured to send for this application. - Solution: Verify that the
name_identifier_format
ingitlab.rb
(or the implicit expectation on GitLab.com) matches the Name ID format selected in the IdP configuration. Also, check that the “Application username” or equivalent setting in the IdP is configured correctly to provide the NameID value (e.g., mapping it to the user’s email).
- Cause: Mismatch in the
- Error (on IdP page):
User Not Found
/Access Denied
/User not assigned to application
- Cause: The user trying to log in has not been granted access to the GitLab SAML application within the IdP itself.
- Solution: Check the application assignments in the IdP (e.g., the
Assignments
tab in Okta) and ensure the user (or a group they belong to) is assigned.
- Error:
Clock Skew Error
/Assertion expired
/Conditions not valid
- Cause: The time difference between the IdP server and the GitLab server is greater than the allowed tolerance (
allowed_clock_drift
, often defaults to a few seconds or minutes). SAML assertions have strict validity periods (NotBefore
,NotOnOrAfter
). - Solution: Ensure both the IdP server(s) and the GitLab server(s) are synchronized to a reliable time source using NTP (Network Time Protocol). If NTP is correctly configured, you might need to slightly increase
allowed_clock_drift
ingitlab.rb
(use cautiously), but fixing the time sync is the better solution.
- Cause: The time difference between the IdP server and the GitLab server is greater than the allowed tolerance (
- Error: JIT Provisioning Fails / User created with missing info
- Cause: The IdP is not sending all the required attributes specified in GitLab’s
attribute_statements
, particularlyemail
. - Solution: Use a SAML tracer to verify the attributes being sent in the assertion. Check the IdP’s attribute mapping configuration to ensure it’s correctly configured to send attributes like
email
,firstName
,lastName
with the exact names GitLab expects.
- Cause: The IdP is not sending all the required attributes specified in GitLab’s
- Error: GitLab
500 Internal Server Error
after redirect from IdP- Cause: A server-side error occurred within GitLab while processing the SAML response. This could be due to various reasons like incorrect configuration parsing in
gitlab.rb
, database issues, problems with user creation/linking logic, or bugs. - Solution: Immediately check the GitLab production logs (
/var/log/gitlab/gitlab-rails/production.log
) for detailed error messages and stack traces around the time of the failure. These logs will provide the specific reason for the 500 error.
- Cause: A server-side error occurred within GitLab while processing the SAML response. This could be due to various reasons like incorrect configuration parsing in
- Error:
User has already been taken
/ Email conflict during linking- Cause: A user tries to log in via SAML, and their email address matches an existing GitLab account, but
omniauth_auto_link_saml_user
might be false, or there’s another conflict preventing automatic linking (e.g., the existing account already linked to a different identity). - Solution: Ensure
omniauth_auto_link_saml_user = true
ingitlab.rb
(if self-managed). Investigate the existing GitLab account – check its primary email and if it has any existing external identities linked under Profile -> Account -> Social sign-in. Manual intervention by an admin might be needed to resolve conflicts.
- Cause: A user tries to log in via SAML, and their email address matches an existing GitLab account, but
12. Security Considerations
While SAML enhances security, keep these points in mind:
- Secure Your IdP: The IdP becomes the central point of authentication. Its security is paramount. Enforce strong password policies, mandate Multi-Factor Authentication (MFA), and utilize any conditional access policies your IdP offers.
- Use HTTPS Everywhere: Ensure both your GitLab instance and your IdP endpoints use HTTPS to encrypt traffic, including the SAML messages exchanged via the browser.
- Certificate Management: SAML relies on certificates for signing. These certificates expire. Have a plan and process for rotating the IdP signing certificate before it expires and updating the new certificate/fingerprint in GitLab to avoid service disruption. Monitor certificate expiration dates.
- Audit Regularly: Periodically review who has access to the GitLab application in the IdP. Audit SAML Group Links in GitLab to ensure correct permissions are maintained. Review IdP and GitLab logs for suspicious activity.
- Understand
block_auto_created_users
: Decide carefully whether you want JIT-provisioned users to gain immediate access (false
) or require admin approval (true
). The latter provides more control but adds administrative overhead. - Enforce SSO (Carefully!): GitLab.com allows enforcing SAML SSO for group access. Self-managed instances can achieve similar effects by disabling other sign-in methods or using
required_groups
. Before enforcing SSO, ensure all necessary users (including administrators) can log in via SAML, and consider having a backup administrator account with a password for emergencies (though this bypasses SSO enforcement). Understand the implications for Git access via SSH/HTTPS tokens.
13. Conclusion
Configuring SAML Single Sign-On for GitLab is a significant step towards streamlining user access, improving security, and simplifying administration. While the initial setup involves careful coordination between your Identity Provider and GitLab, the long-term benefits are substantial.
By understanding the core SAML concepts – IdP, SP, Assertions, Metadata, Bindings – and meticulously following the configuration steps for both GitLab (gitlab.rb
for self-managed or Group Settings for GitLab.com) and your chosen IdP, you can establish a robust and seamless authentication flow. Remember to pay close attention to detail, especially with URLs, Entity IDs, certificate fingerprints, and attribute mapping names.
Leveraging features like Just-in-Time provisioning and SAML Group Sync further automates user lifecycle management and permission handling, integrating GitLab deeply into your organization’s identity infrastructure.
Don’t be discouraged if you encounter issues during setup. Use troubleshooting tools like SAML tracers and logs systematically to diagnose problems. With patience and attention to detail, you can successfully implement SAML SSO and provide your users with a secure and efficient way to access GitLab. This investment pays dividends in improved security posture, user satisfaction, and administrative efficiency for your DevOps platform.