SAML OmniAuth Provider

This page describes instance-wide SAML for self-managed GitLab instances. For SAML on GitLab.com, see SAML SSO for GitLab.com groups.

You should also reference the OmniAuth documentation for general settings that apply to all OmniAuth providers.

Glossary of common terms

Term Description
Identity provider (IdP) The service which manages your user identities, such as Okta or OneLogin.
Service provider (SP) GitLab can be configured as a SAML 2.0 SP.
Assertion A piece of information about a user’s identity, such as their name or role. Also known as claims or attributes.
Single Sign-On (SSO) Name of authentication scheme.
Assertion consumer service URL The callback on GitLab where users are redirected after successfully authenticating with the identity provider.
Issuer How GitLab identifies itself to the identity provider. Also known as a “Relying party trust identifier”.
Certificate fingerprint Used to confirm that communications over SAML are secure by checking that the server is signing communications with the correct certificate. Also known as a certificate thumbprint.

General Setup

GitLab can be configured to act as a SAML 2.0 Service Provider (SP). This allows GitLab to consume assertions from a SAML 2.0 Identity Provider (IdP), such as Okta to authenticate users.

First configure SAML 2.0 support in GitLab, then register the GitLab application in your SAML IdP:

  1. Make sure GitLab is configured with HTTPS. See Using HTTPS for instructions.

  2. On your GitLab server, open the configuration file.

    For Omnibus package:

    sudo editor /etc/gitlab/gitlab.rb
    

    For installations from source:

    cd /home/git/gitlab
    
    sudo -u git -H editor config/gitlab.yml
    
  3. See Configure initial settings for initial settings.
  4. To allow your users to use SAML to sign up without having to manually create an account first, add the following values to your configuration:

    For Omnibus package:

    gitlab_rails['omniauth_allow_single_sign_on'] = ['saml']
    gitlab_rails['omniauth_block_auto_created_users'] = false
    

    For installations from source:

    omniauth:
      enabled: true
      allow_single_sign_on: ["saml"]
      block_auto_created_users: false
    
  5. You can also automatically link SAML users with existing GitLab users if their email addresses match by adding the following setting:

    For Omnibus package:

    gitlab_rails['omniauth_auto_link_saml_user'] = true
    

    For installations from source:

    auto_link_saml_user: true
    
  6. Ensure that the SAML NameID and email address are fixed for each user, as described in the section on Security. Otherwise, your users are able to sign in as other authorized users.

  7. Add the provider configuration:

    For Omnibus package:

    gitlab_rails['omniauth_providers'] = [
      {
        name: "saml",
        label: "Provider name", # optional label for login button, defaults to "Saml"
        args: {
          assertion_consumer_service_url: "https://gitlab.example.com/users/auth/saml/callback",
          idp_cert_fingerprint: "43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8",
          idp_sso_target_url: "https://login.example.com/idp",
          issuer: "https://gitlab.example.com",
          name_identifier_format: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
        }
      }
    ]
    

    For installations from source:

    omniauth:
      providers:
        - {
          name: 'saml',
          label: 'Provider name', # optional label for login button, defaults to "Saml"
          args: {
            assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
            idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
            idp_sso_target_url: 'https://login.example.com/idp',
            issuer: 'https://gitlab.example.com',
            name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
          }
        }
    
  8. Change the value for assertion_consumer_service_url to match the HTTPS endpoint of GitLab (append users/auth/saml/callback to the HTTPS URL of your GitLab installation to generate the correct value).

  9. Change the values of idp_cert_fingerprint, idp_sso_target_url, name_identifier_format to match your IdP. If a fingerprint is used it must be a SHA1 fingerprint; check the OmniAuth SAML documentation for more details on these options. See the notes on configuring your identity provider for more information.

  10. Change the value of issuer to a unique name, which identifies the application to the IdP.

  11. For the changes to take effect, you must reconfigure GitLab if you installed via Omnibus or restart GitLab if you installed from source.

  12. Register the GitLab SP in your SAML 2.0 IdP, using the application name specified in issuer.

To ease configuration, most IdP accept a metadata URL for the application to provide configuration information to the IdP. To build the metadata URL for GitLab, append users/auth/saml/metadata to the HTTPS URL of your GitLab installation, for instance:

https://gitlab.example.com/users/auth/saml/metadata

At a minimum the IdP must provide a claim containing the user’s email address using email or mail. See the assertions list for other available claims.

On the sign in page there should now be a SAML button below the regular sign in form. Select the icon to begin the authentication process. If everything goes well the user is returned to GitLab and signed in.

Use multiple SAML identity providers

Introduced in GitLab 14.6.

You can configure GitLab to use multiple SAML identity providers if:

  • Each provider has a unique name set that matches a name set in args.
  • The providers’ names are:
    • Used in OmniAuth configuration for properties based on the provider name. For example, allowBypassTwoFactor, allowSingleSignOn, and syncProfileFromProvider.
    • Used for association to each existing user as an additional identity.
  • The assertion_consumer_service_url matches the provider name.
  • The strategy_class is explicitly set because it cannot be inferred from provider name.

Example multiple providers configuration for Omnibus GitLab:

gitlab_rails['omniauth_providers'] = [
  {
    name: 'saml_1',
    args: {
            name: 'saml_1', # This is mandatory and must match the provider name
            strategy_class: 'OmniAuth::Strategies::SAML',
            assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_1/callback', # URL must match the name of the provider
            ... # Put here all the required arguments similar to a single provider
          },
    label: 'Provider 1' # Differentiate the two buttons and providers in the UI
  },
  {
    name: 'saml_2',
    args: {
            name: 'saml_2', # This is mandatory and must match the provider name
            strategy_class: 'OmniAuth::Strategies::SAML',
            assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_2/callback', # URL must match the name of the provider
            ... # Put here all the required arguments similar to a single provider
          },
    label: 'Provider 2' # Differentiate the two buttons and providers in the UI
  }
]

Example providers configuration for installations from source:

omniauth:
  providers:
    - {
      name: 'saml_1',
      args: {
        name: 'saml_1', # This is mandatory and must match the provider name
        strategy_class: 'OmniAuth::Strategies::SAML',
        assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_1/callback', # URL must match the name of the provider
        ... # Put here all the required arguments similar to a single provider
      },
      label: 'Provider 1' # Differentiate the two buttons and providers in the UI
    }
    - {
      name: 'saml_2',
      args: {
        name: 'saml_2', # This is mandatory and must match the provider name
        strategy_class: 'OmniAuth::Strategies::SAML',
        assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_2/callback', # URL must match the name of the provider
        ... # Put here all the required arguments similar to a single provider
      },
      label: 'Provider 2' # Differentiate the two buttons and providers in the UI
    }