diff --git a/ee/app/controllers/admin/ai/self_hosted_models_controller.rb b/ee/app/controllers/admin/ai/self_hosted_models_controller.rb
index 433fd7f611afcca1fdbc5b143cab6c445fdad12d..856ac4e75a0bc86bb08b5c5d4ecd246705785bc0 100644
--- a/ee/app/controllers/admin/ai/self_hosted_models_controller.rb
+++ b/ee/app/controllers/admin/ai/self_hosted_models_controller.rb
@@ -22,7 +22,7 @@ def ensure_registration!
       end
 
       def ensure_feature_enabled!
-        render_404 unless Ability.allowed?(current_user, :manage_ai_settings)
+        render_404 unless Ability.allowed?(current_user, :manage_self_hosted_models_settings)
       end
     end
   end
diff --git a/ee/app/controllers/admin/ai/terms_and_conditions_controller.rb b/ee/app/controllers/admin/ai/terms_and_conditions_controller.rb
index 31450d0fa440f04e051ad923a599a860ba63463a..7767e1269caab7e1a519b44038962f08b5c94d1f 100644
--- a/ee/app/controllers/admin/ai/terms_and_conditions_controller.rb
+++ b/ee/app/controllers/admin/ai/terms_and_conditions_controller.rb
@@ -25,7 +25,7 @@ def create
       private
 
       def ensure_feature_enabled!
-        render_404 unless Ability.allowed?(current_user, :manage_ai_settings)
+        render_404 unless Ability.allowed?(current_user, :manage_self_hosted_models_settings)
       end
 
       def audit_event(user)
diff --git a/ee/app/graphql/mutations/ai/feature_settings/base.rb b/ee/app/graphql/mutations/ai/feature_settings/base.rb
index 65231681197b095b764562a7219e7a87a920f082..d00e5de2fbf42e3bba92f4620d880f98c3ca6c48 100644
--- a/ee/app/graphql/mutations/ai/feature_settings/base.rb
+++ b/ee/app/graphql/mutations/ai/feature_settings/base.rb
@@ -13,7 +13,7 @@ class Base < BaseMutation
         private
 
         def check_feature_access!
-          raise_resource_not_available_error! unless Ability.allowed?(current_user, :manage_ai_settings)
+          raise_resource_not_available_error! unless Ability.allowed?(current_user, :manage_self_hosted_models_settings)
         end
       end
       # rubocop: enable GraphQL/GraphqlName
diff --git a/ee/app/graphql/mutations/ai/self_hosted_models/base.rb b/ee/app/graphql/mutations/ai/self_hosted_models/base.rb
index fe61191e10587bef4239e9fc08810a0f0aa889cb..294f4597e1c7aba8f4f5f83fec52807582ea237c 100644
--- a/ee/app/graphql/mutations/ai/self_hosted_models/base.rb
+++ b/ee/app/graphql/mutations/ai/self_hosted_models/base.rb
@@ -37,7 +37,7 @@ def self.arguments_for_model_attributes
         private
 
         def check_feature_access!
-          raise_resource_not_available_error! unless Ability.allowed?(current_user, :manage_ai_settings)
+          raise_resource_not_available_error! unless Ability.allowed?(current_user, :manage_self_hosted_models_settings)
         end
       end
       # rubocop: enable GraphQL/GraphqlName
diff --git a/ee/app/graphql/resolvers/ai/feature_settings/feature_settings_resolver.rb b/ee/app/graphql/resolvers/ai/feature_settings/feature_settings_resolver.rb
index fe41003003941c87d829511cbca68efbe125ebde..22227c109226c2f20310296c21900353bd964d12 100644
--- a/ee/app/graphql/resolvers/ai/feature_settings/feature_settings_resolver.rb
+++ b/ee/app/graphql/resolvers/ai/feature_settings/feature_settings_resolver.rb
@@ -14,7 +14,7 @@ class FeatureSettingsResolver < BaseResolver
           description: 'Global ID of the self-hosted model.'
 
         def resolve(self_hosted_model_id: nil)
-          raise_resource_not_available_error! unless Ability.allowed?(current_user, :manage_ai_settings)
+          return unless Ability.allowed?(current_user, :manage_self_hosted_models_settings)
 
           feature_settings = get_feature_settings(self_hosted_model_id)
 
diff --git a/ee/app/graphql/resolvers/ai/self_hosted_models/self_hosted_models_resolver.rb b/ee/app/graphql/resolvers/ai/self_hosted_models/self_hosted_models_resolver.rb
index d90c28b8c335041e44471ad3c44f01827200d69e..929dc084fc7ec4dc8ecc64db60d1d95af0c37d56 100644
--- a/ee/app/graphql/resolvers/ai/self_hosted_models/self_hosted_models_resolver.rb
+++ b/ee/app/graphql/resolvers/ai/self_hosted_models/self_hosted_models_resolver.rb
@@ -7,7 +7,7 @@ class SelfHostedModelsResolver < BaseResolver
         type ::Types::Ai::SelfHostedModels::SelfHostedModelType.connection_type, null: false
 
         def resolve(**args)
-          return unless Ability.allowed?(current_user, :manage_ai_settings)
+          return unless Ability.allowed?(current_user, :manage_self_hosted_models_settings)
 
           if args[:id]
             get_self_hosted_model(args[:id])
diff --git a/ee/app/policies/ee/global_policy.rb b/ee/app/policies/ee/global_policy.rb
index e88979745810a4106981101af1e3e016aeb4e427..61400bbd670ef9f8cd93dc01997c4084bf9cd8ea 100644
--- a/ee/app/policies/ee/global_policy.rb
+++ b/ee/app/policies/ee/global_policy.rb
@@ -102,11 +102,12 @@ module GlobalPolicy
         ::License.feature_available?(:default_roles_assignees)
       end
 
-      condition(:user_allowed_to_manage_ai_settings) do
+      condition(:user_allowed_to_manage_self_hosted_models_settings) do
         next false if ::Feature.disabled?(:allow_self_hosted_features_for_com) &&
           ::Gitlab::Saas.feature_available?(:gitlab_com_subscriptions)
 
-        ::License.current&.paid? # Replace with license :ai_self_hosted_model for GA
+        ::License.current&.ultimate? && # Replace with license :ai_self_hosted_model for GA
+          ::GitlabSubscriptions::AddOnPurchase.for_duo_enterprise.active.exists?
       end
 
       condition(:x_ray_available) do
@@ -147,8 +148,8 @@ module GlobalPolicy
         enable :read_cloud_connector_status
       end
 
-      rule { admin & user_allowed_to_manage_ai_settings }.policy do
-        enable :manage_ai_settings
+      rule { admin & user_allowed_to_manage_self_hosted_models_settings }.policy do
+        enable :manage_self_hosted_models_settings
       end
 
       rule { admin & custom_roles_allowed }.policy do
diff --git a/ee/spec/policies/global_policy_spec.rb b/ee/spec/policies/global_policy_spec.rb
index 490daaa68011fa25fbc28f3720314a06659e44d5..83cfe5a78c5e0b0abb6c44e94347b3e674796d7c 100644
--- a/ee/spec/policies/global_policy_spec.rb
+++ b/ee/spec/policies/global_policy_spec.rb
@@ -829,7 +829,9 @@
 
   describe 'manage self-hosted AI models' do
     let(:current_user) { admin }
-    let(:license_double) { instance_double('License', paid?: true) }
+    let(:license_double) { instance_double('License', ultimate?: true) }
+
+    let_it_be(:add_on_purchase) { create(:gitlab_subscription_add_on_purchase, :duo_enterprise, :active) }
 
     before do
       allow(License).to receive(:current).and_return(license_double)
@@ -837,17 +839,25 @@
 
     context 'when admin' do
       context 'when conditions are respected', :enable_admin_mode do
-        it { is_expected.to be_allowed(:manage_ai_settings) }
+        it { is_expected.to be_allowed(:manage_self_hosted_models_settings) }
       end
 
       context 'when admin mode is disabled' do
-        it { is_expected.to be_disallowed(:manage_ai_settings) }
+        it { is_expected.to be_disallowed(:manage_self_hosted_models_settings) }
+      end
+
+      context 'when license is not an Ultimate license', :enable_admin_mode do
+        let(:license_double) { instance_double('License', ultimate?: false) }
+
+        it { is_expected.to be_disallowed(:manage_self_hosted_models_settings) }
       end
 
-      context 'when license is not paid', :enable_admin_mode do
-        let(:license_double) { instance_double('License', paid?: false) }
+      context 'when there is no active Duo Enterprise subscription', :enable_admin_mode do
+        before do
+          add_on_purchase.update!(expires_on: 1.day.ago)
+        end
 
-        it { is_expected.to be_disallowed(:manage_ai_settings) }
+        it { is_expected.to be_disallowed(:manage_self_hosted_models_settings) }
       end
 
       context 'when instance is in SASS mode', :enable_admin_mode do
@@ -856,20 +866,20 @@
           stub_feature_flags(allow_self_hosted_features_for_com: true)
         end
 
-        it { is_expected.to be_allowed(:manage_ai_settings) }
+        it { is_expected.to be_allowed(:manage_self_hosted_models_settings) }
 
         context 'when allow_self_hosted_features_for_com is disabled' do
           before do
             stub_feature_flags(allow_self_hosted_features_for_com: false)
           end
 
-          it { is_expected.to be_disallowed(:manage_ai_settings) }
+          it { is_expected.to be_disallowed(:manage_self_hosted_models_settings) }
         end
       end
     end
 
     context 'when regular user' do
-      it { is_expected.to be_disallowed(:manage_ai_settings) }
+      it { is_expected.to be_disallowed(:manage_self_hosted_models_settings) }
     end
   end
 
diff --git a/ee/spec/requests/admin/ai/self_hosted_models_controller_spec.rb b/ee/spec/requests/admin/ai/self_hosted_models_controller_spec.rb
index 63086f333bc385effe6645fd2eeac21f5702c4e8..a9dfcdda85db3b60d0fa876de0a5cf7d0a8b9386 100644
--- a/ee/spec/requests/admin/ai/self_hosted_models_controller_spec.rb
+++ b/ee/spec/requests/admin/ai/self_hosted_models_controller_spec.rb
@@ -5,6 +5,10 @@
 RSpec.describe Admin::Ai::SelfHostedModelsController, :enable_admin_mode, feature_category: :"self-hosted_models" do
   let(:admin) { create(:admin) }
   let(:duo_features_enabled) { true }
+  let_it_be(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
+  let_it_be(:add_on_purchase) do
+    create(:gitlab_subscription_add_on_purchase, :duo_enterprise, :active)
+  end
 
   before do
     sign_in(admin)
@@ -31,7 +35,7 @@
     context 'when the user is not authorized' do
       it 'performs the right authorization correctly' do
         allow(Ability).to receive(:allowed?).and_call_original
-        expect(Ability).to receive(:allowed?).with(admin, :manage_ai_settings).and_return(false)
+        expect(Ability).to receive(:allowed?).with(admin, :manage_self_hosted_models_settings).and_return(false)
 
         perform_request
 
@@ -39,4 +43,21 @@
       end
     end
   end
+
+  describe 'GET #index' do
+    let(:page) { Nokogiri::HTML(response.body) }
+
+    subject :perform_request do
+      get admin_ai_self_hosted_models_path
+    end
+
+    it 'returns list of self-hosted models' do
+      perform_request
+
+      expect(response).to have_gitlab_http_status(:ok)
+    end
+
+    it_behaves_like 'returns 404'
+    it_behaves_like 'must accept terms and conditions'
+  end
 end
diff --git a/ee/spec/requests/admin/ai/terms_and_conditions_controller_spec.rb b/ee/spec/requests/admin/ai/terms_and_conditions_controller_spec.rb
index 06a491c4822c6b188fe5e1188e78defad23473fe..0fa8756562f6f3893c11c21043468ed995f02d49 100644
--- a/ee/spec/requests/admin/ai/terms_and_conditions_controller_spec.rb
+++ b/ee/spec/requests/admin/ai/terms_and_conditions_controller_spec.rb
@@ -5,6 +5,10 @@
 RSpec.describe Admin::Ai::TermsAndConditionsController, :enable_admin_mode, feature_category: :"self-hosted_models" do
   let(:admin) { create(:admin) }
   let(:duo_features_enabled) { true }
+  let_it_be(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
+  let_it_be(:add_on_purchase) do
+    create(:gitlab_subscription_add_on_purchase, :duo_enterprise, :active)
+  end
 
   before do
     sign_in(admin)
@@ -15,7 +19,7 @@
     context 'when the user is not authorized' do
       it 'performs the right authorization correctly' do
         allow(Ability).to receive(:allowed?).and_call_original
-        expect(Ability).to receive(:allowed?).with(admin, :manage_ai_settings).and_return(false)
+        expect(Ability).to receive(:allowed?).with(admin, :manage_self_hosted_models_settings).and_return(false)
 
         perform_request
 
diff --git a/ee/spec/requests/api/graphql/ai/feature_settings/feature_settings_spec.rb b/ee/spec/requests/api/graphql/ai/feature_settings/feature_settings_spec.rb
index a020353815160b22c36d59027db8d3d03bbc5f03..7b50a4248ababadde0dfcce9ef0294119a3624c5 100644
--- a/ee/spec/requests/api/graphql/ai/feature_settings/feature_settings_spec.rb
+++ b/ee/spec/requests/api/graphql/ai/feature_settings/feature_settings_spec.rb
@@ -6,6 +6,11 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:admin) }
+  let_it_be(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
+  let_it_be(:add_on_purchase) do
+    create(:gitlab_subscription_add_on_purchase, :duo_enterprise, :active)
+  end
+
   let(:query) do
     %(
       query aiFeatureSettings {
@@ -64,14 +69,6 @@
     allow(::Ai::FeatureSetting).to receive(:allowed_features).and_return(test_ai_feature_enum)
   end
 
-  shared_examples 'an error response' do |expected_error_message|
-    it 'returns an error', :aggregate_failures do
-      post_graphql(query, current_user: current_user)
-      expect(graphql_data['aiFeatureSettings']).to be_nil
-      expect_graphql_errors_to_include(expected_error_message)
-    end
-  end
-
   context "when the user is authorized" do
     context 'when no query parameters are given' do
       let(:expected_response) do
diff --git a/ee/spec/requests/api/graphql/ai/feature_settings/update_spec.rb b/ee/spec/requests/api/graphql/ai/feature_settings/update_spec.rb
index 3a99ad6e6fc56b0b4a4476db5763019f8d59ad42..a959cf23eabb2988f2c11fb09adebe71099b629e 100644
--- a/ee/spec/requests/api/graphql/ai/feature_settings/update_spec.rb
+++ b/ee/spec/requests/api/graphql/ai/feature_settings/update_spec.rb
@@ -8,6 +8,10 @@
   let_it_be(:current_user) { create(:admin) }
   let_it_be(:self_hosted_model) { create(:ai_self_hosted_model) }
   let_it_be(:feature_setting) { create(:ai_feature_setting, provider: :vendored, self_hosted_model: nil) }
+  let_it_be(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
+  let_it_be(:add_on_purchase) do
+    create(:gitlab_subscription_add_on_purchase, :duo_enterprise, :active)
+  end
 
   let(:mutation_name) { :ai_feature_setting_update }
   let(:mutation_params) do
diff --git a/ee/spec/requests/api/graphql/ai/self_hosted_models/connection_check_spec.rb b/ee/spec/requests/api/graphql/ai/self_hosted_models/connection_check_spec.rb
index 7a58c1ffbacaa4b9e7482fcb4152793eb7ac00bc..cad00c3bac2533286efd186b95f19133a86a20b5 100644
--- a/ee/spec/requests/api/graphql/ai/self_hosted_models/connection_check_spec.rb
+++ b/ee/spec/requests/api/graphql/ai/self_hosted_models/connection_check_spec.rb
@@ -6,6 +6,10 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:admin) }
+  let_it_be(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
+  let_it_be(:add_on_purchase) do
+    create(:gitlab_subscription_add_on_purchase, :duo_enterprise, :active)
+  end
 
   let(:input) do
     {
@@ -22,12 +26,10 @@
 
   subject(:request) { post_graphql_mutation(mutation, current_user: current_user) }
 
-  shared_examples 'it calls the manage_ai_settings policy' do
-    it 'calls the manage_ai_settings policy' do
+  shared_examples 'it calls the manage_self_hosted_models_settings policy' do
+    it 'calls the manage_self_hosted_models_settings policy' do
       allow(::Ability).to receive(:allowed?).and_call_original
-
-      expect(::Ability).to receive(:allowed?)
-                             .with(current_user, :manage_ai_settings)
+      expect(::Ability).to receive(:allowed?).with(current_user, :manage_self_hosted_models_settings)
 
       request
     end
@@ -36,14 +38,14 @@
   context 'when user is not allowed to write changes' do
     let(:current_user) { create(:user) }
 
-    it_behaves_like 'it calls the manage_ai_settings policy'
+    it_behaves_like 'it calls the manage_self_hosted_models_settings policy'
     it_behaves_like 'a mutation that returns a top-level access error'
   end
 
   context 'when user is allowed to write changes' do
     let(:probe_graphql_result) { mutation_response['result'] }
 
-    it_behaves_like 'it calls the manage_ai_settings policy'
+    it_behaves_like 'it calls the manage_self_hosted_models_settings policy'
 
     context 'when there are errors with creating the self-hosted model' do
       let(:error_message) { 'API error' }
diff --git a/ee/spec/requests/api/graphql/ai/self_hosted_models/create_spec.rb b/ee/spec/requests/api/graphql/ai/self_hosted_models/create_spec.rb
index 18fe597811f73024d798a700e54fce88fe33c275..02ce94e8249589f13a429e9b0facff6b317e4c06 100644
--- a/ee/spec/requests/api/graphql/ai/self_hosted_models/create_spec.rb
+++ b/ee/spec/requests/api/graphql/ai/self_hosted_models/create_spec.rb
@@ -6,6 +6,10 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:admin) }
+  let_it_be(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
+  let_it_be(:add_on_purchase) do
+    create(:gitlab_subscription_add_on_purchase, :duo_enterprise, :active)
+  end
 
   let(:input) do
     {
@@ -23,11 +27,9 @@
   subject(:request) { post_graphql_mutation(mutation, current_user: current_user) }
 
   shared_examples 'it calls the manage_ai_settings policy' do
-    it 'calls the manage_ai_settings policy' do
+    it 'calls the manage_self_hosted_models_settings policy' do
       allow(::Ability).to receive(:allowed?).and_call_original
-
-      expect(::Ability).to receive(:allowed?)
-                             .with(current_user, :manage_ai_settings)
+      expect(::Ability).to receive(:allowed?).with(current_user, :manage_self_hosted_models_settings)
 
       request
     end
diff --git a/ee/spec/requests/api/graphql/ai/self_hosted_models/delete_spec.rb b/ee/spec/requests/api/graphql/ai/self_hosted_models/delete_spec.rb
index 20bbef9097fad7e2a4d8313f2224a855927a4a3a..d8ed56b639f01393db0604e7d87b8160277a69bc 100644
--- a/ee/spec/requests/api/graphql/ai/self_hosted_models/delete_spec.rb
+++ b/ee/spec/requests/api/graphql/ai/self_hosted_models/delete_spec.rb
@@ -6,6 +6,11 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:admin) }
+  let_it_be(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
+  let_it_be(:add_on_purchase) do
+    create(:gitlab_subscription_add_on_purchase, :duo_enterprise, :active)
+  end
+
   let_it_be(:self_hosted_model) do
     create(
       :ai_self_hosted_model,
diff --git a/ee/spec/requests/api/graphql/ai/self_hosted_models/self_hosted_models_spec.rb b/ee/spec/requests/api/graphql/ai/self_hosted_models/self_hosted_models_spec.rb
index 9382e8e74fac635e08325dc8896d831b802d4c6b..3864825fd7461fadd832f25de6fbaac35c5bd00c 100644
--- a/ee/spec/requests/api/graphql/ai/self_hosted_models/self_hosted_models_spec.rb
+++ b/ee/spec/requests/api/graphql/ai/self_hosted_models/self_hosted_models_spec.rb
@@ -6,6 +6,10 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:admin) }
+  let_it_be(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
+  let_it_be(:add_on_purchase) do
+    create(:gitlab_subscription_add_on_purchase, :duo_enterprise, :active)
+  end
 
   let! :model_params do
     [
@@ -38,18 +42,18 @@
 
   let(:query) do
     %(
-    query SelfHostedModel {
-      aiSelfHostedModels {
-        nodes {
-          id
-          name
-          model
-          modelDisplayName
-          endpoint
-          hasApiToken
+      query SelfHostedModel {
+        aiSelfHostedModels {
+          nodes {
+            id
+            name
+            model
+            modelDisplayName
+            endpoint
+            hasApiToken
+          }
         }
       }
-    }
     )
   end
 
@@ -84,18 +88,18 @@
     let(:self_hosted_model_gid) { self_hosted_models.first.to_global_id }
     let(:query) do
       %(
-      query SelfHostedModel {
-        aiSelfHostedModels(id: "#{self_hosted_model_gid}") {
-          nodes {
-            id
-            name
-            model
-            modelDisplayName
-            endpoint
-            apiToken
+        query SelfHostedModel {
+          aiSelfHostedModels(id: "#{self_hosted_model_gid}") {
+            nodes {
+              id
+              name
+              model
+              modelDisplayName
+              endpoint
+              apiToken
+            }
           }
         }
-      }
       )
     end
 
diff --git a/ee/spec/requests/api/graphql/ai/self_hosted_models/update_spec.rb b/ee/spec/requests/api/graphql/ai/self_hosted_models/update_spec.rb
index 1f7ec00c57b2accbdb0a35456f97a63187fc06dc..2a2c0dd687a255aea253cc3cea466f578115d27f 100644
--- a/ee/spec/requests/api/graphql/ai/self_hosted_models/update_spec.rb
+++ b/ee/spec/requests/api/graphql/ai/self_hosted_models/update_spec.rb
@@ -6,6 +6,11 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:admin) }
+  let_it_be(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
+  let_it_be(:add_on_purchase) do
+    create(:gitlab_subscription_add_on_purchase, :duo_enterprise, :active)
+  end
+
   let_it_be(:self_hosted_model) do
     create(
       :ai_self_hosted_model,
diff --git a/ee/spec/support/shared_examples/graphql/ai/self_hosted_models/self_hosted_models_examples.rb b/ee/spec/support/shared_examples/graphql/ai/self_hosted_models/self_hosted_models_examples.rb
index 09035bfc51a4f001e5f8e7b2996bcba996f24c14..250f4fe2c424f80e5de456163378cff7bdd9680e 100644
--- a/ee/spec/support/shared_examples/graphql/ai/self_hosted_models/self_hosted_models_examples.rb
+++ b/ee/spec/support/shared_examples/graphql/ai/self_hosted_models/self_hosted_models_examples.rb
@@ -5,7 +5,7 @@
 RSpec.shared_examples 'performs the right authorization' do
   it 'performs the right authorization correctly' do
     allow(Ability).to receive(:allowed?).and_call_original
-    expect(Ability).to receive(:allowed?).with(current_user, :manage_ai_settings)
+    expect(Ability).to receive(:allowed?).with(current_user, :manage_self_hosted_models_settings)
 
     request
   end