This guide walks you through integrating GitLab Self-Managed (Omnibus) with Keycloak as a Single Sign-On (SSO) Identity Provider using the OpenID Connect (OIDC) protocol — so your users can log in to GitLab through Keycloak.
This document focuses purely on the integration itself. For the Keycloak installation, refer to the separate guide: Deploying Keycloak 26 in Production on AlmaLinux 9.
Placeholders used throughout this guide: Wherever you see values like
sso.example.com,gitlab.example.com, orYOUR_CLIENT_SECRET, replace them with your own actual values.
| Placeholder | Description | Example |
|---|---|---|
sso.example.com | Your Keycloak FQDN | sso.company.net |
gitlab.example.com | Your GitLab FQDN | gitlab.company.net |
YOUR_CLIENT_SECRET | The OIDC client secret from Keycloak | Copy from the Credentials tab |
YOUR_REALM | Your Keycloak realm name | internal |
Table of Contents
- Prerequisites
- Create a Realm in Keycloak
- Create a Client for GitLab
- Retrieve the Client Secret
- Verify the Realm Signature Algorithm
- Configure GitLab (gitlab.rb)
- Auto-Link Existing Accounts by Email
- Reconfigure & Test Login
- Troubleshooting
1. Prerequisites
- Keycloak is up and running, accessible over HTTPS (e.g.,
https://sso.example.com). GitLab requires OIDC Identity Providers to be accessed over HTTPS — plain HTTP is not supported. - GitLab Omnibus (Self-Managed) is installed and accessible over HTTPS (e.g.,
https://gitlab.example.com). - Admin access to the Keycloak Admin Console.
- Root/sudo access to the GitLab server for editing
/etc/gitlab/gitlab.rb.
2. Create a Realm in Keycloak
Production application clients should not be placed in the master realm — that realm is recommended only for Keycloak’s own superadmin accounts.
- Log in to
https://sso.example.com/admin/. - Click the realm dropdown in the top-left corner → Create realm.
- Enter a Realm name, for example
YOUR_REALM. - Click Create.
All subsequent steps are performed inside this realm.
NOTEIf you already have a realm set up from a previous integration (e.g., ArgoCD), you can reuse it. There is no need to create a new realm for each application — just create a new client within the existing realm.
3. Create a Client for GitLab
- Inside your realm, navigate to Clients → Create client.
- General Settings
- Client type:
OpenID Connect - Client ID:
gitlab - Click Next.
- Client type:
- Capability config
- Client authentication:
On(this makes the client confidential, generating a client secret) - Authentication flow: check Standard flow only. Leave Direct access grants, Implicit flow, and other options unchecked — Standard flow (Authorization Code) is sufficient and the most secure choice for this use case.
- Click Next, then Save.
- Client authentication:
- On the Settings page of the newly created client:
- Valid redirect URIs:
https://gitlab.example.com/users/auth/openid_connect/callback - Valid post logout redirect URIs:
https://gitlab.example.com/* - Web origins:
https://gitlab.example.com
- Valid redirect URIs:
- Click Save.
4. Retrieve the Client Secret
- Still on the
gitlabclient, open the Credentials tab. - Copy the Client secret value — this will be used in the
gitlab.rbconfiguration.
5. Verify the Realm Signature Algorithm
GitLab recommends tokens to be signed with a public-key algorithm (RS256) rather than a symmetric key (HS256), as it is more secure and easier to configure.
- Navigate to Realm settings → Tokens tab.
- Check the Default signature algorithm — ensure it is set to
RS256(this is Keycloak’s default and typically does not need to be changed).
6. Configure GitLab (gitlab.rb)
Edit the GitLab configuration file:
sudo nano /etc/gitlab/gitlab.rbAdd the following block (replace identifier and secret with the Client ID and Client Secret from steps 3–4):
gitlab_rails['omniauth_allow_single_sign_on'] = ['openid_connect']gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_providers'] = [ { name: "openid_connect", # do not change — this is the internal provider name label: "Keycloak", # the label displayed on the login button args: { name: "openid_connect", scope: ["openid", "profile", "email"], response_type: "code", issuer: "https://sso.example.com/realms/YOUR_REALM", client_auth_method: "query", discovery: true, uid_field: "preferred_username", pkce: true, client_options: { identifier: "gitlab", secret: "YOUR_CLIENT_SECRET", redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback" } } }]Key options explained:
omniauth_allow_single_sign_on— enables automatic creation of new GitLab accounts (Just-In-Time provisioning) when a user logs in through Keycloak for the first time.omniauth_block_auto_created_users— whenfalse, automatically created accounts are immediately active without requiring admin approval. Set totrueif you want a GitLab admin to manually approve every new SSO account.discovery: true— GitLab automatically fetches all OIDC endpoints (authorization, token, userinfo, jwks) fromhttps://sso.example.com/realms/YOUR_REALM/.well-known/openid-configuration, so there is no need to define them individually.pkce: true— enables PKCE (Proof Key for Code Exchange) as an additional security layer on the Authorization Code flow.uid_field: "preferred_username"— the field from the Keycloak token that GitLab uses as the unique user identifier.
7. Auto-Link Existing Accounts by Email
If there are existing GitLab users whose email addresses match those that will be used for Keycloak login, add the following line so that GitLab links to the existing account instead of creating a new one:
gitlab_rails['omniauth_auto_link_user'] = ["openid_connect"]Auto-linking matches based on email addresses that are verified on both sides. Without this line, a user with a matching email will still receive a separate, brand-new GitLab account.
8. Reconfigure & Test Login
Apply the configuration changes:
sudo gitlab-ctl reconfigureOnce complete, open the GitLab login page:
https://gitlab.example.com/users/sign_inA login button labeled Keycloak will appear below the standard login form. Click it to be redirected to the Keycloak login page, and after successful authentication, you will be redirected back to GitLab in a logged-in state.
WARNINGAfter SSO is enabled, every sign-in attempt is redirected to the OmniAuth provider, which means the standard local GitLab login will no longer be directly available from the main page. Make sure at least one OmniAuth user has administrator privileges before enabling this in production. Local login can still be accessed manually via
https://gitlab.example.com/users/sign_in?auto_sign_in=falseas an emergency fallback.
9. Troubleshooting
| Symptom | Likely Cause |
|---|---|
| Keycloak login button does not appear | gitlab-ctl reconfigure has not been run, or there is a syntax error in gitlab.rb — run sudo gitlab-ctl reconfigure and check the output for errors |
invalid_redirect_uri error from Keycloak | The redirect URI in the Keycloak client does not exactly match the one sent by GitLab (https://gitlab.example.com/users/auth/openid_connect/callback) — pay attention to trailing slashes and the http/https scheme |
| Discovery failure / GitLab cannot fetch OIDC configuration | Ensure the GitLab server can resolve DNS and make HTTPS requests to sso.example.com; test with curl https://sso.example.com/realms/YOUR_REALM/.well-known/openid-configuration from the GitLab server |
| Login succeeds at Keycloak but fails returning to GitLab / signature invalid | Check that Default signature algorithm in Realm Settings > Tokens is set to RS256, not HS256 |
| Same user logging in via SSO creates a new account instead of linking to the existing one | Add gitlab_rails['omniauth_auto_link_user'] = ["openid_connect"] as described in step 7, and ensure the email is identical and verified on both sides |
| GitLab refuses connection to Keycloak citing HTTPS | GitLab does not support OIDC Identity Providers over plain HTTP; ensure Keycloak is accessible over HTTPS (see the Keycloak deployment guide) |
Summary of the flow: create a dedicated realm in Keycloak (or reuse an existing one) → register a gitlab client with Standard Flow only → copy the client secret → add the configuration to gitlab.rb with the matching issuer, identifier, and secret → run gitlab-ctl reconfigure → test login via the Keycloak button on the GitLab sign-in page.