diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index c1c4a110aae4e61f602048e7f866f122cbd4804b..927b50245a40718dda9a788a5d2f37bd8e917bf5 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -9,7 +9,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
 
   after_action :verify_known_sign_in
 
-  protect_from_forgery except: [:saml, :cas3, :failure] + AuthHelper.saml_providers, with: :exception, prepend: true
+  protect_from_forgery except: [:cas3, :failure] + AuthHelper.saml_providers, with: :exception, prepend: true
 
   feature_category :authentication_and_authorization
 
diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb
index 6ac4a12bcd5c1a137e3b3702a9e9baebc5f61fd4..07152133402bd2520bbc7af47a7c13ee9704ff7c 100644
--- a/app/helpers/auth_helper.rb
+++ b/app/helpers/auth_helper.rb
@@ -91,7 +91,9 @@ def form_based_providers
   end
 
   def saml_providers
-    auth_providers.select { |provider| auth_strategy_class(provider) == 'OmniAuth::Strategies::SAML' }
+    auth_providers.select do |provider|
+      provider == :saml || auth_strategy_class(provider) == 'OmniAuth::Strategies::SAML'
+    end
   end
 
   def auth_strategy_class(provider)
diff --git a/ee/app/models/ee/group.rb b/ee/app/models/ee/group.rb
index fca1b6edb74853d5262c71f230af78994e95ed7a..c3fbf1db5e759941565d85529a8e237254970816 100644
--- a/ee/app/models/ee/group.rb
+++ b/ee/app/models/ee/group.rb
@@ -305,13 +305,21 @@ def saml_discovery_token
     end
 
     def saml_enabled?
-      return false unless saml_provider
+      group_saml_enabled? || global_saml_enabled?
+    end
+
+    def saml_group_sync_available?
+      feature_available?(:saml_group_sync) && root_ancestor.saml_enabled?
+    end
+
+    def group_saml_enabled?
+      return false unless saml_provider && ::Gitlab::Auth::GroupSaml::Config.enabled?
 
       saml_provider.persisted? && saml_provider.enabled?
     end
 
-    def saml_group_sync_available?
-      feature_available?(:group_saml_group_sync) && root_ancestor.saml_enabled?
+    def global_saml_enabled?
+      ::Gitlab::Auth::Saml::Config.enabled?
     end
 
     override :multiple_issue_boards_available?
diff --git a/ee/app/models/gitlab_subscriptions/features.rb b/ee/app/models/gitlab_subscriptions/features.rb
index 79ccc7bf5f33416bdce14d82f504d9655719db2a..72bf6243de18812c76f7401d69a121ce6af43667 100644
--- a/ee/app/models/gitlab_subscriptions/features.rb
+++ b/ee/app/models/gitlab_subscriptions/features.rb
@@ -114,7 +114,6 @@ class Features
       group_project_templates
       group_repository_analytics
       group_saml
-      group_saml_group_sync
       group_scoped_ci_variables
       group_wikis
       incident_sla
@@ -140,6 +139,7 @@ class Features
       project_aliases
       protected_environments
       reject_unsigned_commits
+      saml_group_sync
       scoped_labels
       smartcard_auth
       swimlanes
diff --git a/ee/app/policies/ee/group_policy.rb b/ee/app/policies/ee/group_policy.rb
index ddc3780f29e4a9d947ac5c10ff55e241f1663ef8..5c4eb49d63289be6a5327ba3d4b07019907edc52 100644
--- a/ee/app/policies/ee/group_policy.rb
+++ b/ee/app/policies/ee/group_policy.rb
@@ -96,16 +96,24 @@ module GroupPolicy
         @subject.feature_available?(:cluster_deployments)
       end
 
-      condition(:group_saml_config_enabled, scope: :global) do
-        ::Gitlab::Auth::GroupSaml::Config.enabled?
+      condition(:global_saml_enabled, scope: :global) do
+        ::Gitlab::Auth::Saml::Config.enabled?
       end
 
-      condition(:group_saml_available, scope: :subject) do
-        !@subject.subgroup? && @subject.feature_available?(:group_saml)
+      condition(:global_saml_group_sync_enabled, scope: :global) do
+        ::Gitlab::Auth::Saml::Config.group_sync_enabled?
+      end
+
+      condition(:group_saml_globally_enabled, scope: :global) do
+        ::Gitlab::Auth::GroupSaml::Config.enabled?
       end
 
       condition(:group_saml_enabled, scope: :subject) do
-        @subject.saml_enabled?
+        @subject.group_saml_enabled?
+      end
+
+      condition(:group_saml_available, scope: :subject) do
+        !@subject.subgroup? && @subject.feature_available?(:group_saml)
       end
 
       condition(:group_saml_group_sync_available, scope: :subject) do
@@ -286,9 +294,13 @@ module GroupPolicy
         enable :read_group_audit_events
       end
 
-      rule { group_saml_config_enabled & group_saml_available & (admin | owner) }.enable :admin_group_saml
+      rule { group_saml_globally_enabled & group_saml_available & (admin | owner) }.enable :admin_group_saml
+
+      rule { group_saml_group_sync_available & (admin | owner) }.policy do
+        enable :admin_saml_group_links
+      end
 
-      rule { group_saml_config_enabled & group_saml_group_sync_available & (admin | owner) }.policy do
+      rule { global_saml_enabled & global_saml_group_sync_enabled & (admin | owner) }.policy do
         enable :admin_saml_group_links
       end
 
diff --git a/ee/lib/ee/gitlab/auth/saml/config.rb b/ee/lib/ee/gitlab/auth/saml/config.rb
index b5963d40f2452b29fb5ae1116c6ebf00e61a6a18..92752a492159573cef0e44cf58ec0203983a8793 100644
--- a/ee/lib/ee/gitlab/auth/saml/config.rb
+++ b/ee/lib/ee/gitlab/auth/saml/config.rb
@@ -15,6 +15,10 @@ def auditor_groups
             def required_groups
               Array(options[:required_groups])
             end
+
+            def group_sync_enabled?
+              enabled? && groups.present? && ::License.feature_available?(:saml_group_sync)
+            end
           end
         end
       end
diff --git a/ee/lib/ee/gitlab/auth/saml/identity_linker.rb b/ee/lib/ee/gitlab/auth/saml/identity_linker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bdfe9dd047f457cfacfc2a425635514a16f63e67
--- /dev/null
+++ b/ee/lib/ee/gitlab/auth/saml/identity_linker.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module EE
+  module Gitlab
+    module Auth
+      module Saml
+        module IdentityLinker
+          extend ::Gitlab::Utils::Override
+
+          override :link
+          def link
+            super
+
+            update_group_membership unless failed?
+          end
+
+          def update_group_membership
+            auth_hash = ::Gitlab::Auth::Saml::AuthHash.new(oauth)
+            ::Gitlab::Auth::Saml::MembershipUpdater.new(current_user, auth_hash).execute
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/ee/lib/ee/gitlab/auth/saml/user.rb b/ee/lib/ee/gitlab/auth/saml/user.rb
index 602c56e03216712dff2d3cfe75a3299106a66102..4fe0d3127d12cee0cc66f0638b5aa996d63b830e 100644
--- a/ee/lib/ee/gitlab/auth/saml/user.rb
+++ b/ee/lib/ee/gitlab/auth/saml/user.rb
@@ -29,6 +29,14 @@ def find_user
             user
           end
 
+          override :find_and_update!
+          def find_and_update!
+            save
+
+            update_group_membership
+            gl_user
+          end
+
           protected
 
           def block_user(user, reason)
@@ -53,6 +61,10 @@ def admin_groups_enabled?
           def auditor_groups_enabled?
             !saml_config.auditor_groups.blank?
           end
+
+          def update_group_membership
+            ::Gitlab::Auth::Saml::MembershipUpdater.new(gl_user, auth_hash).execute
+          end
         end
       end
     end
diff --git a/ee/lib/gitlab/auth/group_saml/identity_linker.rb b/ee/lib/gitlab/auth/group_saml/identity_linker.rb
index 5c7337dfcfd3f579395d0ac6ab48b139e5761da0..d5f11e74a0968f8ade34c0901292b11e8299976a 100644
--- a/ee/lib/gitlab/auth/group_saml/identity_linker.rb
+++ b/ee/lib/gitlab/auth/group_saml/identity_linker.rb
@@ -12,13 +12,6 @@ def initialize(current_user, oauth, session, saml_provider)
           @saml_provider = saml_provider
         end
 
-        override :link
-        def link
-          super
-
-          update_group_membership unless failed?
-        end
-
         protected
 
         # rubocop: disable CodeReuse/ActiveRecord
@@ -30,6 +23,7 @@ def identity
         end
         # rubocop: enable CodeReuse/ActiveRecord
 
+        override :update_group_membership
         def update_group_membership
           auth_hash = AuthHash.new(oauth)
           MembershipUpdater.new(current_user, saml_provider, auth_hash).execute
diff --git a/ee/lib/gitlab/auth/saml/membership_updater.rb b/ee/lib/gitlab/auth/saml/membership_updater.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0e81b7bc2ac59463ca2546deeb51b7892dad3156
--- /dev/null
+++ b/ee/lib/gitlab/auth/saml/membership_updater.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module Auth
+    module Saml
+      class MembershipUpdater
+        include Gitlab::Utils::StrongMemoize
+
+        def initialize(user, auth_hash)
+          @user = user
+          @auth_hash = auth_hash
+        end
+
+        def execute
+          enqueue_group_sync if sync_groups?
+        end
+
+        private
+
+        attr_reader :user, :auth_hash
+
+        def enqueue_group_sync
+          group_link_ids
+        end
+
+        def sync_groups?
+          return false unless user
+
+          sync_enabled? && any_group_links?
+        end
+
+        # rubocop:disable CodeReuse/ActiveRecord
+        def group_link_ids
+          strong_memoize(:group_link_ids) do
+            next [] if group_names_from_saml.empty?
+
+            SamlGroupLink
+              .by_saml_group_name(group_names_from_saml)
+              .pluck(:id)
+          end
+        end
+
+        def any_group_links?
+          strong_memoize(:any_group_links) do
+            SamlGroupLink.any?
+          end
+        end
+        # rubocop:enable CodeReuse/ActiveRecord
+
+        def group_names_from_saml
+          strong_memoize(:group_names_from_saml) do
+            auth_hash.groups || []
+          end
+        end
+
+        def sync_enabled?
+          Gitlab::Auth::Saml::Config.group_sync_enabled?
+        end
+      end
+    end
+  end
+end
diff --git a/ee/spec/controllers/groups/saml_group_links_controller_spec.rb b/ee/spec/controllers/groups/saml_group_links_controller_spec.rb
index c8ec1d6a6abdfeae044d734f62d2c4de24407eea..8fea5870b19b5e51cc71da20de0c370d140446a8 100644
--- a/ee/spec/controllers/groups/saml_group_links_controller_spec.rb
+++ b/ee/spec/controllers/groups/saml_group_links_controller_spec.rb
@@ -11,7 +11,7 @@
   end
 
   before do
-    stub_licensed_features(group_saml: true, group_saml_group_sync: true)
+    stub_licensed_features(group_saml: true, saml_group_sync: true)
 
     sign_in(user)
   end
diff --git a/ee/spec/features/groups/saml_group_links_spec.rb b/ee/spec/features/groups/saml_group_links_spec.rb
index 1af8ac571ee493436621746a0d34727108c7ecee..76c11f4c71648907335886663ef764703d8c2b4e 100644
--- a/ee/spec/features/groups/saml_group_links_spec.rb
+++ b/ee/spec/features/groups/saml_group_links_spec.rb
@@ -13,7 +13,7 @@
 
   context 'when SAML group links is available' do
     before do
-      stub_licensed_features(group_saml: true, group_saml_group_sync: true)
+      stub_licensed_features(group_saml: true, saml_group_sync: true)
 
       create(:saml_provider, group: group, enabled: true)
 
diff --git a/ee/spec/lib/ee/gitlab/auth/saml/identity_linker_spec.rb b/ee/spec/lib/ee/gitlab/auth/saml/identity_linker_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d5f528c013dc9d845ed5c89ef59e65a5ec41f0a6
--- /dev/null
+++ b/ee/spec/lib/ee/gitlab/auth/saml/identity_linker_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Auth::Saml::IdentityLinker do
+  let(:user) { create(:user) }
+  let(:in_response_to) { '12345' }
+  let(:saml_response) { instance_double(OneLogin::RubySaml::Response, in_response_to: in_response_to) }
+  let(:session) { { 'last_authn_request_id' => in_response_to } }
+
+  let(:oauth) do
+    OmniAuth::AuthHash.new(provider: 'saml', uid: user.email, extra: { response_object: saml_response })
+  end
+
+  subject(:linker) { described_class.new(user, oauth, session) }
+
+  it 'updates membership' do
+    expect(Gitlab::Auth::Saml::MembershipUpdater).to receive(:new).with(user, any_args).and_call_original
+
+    linker.link
+  end
+end
diff --git a/ee/spec/lib/ee/gitlab/auth/saml/membership_updater_spec.rb b/ee/spec/lib/ee/gitlab/auth/saml/membership_updater_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..52a16abcd0d43c40396a5cd43528c3ca5db68a7d
--- /dev/null
+++ b/ee/spec/lib/ee/gitlab/auth/saml/membership_updater_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Auth::Saml::MembershipUpdater do
+  let_it_be(:user) { create(:user) }
+  let_it_be(:group1) { create(:group) }
+  let_it_be(:group2) { create(:group) }
+
+  let(:auth_hash) do
+    Gitlab::Auth::GroupSaml::AuthHash.new(
+      OmniAuth::AuthHash.new(extra: {
+        raw_info: OneLogin::RubySaml::Attributes.new('groups' => %w(Developers Owners))
+      })
+    )
+  end
+
+  subject(:update_membership) { described_class.new(user, auth_hash).execute }
+
+  context 'when SAML group links exist' do
+    def stub_saml_group_sync_enabled(enabled)
+      allow(::Gitlab::Auth::Saml::Config).to receive(:group_sync_enabled?).and_return(enabled)
+    end
+
+    let!(:group_link) { create(:saml_group_link, saml_group_name: 'Owners', group: group1) }
+
+    context 'when group sync is not available' do
+      before do
+        stub_saml_group_sync_enabled(false)
+      end
+
+      it 'does not enqueue group sync' do
+        expect(::SamlGroupLink).not_to receive(:by_saml_group_name)
+
+        update_membership
+      end
+    end
+
+    context 'when group sync is available' do
+      before do
+        stub_saml_group_sync_enabled(true)
+      end
+
+      it 'enqueues group sync' do
+        expect(::SamlGroupLink).to receive(:by_saml_group_name).and_call_original
+
+        update_membership
+      end
+
+      context 'when auth hash contains no groups' do
+        let(:auth_hash) do
+          Gitlab::Auth::GroupSaml::AuthHash.new(
+            OmniAuth::AuthHash.new(extra: { raw_info: OneLogin::RubySaml::Attributes.new })
+          )
+        end
+
+        it 'enqueues group sync' do
+          expect(::SamlGroupLink).not_to receive(:by_saml_group_name)
+
+          update_membership
+        end
+      end
+
+      context 'when auth hash groups do not match group links' do
+        before do
+          group_link.update!(saml_group_name: 'Web Developers')
+        end
+
+        it 'enqueues group sync' do
+          expect(::SamlGroupLink).to receive(:by_saml_group_name).and_call_original
+
+          update_membership
+        end
+      end
+    end
+  end
+end
diff --git a/ee/spec/lib/gitlab/auth/saml/config_spec.rb b/ee/spec/lib/gitlab/auth/saml/config_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a183a3db7ccb6f35ae2a62b51f8dab6180c83519
--- /dev/null
+++ b/ee/spec/lib/gitlab/auth/saml/config_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Auth::Saml::Config do
+  describe '.group_sync_enabled?' do
+    subject { described_class.group_sync_enabled? }
+
+    it { is_expected.to eq(false) }
+
+    context 'when SAML is enabled' do
+      before do
+        allow(Gitlab::Auth::Saml::Config).to receive_messages({ options: { name: 'saml', args: {} } })
+        allow(Gitlab::Auth::OAuth::Provider).to receive(:providers).and_return([:saml])
+      end
+
+      it { is_expected.to eq(false) }
+
+      context 'when the group attribute is configured' do
+        before do
+          allow(Gitlab::Auth::Saml::Config).to receive(:groups).and_return(['Groups'])
+        end
+
+        it { is_expected.to eq(false) }
+
+        context 'when the saml_group_sync feature is licensed' do
+          before do
+            stub_licensed_features(saml_group_sync: true)
+          end
+
+          it { is_expected.to eq(true) }
+        end
+      end
+    end
+  end
+end
diff --git a/ee/spec/models/ee/group_spec.rb b/ee/spec/models/ee/group_spec.rb
index 95eb2977bf0d052fe8d5c99c5525a309c46b2fc7..76e65d6233c2b553e93bdf4e8fed1c5ed8824982 100644
--- a/ee/spec/models/ee/group_spec.rb
+++ b/ee/spec/models/ee/group_spec.rb
@@ -1653,6 +1653,14 @@
 
       it { is_expected.to eq(false) }
     end
+
+    context 'when global SAML is enabled' do
+      before do
+        allow(Gitlab::Auth::OAuth::Provider).to receive(:providers).and_return([:saml])
+      end
+
+      it { is_expected.to eq(true) }
+    end
   end
 
   describe '#saml_group_sync_available?' do
@@ -1662,7 +1670,7 @@
 
     context 'with group_saml_group_sync feature licensed' do
       before do
-        stub_licensed_features(group_saml_group_sync: true)
+        stub_licensed_features(saml_group_sync: true)
       end
 
       it { is_expected.to eq(false) }
diff --git a/ee/spec/policies/group_policy_spec.rb b/ee/spec/policies/group_policy_spec.rb
index d0a13a742df7bdaa4896e70d49dc6079e5924ea7..360d087236fefed41ef0201f17992540b09a3e10 100644
--- a/ee/spec/policies/group_policy_spec.rb
+++ b/ee/spec/policies/group_policy_spec.rb
@@ -621,6 +621,43 @@ def stub_group_saml_config(enabled)
     end
   end
 
+  describe 'admin_saml_group_links for global SAML' do
+    let(:current_user) { owner }
+
+    it { is_expected.to be_disallowed(:admin_saml_group_links) }
+
+    context 'when global SAML is enabled' do
+      before do
+        allow(Gitlab::Auth::Saml::Config).to receive_messages({ options: { name: 'saml', args: {} } })
+        allow(Gitlab::Auth::OAuth::Provider).to receive(:providers).and_return([:saml])
+      end
+
+      it { is_expected.to be_disallowed(:admin_saml_group_links) }
+
+      context 'when the groups attribute is configured' do
+        before do
+          allow(Gitlab::Auth::Saml::Config).to receive(:groups).and_return(['Groups'])
+        end
+
+        it { is_expected.to be_disallowed(:admin_saml_group_links) }
+
+        context 'when saml_group_sync feature is licensed' do
+          before do
+            stub_licensed_features(saml_group_sync: true)
+          end
+
+          it { is_expected.to be_allowed(:admin_saml_group_links) }
+
+          context 'when the current user is not an admin or owner' do
+            let(:current_user) { maintainer }
+
+            it { is_expected.to be_disallowed(:admin_saml_group_links) }
+          end
+        end
+      end
+    end
+  end
+
   context 'with ip restriction' do
     let(:current_user) { developer }
 
diff --git a/ee/spec/views/layouts/nav/sidebar/_group.html.haml_spec.rb b/ee/spec/views/layouts/nav/sidebar/_group.html.haml_spec.rb
index f635944660c01da93a6e94d291b88824e58c52c2..327a9170b445dc316c10c722c8ed4ab6bf557a58 100644
--- a/ee/spec/views/layouts/nav/sidebar/_group.html.haml_spec.rb
+++ b/ee/spec/views/layouts/nav/sidebar/_group.html.haml_spec.rb
@@ -532,7 +532,7 @@
         usage_quotas: true,
         group_saml: true,
         group_webhooks: true,
-        group_saml_group_sync: true,
+        saml_group_sync: true,
         ldap_group_sync: true
       )
       stub_feature_flags(group_administration_nav_item: false)
diff --git a/ee/spec/workers/group_saml_group_sync_worker_spec.rb b/ee/spec/workers/group_saml_group_sync_worker_spec.rb
index a69ef4ad0dd8f32fbc9b09c896d0600eef09d7a6..915580cfb5614d1eb4af26641668cfc97f3f482f 100644
--- a/ee/spec/workers/group_saml_group_sync_worker_spec.rb
+++ b/ee/spec/workers/group_saml_group_sync_worker_spec.rb
@@ -28,7 +28,7 @@
 
     context 'when the group has group_saml_group_sync feature licensed' do
       before do
-        stub_licensed_features(group_saml_group_sync: true)
+        stub_licensed_features(saml_group_sync: true)
       end
 
       context 'when SAML is not enabled' do
diff --git a/lib/gitlab/auth/saml/config.rb b/lib/gitlab/auth/saml/config.rb
index 3f13a264b0acce4bc185fd763afc1636d61644dd..815130aeee2262f828c2f8a129dd31f21b95e0e0 100644
--- a/lib/gitlab/auth/saml/config.rb
+++ b/lib/gitlab/auth/saml/config.rb
@@ -5,6 +5,10 @@ module Auth
     module Saml
       class Config
         class << self
+          def enabled?
+            ::AuthHelper.saml_providers.any?
+          end
+
           def options
             Gitlab::Auth::OAuth::Provider.config_for('saml')
           end
diff --git a/lib/gitlab/auth/saml/identity_linker.rb b/lib/gitlab/auth/saml/identity_linker.rb
index 93195c3189ff84bb04ca0d5903069a4f1f765774..a44a9c2fca51097f0ea5d520552d0e67b1c57c23 100644
--- a/lib/gitlab/auth/saml/identity_linker.rb
+++ b/lib/gitlab/auth/saml/identity_linker.rb
@@ -32,3 +32,5 @@ def saml_response
     end
   end
 end
+
+Gitlab::Auth::Saml::IdentityLinker.prepend_mod
diff --git a/spec/helpers/auth_helper_spec.rb b/spec/helpers/auth_helper_spec.rb
index 4bb09699db4f6121159acc9baa6821c14dc4e577..4b0b44d1325b99d1d850e97b8696c474e58c9c11 100644
--- a/spec/helpers/auth_helper_spec.rb
+++ b/spec/helpers/auth_helper_spec.rb
@@ -500,6 +500,16 @@ def auth_active?
       )
     end
 
+    context 'when SAML is enabled without specifying a strategy class' do
+      before do
+        allow(Gitlab::Auth::OAuth::Provider).to receive(:providers).and_return([:saml])
+      end
+
+      it 'returns the saml provider' do
+        expect(saml_providers).to match_array([:saml])
+      end
+    end
+
     context 'when configuration specifies no provider' do
       before do
         allow(Devise).to receive(:omniauth_providers).and_return([])
diff --git a/spec/lib/gitlab/auth/saml/config_spec.rb b/spec/lib/gitlab/auth/saml/config_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..12f5da4887357ea7dab94cc1fcad6c1edd9daa21
--- /dev/null
+++ b/spec/lib/gitlab/auth/saml/config_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Auth::Saml::Config do
+  describe '.enabled?' do
+    subject { described_class.enabled? }
+
+    it { is_expected.to eq(false) }
+
+    context 'when SAML is enabled' do
+      before do
+        allow(Gitlab::Auth::OAuth::Provider).to receive(:providers).and_return([:saml])
+      end
+
+      it { is_expected.to eq(true) }
+    end
+  end
+end