Geo with Single Sign On (SSO)
This documentation only discusses Geo-specific SSO considerations and configuration. For more information on general authentication, see GitLab authentication and authorization.
Configuring instance-wide SAML
Prerequisites
Instance-wide SAML must be working on your primary Geo site.
You only configure SAML on the primary site. Configuring gitlab_rails['omniauth_providers']
in gitlab.rb
in a secondary site has no effect. The secondary site authenticates against the SAML provider configured on the primary site. Depending on the URL type of the secondary site, additional configuration might be needed on the primary site.
Determine the type of URL your secondary site uses
How you configure instance-wide SAML differs depending on your secondary site configuration. Determine if your secondary site uses a:
-
Unified URL, meaning the
external_url
exactly matches theexternal_url
of the primary site. - Separate URL with proxying enabled. Proxying is enabled by default in GitLab 15.1 and later.
- Separate URL with proxying disabled.
SAML with Unified URL
If you have configured SAML on the primary site correctly, then it should work on the secondary site without additional configuration.
SAML with separate URL with proxying enabled
If a secondary site uses a different external_url
to the primary site, then configure your SAML Identity Provider (IdP) to allow the secondary site’s SAML callback URL. For example, to configure Okta:
- Sign in to Okta.
- Go to Okta Admin Dashboard > Applications > Your App Name > General.
- In SAML Settings, select Edit.
- In General Settings, select Next to go to SAML Settings.
- In SAML Settings > General, make sure the Single sign-on URL is your primary site’s SAML callback URL. For example,
https://gitlab-primary.example.com/users/auth/saml/callback
. If it is not, enter your primary site’s SAML callback URL into this field. - Select Show Advanced Settings.
- In Other Requestable SSO URLs, enter your secondary site’s SAML callback URL. For example,
https://gitlab-secondary.example.com/users/auth/saml/callback
. You can set Index to anything. - Select Next and then Finish.
You must not specify assertion_consumer_service_url
in the SAML provider configuration in gitlab_rails['omniauth_providers']
in gitlab.rb
of the primary site. For example:
gitlab_rails['omniauth_providers'] = [
{
name: "saml",
label: "Okta", # optional label for login button, defaults to "Saml"
args: {
idp_cert_fingerprint: "B5:AD:AA:9E:3C:05:68:AD:3B:78:ED:31:99:96:96:43:9E:6D:79:96",
idp_sso_target_url: "https://<dev-account>.okta.com/app/dev-account_gitlabprimary_1/exk7k2gft2VFpVFXa5d1/sso/saml",
issuer: "https://<gitlab-primary>",
name_identifier_format: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
}
}
]
This configuration causes:
- Both your sites to use
/users/auth/saml/callback
as their assertion consumer service (ACS) URL. - The URL’s host to be set to the corresponding site’s host.
You can check this by visiting each site’s /users/auth/saml/metadata
path. For example, visiting https://gitlab-primary.example.com/users/auth/saml/metadata
may respond with:
<md:EntityDescriptor ID="_b9e00d84-d34e-4e3d-95de-122e3c361617" entityID="https://gitlab-primary.example.com"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://gitlab-primary.example.com/users/auth/saml/callback" index="0" isDefault="true"/>
<md:AttributeConsumingService index="1" isDefault="true">
<md:ServiceName xml:lang="en">Required attributes</md:ServiceName>
<md:RequestedAttribute FriendlyName="Email address" Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="false"/>
<md:RequestedAttribute FriendlyName="Full name" Name="name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="false"/>
<md:RequestedAttribute FriendlyName="Given name" Name="first_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="false"/>
<md:RequestedAttribute FriendlyName="Family name" Name="last_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="false"/>
</md:AttributeConsumingService>
</md:SPSSODescriptor>
</md:EntityDescriptor>
Visiting https://gitlab-secondary.example.com/users/auth/saml/metadata
may respond with:
<md:EntityDescriptor ID="_bf71eb57-7490-4024-bfe2-54cec716d4bf" entityID="https://gitlab-primary.example.com"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://gitlab-secondary.example.com/users/auth/saml/callback" index="0" isDefault="true"/>
<md:AttributeConsumingService index="1" isDefault="true">
<md:ServiceName xml:lang="en">Required attributes</md:ServiceName>
<md:RequestedAttribute FriendlyName="Email address" Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="false"/>
<md:RequestedAttribute FriendlyName="Full name" Name="name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="false"/>
<md:RequestedAttribute FriendlyName="Given name" Name="first_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="false"/>
<md:RequestedAttribute FriendlyName="Family name" Name="last_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="false"/>
</md:AttributeConsumingService>
</md:SPSSODescriptor>
</md:EntityDescriptor>
The Location
attribute of the md:AssertionConsumerService
field points to gitlab-secondary.example.com
.
After configuring your SAML IdP to allow the secondary site’s SAML callback URL, you should be able to sign in with SAML on your primary site as well as your secondary site.
SAML with separate URL with proxying disabled
If you have configured SAML on the primary site correctly, then it should work on the secondary site without additional configuration.
OpenID Connect
If you use an OpenID Connect (OIDC) OmniAuth provider, in most cases, it should work without an issue:
- OIDC with Unified URL: If you have configured OIDC on the primary site correctly, then it should work on the secondary site without additional configuration.
- OIDC with separate URL with proxying disabled: If you have configured OIDC on the primary site correctly, then it should work on the secondary site without additional configuration.
- OIDC with separate URL with proxying enabled: Geo with separate URL with proxying enabled does not support OpenID Connect. For more information, see issue 396745.
LDAP
If you use LDAP on your primary site, you should also set up secondary LDAP servers on each secondary site. Otherwise, users cannot perform Git operations over HTTP(s) on the secondary site using HTTP basic authentication. However, users can still use Git with SSH and personal access tokens.
Check your LDAP service documentation for instructions on how to set up replication in your LDAP service. The process differs depending on the software or service used. For example, OpenLDAP provides this replication documentation.