Integrations · OIDC
GitLab SSO
Enable OpenID Connect SSO for GitLab Self-Managed. Users authenticate via Clavex; group claims automatically assign GitLab roles and group memberships. Works with GitLab CE and EE ≥ 14.0.
GitLab.com vs Self-Managed: This guide covers GitLab Self-Managed.
For GitLab.com group SSO (available on Premium/Ultimate), the configuration is in
Group Settings → SAML SSO and uses a different flow.
Prerequisites
- GitLab Self-Managed ≥ 14.0 with shell or Omnibus access
- GitLab admin account
- Clavex at
https://id.acme.eu, org slugacme
Step 1 — Register OIDC Client in Clavex
$ curl -X POST https://id.acme.eu/api/v1/organizations/acme/clients \
-H 'Authorization: Bearer $ADMIN_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"client_id": "gitlab",
"client_name": "GitLab",
"grant_types": ["authorization_code", "refresh_token"],
"redirect_uris": ["https://gitlab.acme.eu/users/auth/openid_connect/callback"],
"scopes": ["openid", "profile", "email", "groups"],
"token_endpoint_auth_method": "client_secret_basic"
}'
Step 2 — Configure GitLab Omnibus
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_auto_link_user'] = ['openid_connect']
gitlab_rails['omniauth_providers'] = [ { name: "openid_connect", label: "Clavex", icon: nil, args: { name: "openid_connect", scope: ["openid", "profile", "email", "groups"], response_type: "code", issuer: "https://id.acme.eu/acme", discovery: true, client_auth_method: "basic", uid_field: "sub", send_scope_to_token_endpoint: true, pkce: true, client_options: { identifier: "gitlab", secret: "cs_xxxxxxxxxxxxxxxx", redirect_uri: "https://gitlab.acme.eu/users/auth/openid_connect/callback" } } } ]
gitlab_rails['omniauth_providers'] = [ { name: "openid_connect", label: "Clavex", icon: nil, args: { name: "openid_connect", scope: ["openid", "profile", "email", "groups"], response_type: "code", issuer: "https://id.acme.eu/acme", discovery: true, client_auth_method: "basic", uid_field: "sub", send_scope_to_token_endpoint: true, pkce: true, client_options: { identifier: "gitlab", secret: "cs_xxxxxxxxxxxxxxxx", redirect_uri: "https://gitlab.acme.eu/users/auth/openid_connect/callback" } } } ]
$ gitlab-ctl reconfigure
$ gitlab-ctl restart
Step 3 — Configure GitLab Helm Chart (Kubernetes)
Add to your values.yaml:
global:
appConfig:
omniauth:
enabled: true
allowSingleSignOn: ["openid_connect"]
blockAutoCreatedUsers: false
providers:
- secret: gitlab-clavex-oidc
key: provider
Store the OIDC provider JSON in a Kubernetes secret
gitlab-clavex-oidc
with key provider containing the full provider config block as a JSON string.
Group Sync (EE only)
GitLab EE can sync SAML groups, but for OIDC the group claim maps to GitLab roles
via Admin Area → Settings → General → Sign-in restrictions → Trusted OIDC providers.
Use the groups claim to set GitLab admin status:
# Grant GitLab admin if user is in "gitlab-admins" group in Clavex
gitlab_rails['omniauth_external_providers'] = []
gitlab_rails['omniauth_admin_groups'] = ['gitlab-admins']
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Button "Sign in with Clavex" not shown | OmniAuth not enabled or config syntax error | Run gitlab-ctl tail and look for Ruby errors; verify gitlab.rb |
Could not authenticate you from OpenIDConnect |
Discovery URL unreachable from GitLab server | Check that GitLab can reach https://id.acme.eu/acme/.well-known/openid-configuration |
| User already exists error | Email already linked to another auth provider | Enable omniauth_auto_link_user: ['openid_connect'] or merge accounts via Admin UI |
| Invalid state / CSRF token | Session cookie issue or clock skew | Ensure Clavex and GitLab clocks are synchronized; check cookie domain settings |