diff --git a/ee/app/policies/ee/global_policy.rb b/ee/app/policies/ee/global_policy.rb
index 186d8a42445f88e93d3f8928e20c5f0eaf20c4ba..e733562f176125ae3fcd19b2d605a5e52bfed3a4 100644
--- a/ee/app/policies/ee/global_policy.rb
+++ b/ee/app/policies/ee/global_policy.rb
@@ -232,10 +232,7 @@ def duo_chat_free_access_was_cut_off?
     end
 
     def duo_chat_free_access_was_cut_off_for_gitlab_com?
-      duo_chat_free_cutoff = Time.utc(2024, 10, 17)
-      free_access_expired = Time.now.utc >= duo_chat_free_cutoff
-
-      free_access_expired || user.belongs_to_group_requires_licensed_seat_for_chat?
+      !duo_chat.free_access? || user.belongs_to_group_requires_licensed_seat_for_chat?
     end
 
     def duo_chat_free_access_was_cut_off_for_sm?
diff --git a/ee/config/cloud_connector/access_data.yml b/ee/config/cloud_connector/access_data.yml
index 63526b3fdb5b4703dd88bef9a8b82f4bd93c4a84..736d95694936da11759ab041ebb5e1eff21d33f8 100644
--- a/ee/config/cloud_connector/access_data.yml
+++ b/ee/config/cloud_connector/access_data.yml
@@ -27,6 +27,8 @@ services: # Cloud connector features (i.e. code_suggestions, duo_chat...)
           - code_suggestions
   duo_chat:
     backend: 'gitlab-ai-gateway'
+    # Represents the cut-off date when the service requires addon seat purchase.
+    cut_off_date: 2024-10-17 00:00:00 UTC
     bundled_with:
       duo_pro:
         unit_primitives:
diff --git a/ee/spec/lib/cloud_connector/self_signed/access_data_reader_spec.rb b/ee/spec/lib/cloud_connector/self_signed/access_data_reader_spec.rb
index d31c6ee1f207554ed3638169f8513c79b6954306..53a9980454817142f40af8bbc354b61e48c07a30 100644
--- a/ee/spec/lib/cloud_connector/self_signed/access_data_reader_spec.rb
+++ b/ee/spec/lib/cloud_connector/self_signed/access_data_reader_spec.rb
@@ -19,6 +19,7 @@
     let_it_be(:sast_backend) { 'gitlab-security-gateway' }
 
     let_it_be(:self_hosted_models_cut_off_date) { Time.zone.parse("2024-10-17 00:00:00 UTC").utc }
+    let_it_be(:duo_chat_cutoff_date) { Time.zone.parse("2024-10-17 00:00:00 UTC").utc }
     let_it_be(:self_hosted_models_bundled_with) { { "duo_enterprise" => [:code_suggestions, :duo_chat] } }
 
     let_it_be(:anthropic_proxy_bundled_with) do
@@ -133,7 +134,7 @@
       let_it_be(:arguments_map) do
         {
           code_suggestions: [cs_cut_off_date, cs_bundled_with, backend],
-          duo_chat: [nil, duo_chat_bundled_with, backend],
+          duo_chat: [duo_chat_cutoff_date, duo_chat_bundled_with, backend],
           anthropic_proxy: [nil, anthropic_proxy_bundled_with, backend],
           vertex_ai_proxy: [nil, vertex_ai_proxy_bundled_with, backend],
           resolve_vulnerability: [nil, resolve_vulnerability_bundled_with, backend],
diff --git a/ee/spec/policies/global_policy_spec.rb b/ee/spec/policies/global_policy_spec.rb
index adde22984f2e5ae422a595566f00c0ce44f0db6f..7a79468a09d02b2294e482bad464a3bfa8639b14 100644
--- a/ee/spec/policies/global_policy_spec.rb
+++ b/ee/spec/policies/global_policy_spec.rb
@@ -641,26 +641,20 @@
 
   describe 'access_duo_chat' do
     let(:policy) { :access_duo_chat }
-    let_it_be(:before_cutoff) { Date.new(2024, 10, 16) }
-    let_it_be(:after_cutoff) { Date.new(2024, 10, 18) }
 
     let_it_be_with_reload(:current_user) { create(:user) }
 
     context 'when on .org or .com', :saas do
       where(:group_with_ai_membership, :duo_pro_seat_assigned, :requires_licensed_seat,
-        :frozen_date, :duo_chat_enabled_for_user) do
-        false | false  | false | ref(:before_cutoff) | be_disallowed(policy)
-        false | true   | false | ref(:before_cutoff) | be_disallowed(policy)
-        true  | false  | false | ref(:before_cutoff) | be_allowed(policy)
-        true  | true   | false | ref(:before_cutoff) | be_allowed(policy)
-
-        # When Group actor belongs to a group which requires licensed seat for chat
-        true  | false  | true  | ref(:before_cutoff) | be_disallowed(policy)
-        true  | true   | true  | ref(:before_cutoff) | be_allowed(policy)
-
-        # After free access cutoff
-        false | true   | false | ref(:after_cutoff) | be_allowed(policy)
-        true  | false  | false | ref(:after_cutoff) | be_disallowed(policy)
+        :free_access, :duo_chat_enabled_for_user) do
+        false | false | false | true  | be_disallowed(policy)
+        false | true  | false | true  | be_disallowed(policy)
+        true  | false | false | true  | be_allowed(policy)
+        true  | true  | false | true  | be_allowed(policy)
+        true  | false | true  | true  | be_disallowed(policy)
+        true  | true  | true  | true  | be_allowed(policy)
+        false | true  | false | false | be_allowed(policy)
+        true  | false | false | false | be_disallowed(policy)
       end
 
       with_them do
@@ -670,9 +664,9 @@
           allow(CloudConnector::AvailableServices).to receive(:find_by_name).with(:duo_chat)
                                                                             .and_return(duo_chat_service_data)
           allow(duo_chat_service_data).to receive(:allowed_for?).with(current_user).and_return(duo_pro_seat_assigned)
+          allow(duo_chat_service_data).to receive(:free_access?).and_return(free_access)
           allow(current_user).to receive(:belongs_to_group_requires_licensed_seat_for_chat?)
                                    .and_return(requires_licensed_seat)
-          travel_to(frozen_date)
         end
 
         it { is_expected.to duo_chat_enabled_for_user }
@@ -719,13 +713,16 @@
 
     context 'when duo chat is self hosted' do
       where(:duo_chat_on_saas, :ai_chat_available, :self_hosted, :allowed_to_use,
-        :free, :beta_ended, :duo_chat_enabled_for_user) do
-        true  | true  | true  | true  | true  | true  | be_allowed(policy)
-        false | false | true  | true  | true  | true  | be_disallowed(policy)
-        false | true  | true  | true  | true  | true  | be_allowed(policy)
-        true  | true  | false | true  | true  | true  | be_disallowed(policy)
-        true  | true  | true  | false | true  | false | be_allowed(policy)
-        true  | true  | true  | false | true  | true  | be_disallowed(policy)
+        :free, :beta_ended, :duo_chat_free, :duo_chat_enabled_for_user) do
+        true  | true  | true  | true  | true  | true  | true  | be_allowed(policy)
+        false | false | true  | true  | true  | true  | true  | be_disallowed(policy)
+        false | true  | true  | true  | true  | true  | true  | be_allowed(policy)
+        true  | true  | false | true  | true  | true  | true  | be_disallowed(policy)
+        true  | true  | true  | false | true  | false | true  | be_allowed(policy)
+        true  | true  | true  | false | true  | true  | true  | be_disallowed(policy)
+        true  | true  | true  | true  | true  | true  | false | be_allowed(policy)
+        true  | true  | true  | true  | true  | false | true  | be_allowed(policy)
+        true  | true  | true  | true  | false | true  | true  | be_allowed(policy)
       end
 
       with_them do
@@ -738,10 +735,14 @@
             :self_hosted?).and_return(self_hosted)
 
           self_hosted_service_data = instance_double(CloudConnector::SelfSigned::AvailableServiceData)
+          duo_chat_service_data = instance_double(CloudConnector::SelfSigned::AvailableServiceData)
           allow(CloudConnector::AvailableServices).to receive(:find_by_name).with(:self_hosted_models)
                                                                             .and_return(self_hosted_service_data)
+          allow(CloudConnector::AvailableServices).to receive(:find_by_name).with(:duo_chat)
+                                                                            .and_return(duo_chat_service_data)
           allow(self_hosted_service_data).to receive(:allowed_for?).with(current_user).and_return(allowed_to_use)
           allow(self_hosted_service_data).to receive(:free_access?).and_return(free)
+          allow(duo_chat_service_data).to receive(:free_access?).and_return(duo_chat_free)
         end
 
         it { is_expected.to duo_chat_enabled_for_user }