GitLab SSO with Keycloak using OIDC
Configure Keycloak SSO for GitLab using the built-in openid_connect OmniAuth provider. Covers confidential client setup, gitlab.rb configuration, and access control by Keycloak group membership.
KeycloakPro Team
KeycloakPro Team
Introduction
GitLab ships with an openid_connect OmniAuth provider in every edition, Community through Ultimate. No extra plugins needed. You configure it in /etc/gitlab/gitlab.rb, run gitlab-ctl reconfigure, and GitLab handles account provisioning automatically.
This guide covers GitLab 16+ (Omnibus) with Keycloak 24+. If you run GitLab via Helm chart, the same Ruby hash goes into global.appConfig.omniauth.providers in values.yaml.
Prerequisites
- Keycloak 24+ with HTTPS
- GitLab 16+ (Omnibus) with admin access
- GitLab running on HTTPS
Step 1 — Create the Keycloak confidential client
In the Keycloak admin console:
- Clients → Create client
- Client type:
OpenID Connect - Client ID:
gitlab - Click Next
Capability config:
- Client authentication: ON (confidential client)
- Standard flow: ON
- Direct access grants: OFF
- Click Next
Login settings:
- Root URL:
https://gitlab.example.com - 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

1.1 — Copy the client secret
Clients → gitlab → Credentials → copy the client secret. You need this in Step 2.

1.2 — Add a groups mapper (optional)
Skip this if you only need basic SSO login. Come back here if you want to restrict GitLab access to users in specific Keycloak groups.
- Clients → gitlab → Client scopes → gitlab-dedicated → Add mapper → By configuration
- Select Group Membership
- Name:
groups - Token Claim Name:
groups - Full group path: OFF
- Add to ID token: ON
- Save

Step 2 — Configure gitlab.rb
On the GitLab server, edit /etc/gitlab/gitlab.rb:
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['openid_connect']
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
label: "Keycloak",
args: {
name: "openid_connect",
scope: ["openid", "profile", "email"],
response_type: "code",
issuer: "https://keycloak.example.com/realms/YOUR_REALM",
discovery: true,
client_auth_method: "query",
uid_field: "preferred_username",
send_scope_to_token_endpoint: "false",
pkce: true,
client_options: {
identifier: "gitlab",
secret: "<paste-from-step-1.1>",
redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
}
}
}
]
Replace YOUR_REALM with your realm name and keycloak.example.com with your Keycloak hostname.
omniauth_block_auto_created_users = false lets any Keycloak user sign in and get a GitLab account created automatically. Set it to true if you want an admin to manually activate each new user first.
2.1 — Restrict to specific Keycloak groups (optional)
To allow only members of specific Keycloak groups, add required_groups to the args hash. Step 1.2 must be complete first.
args: {
# ... existing args ...
required_groups: ["gitlab-users"],
}
Users in the gitlab-users Keycloak group can sign in. Everyone else gets an error at the callback step.
Step 3 — Reconfigure and restart GitLab
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
reconfigure reprocesses gitlab.rb and regenerates config files. restart applies any service changes. Both take about 30-60 seconds on a standard VM.
Step 4 — Test the login
Open a private browser window and go to https://gitlab.example.com. A Sign in with Keycloak button appears on the login page.

Click the button. Keycloak handles authentication:

After login, GitLab provisions the account from the Keycloak token and shows the dashboard:

Troubleshooting common issues
"Could not authenticate you from OpenidConnect" error
This usually means the redirect URI doesn't match. Check the URI GitLab sends by looking at Keycloak's server logs, then compare it to Valid redirect URIs on the client. A missing trailing slash or an HTTP/HTTPS mismatch will trigger this.
Login button appears but clicking it returns a 404
GitLab's callback path is /users/auth/openid_connect/callback. If your instance uses a relative URL root (e.g., https://example.com/gitlab), the full callback path changes. Update both the Keycloak redirect URI and the redirect_uri in gitlab.rb to match.
discovery: true fails with a certificate error
GitLab's Ruby process fetches the Keycloak discovery document during reconfigure. If Keycloak uses a private CA, add that CA certificate to the OS store on the GitLab server and run update-ca-certificates before gitlab-ctl reconfigure.
uid_field: "preferred_username" links the wrong account
The uid_field determines which claim GitLab uses as the external user identifier. If users already have accounts where email is the UID and you switch to preferred_username, their identities break. Pick one field and never change it after users have logged in.
required_groups blocks everyone even after adding them to the group
The groups mapper (Step 1.2) must be configured before testing required_groups. Without the mapper, the groups claim is absent from the token and GitLab treats every user as not matching any required group.
Production checklist
- HTTPS on both GitLab and Keycloak
- Client secret stored as an environment variable or in a secrets manager, not in
gitlab.rbcommitted to version control -
uid_fieldis consistent — never change it after users have logged in -
omniauth_block_auto_created_usersset deliberately -
required_groupstested before going live if access restriction is needed - Direct access grants disabled on the Keycloak client
-
gitlab-ctl reconfiguretested on a staging instance before production
Need help integrating GitLab with Keycloak?
We deliver production-ready GitLab + Keycloak integrations in 1–3 weeks.
Fixed-price, zero vendor lock-in, full source code ownership.