diff --git a/app/models/ability.rb b/app/models/ability.rb
index c89cc9b2e17aedee592ec411d4781ed96d1a4703..ac5e82c14d224e3ee69b2557f73759fdda8b2a5e 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -61,6 +61,9 @@ class Ability
     private
 
     def uncached_allowed(user, subject)
+      policy_class = BasePolicy.class_for(subject) rescue nil
+      return policy_class.abilities(user, subject) if policy_class
+
       return anonymous_abilities(subject) if user.nil?
       return [] unless user.is_a?(User)
       return [] if user.blocked?
@@ -70,13 +73,6 @@ class Ability
 
     def abilities_by_subject_class(user:, subject:)
       case subject
-      when Project then ProjectPolicy.abilities(user, subject)
-      when Issue then IssuePolicy.abilities(user, subject)
-      when MergeRequest then MergeRequestPolicy.abilities(user, subject)
-
-      when Ci::Build then Ci::BuildPolicy.abilities(user, subject)
-      when CommitStatus then CommitStatus.abilities(user, subject)
-      when Note then note_abilities(user, subject)
       when ProjectSnippet then project_snippet_abilities(user, subject)
       when PersonalSnippet then personal_snippet_abilities(user, subject)
       when Group then group_abilities(user, subject)
@@ -96,14 +92,6 @@ class Ability
         anonymous_personal_snippet_abilities(subject)
       elsif subject.is_a?(ProjectSnippet)
         anonymous_project_snippet_abilities(subject)
-      elsif subject.is_a?(CommitStatus)
-        anonymous_commit_status_abilities(subject)
-      elsif subject.is_a?(Project)
-        ProjectPolicy.abilities(nil, subject)
-      elsif subject.is_a?(Issue)
-        IssuePolicy.abilities(nil, subject)
-      elsif subject.is_a?(MergeRequest)
-        MergeRequestPolicy.abilities(nil, subject)
       elsif subject.respond_to?(:project)
         ProjectPolicy.abilities(nil, subject.project)
       elsif subject.is_a?(Group) || subject.respond_to?(:group)
diff --git a/app/policies/base_policy.rb b/app/policies/base_policy.rb
index e1757d97e89f2ee71485fdb15223667bf5c985a5..12f60d8f76efd74e5329ab3e3120b0ab753f24af 100644
--- a/app/policies/base_policy.rb
+++ b/app/policies/base_policy.rb
@@ -4,7 +4,21 @@ class BasePolicy
   end
 
   def self.class_for(subject)
-    "#{subject.class.name}Policy".constantize
+    subject.class.ancestors.each do |klass|
+      next unless klass.name
+
+      begin
+        policy_class = "#{klass.name}Policy".constantize
+
+        # NB: the < operator here tests whether policy_class
+        # inherits from BasePolicy
+        return policy_class if policy_class < BasePolicy
+      rescue NameError
+        nil
+      end
+    end
+
+    raise "no policy for #{subject.class.name}"
   end
 
   attr_reader :user, :subject