Set up single sign-on (SSO) authentication between GitLab and Keycloak using SAML 2.0 protocol. This enables centralized user management and secure authentication for your GitLab instance through your existing identity provider infrastructure.
Prerequisites
- Existing GitLab installation with admin access
- Running Keycloak instance with admin access
- SSL certificates for both services
- Network connectivity between GitLab and Keycloak
What this solves
Enterprise organizations need centralized authentication to manage user access across multiple applications. This tutorial configures GitLab to authenticate users through Keycloak using SAML 2.0, enabling single sign-on and centralized user management. You'll eliminate the need for separate GitLab accounts while maintaining security and compliance requirements.
Step-by-step configuration
Install required packages
Install XML processing libraries required for SAML authentication on your GitLab server.
sudo apt update
sudo apt install -y libxml2-dev libxslt1-dev
Create Keycloak SAML client
Log into your Keycloak admin console and create a new SAML client for GitLab authentication.
Navigate to your realm, go to Clients, and click "Create client". Configure the following settings:
- Client type: SAML
- Client ID: https://gitlab.example.com
- Name: GitLab SAML
- Root URL: https://gitlab.example.com
Configure Keycloak client settings
Set the SAML client configuration for proper GitLab integration in the client Settings tab.
Valid redirect URIs: https://gitlab.example.com/users/auth/saml/callback
Master SAML Processing URL: https://gitlab.example.com/users/auth/saml/callback
IDP Initiated SSO URL Name: gitlab
Name ID Format: email
Force Name ID Format: ON
Client Signature Required: OFF
Force POST Binding: ON
Front Channel Logout: ON
Force Name ID Format: ON
Configure SAML attribute mappings
Create client mappers to send required user attributes to GitLab in the Client Scopes tab.
Add the following mappers in the "Dedicated" scope for your GitLab client:
Name: email
Mapper Type: User Attribute
User Attribute: email
SAML Attribute Name: email
SAML Attribute NameFormat: Basic
Name: first_name
Mapper Type: User Attribute
User Attribute: firstName
SAML Attribute Name: first_name
SAML Attribute NameFormat: Basic
Name: last_name
Mapper Type: User Attribute
User Attribute: lastName
SAML Attribute Name: last_name
SAML Attribute NameFormat: Basic
Name: name
Mapper Type: User Attribute
User Attribute: username
SAML Attribute Name: name
SAML Attribute NameFormat: Basic
Download Keycloak SAML metadata
Export the SAML descriptor from Keycloak to configure GitLab's identity provider settings.
In your Keycloak realm, go to Realm Settings > General > Endpoints and download the SAML 2.0 Identity Provider Metadata. Save this as keycloak-metadata.xml on your GitLab server.
curl -o /etc/gitlab/keycloak-metadata.xml https://keycloak.example.com/realms/master/protocol/saml/descriptor
Configure GitLab SAML settings
Edit the GitLab configuration file to enable SAML authentication with your Keycloak instance.
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['saml']
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_auto_link_saml_user'] = true
gitlab_rails['omniauth_providers'] = [
{
name: 'saml',
args: {
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
idp_cert_fingerprint: 'YOUR_KEYCLOAK_FINGERPRINT',
idp_sso_target_url: 'https://keycloak.example.com/realms/master/protocol/saml',
issuer: 'https://gitlab.example.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:email',
attribute_statements: {
email: ['email'],
first_name: ['first_name'],
last_name: ['last_name'],
name: ['name']
}
},
label: 'Keycloak SSO'
}
]
Get Keycloak certificate fingerprint
Extract the certificate fingerprint from your Keycloak SAML metadata for GitLab configuration.
openssl x509 -noout -fingerprint -sha1 -inform DER -in <(openssl x509 -in /etc/gitlab/keycloak-metadata.xml -outform DER) | cut -d'=' -f2 | tr -d ':'
Replace YOUR_KEYCLOAK_FINGERPRINT in the GitLab configuration with the output from this command.
Configure GitLab external URL
Ensure GitLab's external URL matches the SAML client configuration in Keycloak.
external_url 'https://gitlab.example.com'
Enable SAML group mapping
Configure automatic group assignment based on Keycloak group membership for role-based access control.
gitlab_rails['omniauth_providers'] = [
{
name: 'saml',
args: {
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
idp_cert_fingerprint: 'YOUR_KEYCLOAK_FINGERPRINT',
idp_sso_target_url: 'https://keycloak.example.com/realms/master/protocol/saml',
issuer: 'https://gitlab.example.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:email',
attribute_statements: {
email: ['email'],
first_name: ['first_name'],
last_name: ['last_name'],
name: ['name'],
groups: ['groups']
},
groups_attribute: 'groups',
external_groups: [],
admin_groups: ['gitlab-admins']
},
label: 'Keycloak SSO'
}
]
Add group mapper in Keycloak
Create a group membership mapper to send user group information to GitLab.
Name: groups
Mapper Type: Group list
Group attribute name: groups
Single Group Attribute: OFF
Full group path: OFF
SAML Attribute Name: groups
SAML Attribute NameFormat: Basic
Reconfigure GitLab
Apply the SAML configuration changes and restart GitLab services.
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
Test SAML authentication
Verify the SAML configuration by attempting to sign in through Keycloak SSO.
Navigate to your GitLab instance and click "Keycloak SSO" on the sign-in page. You should be redirected to Keycloak for authentication, then returned to GitLab upon successful login.
Configure advanced SAML settings
Enable SAML logout
Configure single logout to end sessions in both GitLab and Keycloak simultaneously.
gitlab_rails['omniauth_providers'] = [
{
name: 'saml',
args: {
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
idp_cert_fingerprint: 'YOUR_KEYCLOAK_FINGERPRINT',
idp_sso_target_url: 'https://keycloak.example.com/realms/master/protocol/saml',
idp_slo_target_url: 'https://keycloak.example.com/realms/master/protocol/saml',
slo_default_relay_state: 'https://gitlab.example.com',
issuer: 'https://gitlab.example.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:email'
},
label: 'Keycloak SSO'
}
]
Configure SAML signing
Generate signing certificates for enhanced security between GitLab and Keycloak.
sudo mkdir -p /etc/gitlab/ssl
sudo openssl req -new -x509 -days 365 -nodes -out /etc/gitlab/ssl/saml.crt -keyout /etc/gitlab/ssl/saml.key -subj "/CN=gitlab.example.com"
sudo chown gitlab-www:gitlab-www /etc/gitlab/ssl/saml.*
sudo chmod 600 /etc/gitlab/ssl/saml.key
sudo chmod 644 /etc/gitlab/ssl/saml.crt
Update GitLab SAML configuration with signing
Add certificate paths to enable request signing for additional security.
gitlab_rails['omniauth_providers'] = [
{
name: 'saml',
args: {
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
idp_cert_fingerprint: 'YOUR_KEYCLOAK_FINGERPRINT',
idp_sso_target_url: 'https://keycloak.example.com/realms/master/protocol/saml',
issuer: 'https://gitlab.example.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:email',
certificate: File.read('/etc/gitlab/ssl/saml.crt'),
private_key: File.read('/etc/gitlab/ssl/saml.key'),
security: {
authn_requests_signed: true,
want_assertions_signed: true,
embed_sign: true
}
},
label: 'Keycloak SSO'
}
]
Verify your setup
sudo gitlab-ctl status
sudo gitlab-rails console -e production
In Rails console:
User.where(provider: 'saml').count
exit
Test the complete authentication flow:
curl -I https://gitlab.example.com/users/auth/saml
curl -I https://keycloak.example.com/realms/master/protocol/saml/descriptor
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| SAML authentication fails | Incorrect certificate fingerprint | Regenerate fingerprint: openssl x509 -noout -fingerprint -sha1 |
| User attributes not mapping | Missing attribute mappers in Keycloak | Verify all required mappers are configured with correct attribute names |
| Redirect URI mismatch | GitLab external URL doesn't match Keycloak client | Ensure external_url matches client ID in Keycloak |
| Groups not syncing | Group mapper not configured | Add group list mapper in Keycloak client mappers |
| SSL certificate errors | Self-signed certificates | Add idp_cert: File.read('/path/to/cert.pem') instead of fingerprint |
| Auto-created users blocked | omniauth_block_auto_created_users is true | Set to false or pre-create users in GitLab |