diff --git a/app/models/members/members/invited_private_group_accessibility_assigner.rb b/app/models/members/members/invited_private_group_accessibility_assigner.rb
index 91ff703f68a8e429923615905b4bfe1dab41cff6..8ac1600f6e53be2dcd12ab8deac968ef6d678cf7 100644
--- a/app/models/members/members/invited_private_group_accessibility_assigner.rb
+++ b/app/models/members/members/invited_private_group_accessibility_assigner.rb
@@ -23,13 +23,14 @@ def initialize(members, source:, current_user:)
     end
 
     def execute
+      return if Feature.disabled?(:webui_members_inherited_users, current_user)
+
       # We don't need to calculate the access level of the current user in the invited groups if:
       #
       # 1. The current user can admin members then the user should be able to see the source of all memberships
       #    to enable management of group/project memberships.
       # 2. There are no members invited from a private group.
       return if can_admin_members? || private_invited_group_members.nil?
-      return if Feature.disabled?(:webui_members_inherited_users, current_user)
 
       private_invited_group_members.each do |member|
         member.is_source_accessible_to_current_user = authorized_groups.include?(member.source)
@@ -56,11 +57,20 @@ def private_invited_group_members
         member.is_a?(GroupMember) &&
           member.source.visibility_level != Gitlab::VisibilityLevel::PUBLIC &&
           member.source_id != source.id && # Exclude direct member
-          member.source.traversal_ids.exclude?(source.id) # Exclude inherited member
+          source_traversal_ids.exclude?(member.source_id) # Exclude inherited member
       end
     end
     strong_memoize_attr(:private_invited_group_members)
 
+    def source_traversal_ids
+      if source.is_a?(Project)
+        source.namespace.traversal_ids
+      else
+        source.traversal_ids
+      end
+    end
+    strong_memoize_attr(:source_traversal_ids)
+
     def can_admin_members?
       return can?(current_user, :admin_project_member, source) if source.is_a?(Project)
 
diff --git a/spec/features/groups/members/list_members_spec.rb b/spec/features/groups/members/list_members_spec.rb
index b6e0deb2e7335472d725fc8b5a213f2c0f4a4ab4..63d201be52ade9b141bc86437940fd1756aeb60a 100644
--- a/spec/features/groups/members/list_members_spec.rb
+++ b/spec/features/groups/members/list_members_spec.rb
@@ -34,6 +34,40 @@
     expect(second_row).to be_blank
   end
 
+  context 'for private groups' do
+    let(:group) { create(:group, :private, developers: user1) }
+    let(:nested_group) { create(:group, :private, parent: group, developers: user2) }
+
+    before do
+      sign_in(user2)
+    end
+
+    shared_examples 'direct or inherited member' do
+      it 'sees the sources of inherited members' do
+        visit group_group_members_path(nested_group)
+
+        expect(first_row.text).to include(user1.name, group.name)
+        expect(second_row.text).to include(user2.name)
+      end
+    end
+
+    context 'when signed in using parent group member' do
+      before do
+        sign_in(user1)
+      end
+
+      it_behaves_like 'direct or inherited member'
+    end
+
+    context 'when signed in using subgroup member' do
+      before do
+        sign_in(user2)
+      end
+
+      it_behaves_like 'direct or inherited member'
+    end
+  end
+
   describe 'showing status of members' do
     before do
       group.add_developer(user2)
diff --git a/spec/models/members/members/invited_private_group_accessibility_assigner_spec.rb b/spec/models/members/members/invited_private_group_accessibility_assigner_spec.rb
index ac787d11ef690de734becaba997837ff3147343d..ef32c8fbb19f8517b8f579cf19e8106b7f093493 100644
--- a/spec/models/members/members/invited_private_group_accessibility_assigner_spec.rb
+++ b/spec/models/members/members/invited_private_group_accessibility_assigner_spec.rb
@@ -14,28 +14,51 @@
 
       subject(:assigner) { described_class.new(members, source: source, current_user: current_user) }
 
+      shared_examples 'sets is_source_accessible_to_current_user to true for all members' do
+        specify do
+          assigner.execute
+
+          expect(members.first.is_source_accessible_to_current_user).to eq(true)
+        end
+      end
+
       context 'for direct members' do
-        let_it_be(:source) { create(source_type) } # rubocop:disable Rails/SaveBang -- Using factory, not ActiveRecord
-        let_it_be(:direct_member) { source.add_developer(member_user) }
-        let(:members) { [direct_member] }
+        where(source_visibility: %i[public private])
 
-        it 'sets is_source_accessible_to_current_user to true for all members' do
-          assigner.execute
+        with_them do
+          let(:source) { create(source_type, source_visibility) }
+          let(:direct_member) { source.add_developer(member_user) }
+          let(:members) { [direct_member] }
+          it_behaves_like 'sets is_source_accessible_to_current_user to true for all members'
 
-          expect(members.map(&:is_source_accessible_to_current_user)).to all(be_truthy)
+          context 'with webui_members_inherited_users feature flag disabled' do
+            before do
+              stub_feature_flags(webui_members_inherited_users: false)
+            end
+
+            it_behaves_like 'sets is_source_accessible_to_current_user to true for all members'
+          end
         end
       end
 
       context 'for inherited members' do
-        let_it_be(:parent) { create(:group) }
-        let_it_be(:source) { create(source_type, parent_key => parent) }
-        let_it_be(:inherited_member) { parent.add_developer(member_user) }
-        let(:members) { [inherited_member] }
+        where(source_visibility: %i[public private])
 
-        it 'sets is_source_accessible_to_current_user to true for all members' do
-          assigner.execute
+        with_them do
+          let(:parent) { create(:group, source_visibility) }
+          let(:source) { create(source_type, source_visibility, parent_key => parent) }
+          let(:inherited_member) { parent.add_developer(member_user) }
+          let(:members) { [inherited_member] }
 
-          expect(members.first.is_source_accessible_to_current_user).to eq(true)
+          it_behaves_like 'sets is_source_accessible_to_current_user to true for all members'
+
+          context 'with webui_members_inherited_users feature flag disabled' do
+            before do
+              stub_feature_flags(webui_members_inherited_users: false)
+            end
+
+            it_behaves_like 'sets is_source_accessible_to_current_user to true for all members'
+          end
         end
       end
 
@@ -56,6 +79,14 @@
               expect(members.first.is_source_accessible_to_current_user).to eq(can_see_invited_members_source?)
             end
 
+            context 'with webui_members_inherited_users feature flag disabled' do
+              before do
+                stub_feature_flags(webui_members_inherited_users: false)
+              end
+
+              it_behaves_like 'sets is_source_accessible_to_current_user to true for all members'
+            end
+
             context 'with multiple members belonging to the same source' do
               it 'avoid N+1 queries' do
                 assigner # Initialize objects in let blocks
@@ -107,8 +138,7 @@
 
         context 'when current user is a direct member of shared group and of invited group through sharing' do
           before do
-            group = create(:group, :private)
-            group.add_developer(current_user)
+            group = create(:group, :private, developers: current_user)
             create(:group_group_link, shared_group: invited_group, shared_with_group: group)
           end