diff --git a/ee/app/controllers/groups/dependencies_controller.rb b/ee/app/controllers/groups/dependencies_controller.rb
index f3f99528c114c9dcd14623dea6a47e67ee500114..8e2f3df90e2cb814f7bdc4f118f660613006ff64 100644
--- a/ee/app/controllers/groups/dependencies_controller.rb
+++ b/ee/app/controllers/groups/dependencies_controller.rb
@@ -47,9 +47,10 @@ def collect_dependencies
     end
 
     def serialized_dependencies
-      DependencyListSerializer.new(
-        project: nil,
-        user: current_user).with_pagination(request, response).represent(collect_dependencies)
+      DependencyListSerializer
+        .new(project: nil, group: group, user: current_user)
+        .with_pagination(request, response)
+        .represent(collect_dependencies)
     end
 
     def render_not_authorized
diff --git a/ee/app/serializers/dependency_entity.rb b/ee/app/serializers/dependency_entity.rb
index 6e68a1b7d742521f1f4bc146cc9fefa6fd6b1372..85904264aeaf3177f311c0d5f261bb10055f1b48 100644
--- a/ee/app/serializers/dependency_entity.rb
+++ b/ee/app/serializers/dependency_entity.rb
@@ -18,6 +18,14 @@ class VulnerabilityEntity < Grape::Entity
 
   class LicenseEntity < Grape::Entity
     expose :name, :url
+
+    def name
+      object[:name] || object["name"]
+    end
+
+    def url
+      object[:url] || object["url"]
+    end
   end
 
   class ProjectEntity < Grape::Entity
@@ -28,8 +36,9 @@ class ProjectEntity < Grape::Entity
   expose :location, using: LocationEntity
   expose :vulnerabilities, using: VulnerabilityEntity, if: ->(_) { can_read_vulnerabilities? }
   expose :licenses, using: LicenseEntity, if: ->(_) { can_read_licenses? }
-  expose :project, using: ProjectEntity, if: ->(_) { !has_project? }
-  expose :project_count, :occurrence_count, :component_id, if: ->(_) { !has_project? }
+  expose :project, using: ProjectEntity, if: ->(_) { group? }
+  expose :project_count, :occurrence_count, if: ->(_) { group_counts? }
+  expose :component_id, if: ->(_) { group? }
 
   private
 
@@ -38,10 +47,21 @@ def can_read_vulnerabilities?
   end
 
   def can_read_licenses?
-    can?(request.user, :read_licenses, request.project)
+    (group? && Feature.enabled?(:group_level_licenses, group)) ||
+      can?(request.user, :read_licenses, request.project)
+  end
+
+  def group
+    request.respond_to?(:group) ? request.group : nil
+  end
+
+  def group?
+    group.present?
   end
 
-  def has_project?
-    !request.project.nil?
+  def group_counts?
+    group? &&
+      object.respond_to?(:project_count) &&
+      object.respond_to?(:occurrence_count)
   end
 end
diff --git a/ee/config/feature_flags/development/group_level_licenses.yml b/ee/config/feature_flags/development/group_level_licenses.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ac3d3dd0ce1a5bdf4a737b0b7cd94870f94cf310
--- /dev/null
+++ b/ee/config/feature_flags/development/group_level_licenses.yml
@@ -0,0 +1,8 @@
+---
+name: group_level_licenses
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130238
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/422978
+milestone: '16.4'
+type: development
+group: group::threat insights
+default_enabled: false
diff --git a/ee/spec/factories/sbom/occurrences.rb b/ee/spec/factories/sbom/occurrences.rb
index ccd2e48a445ed0776767ab608c1d76486d067782..5c7ddff4a299c082b0cdca930eb5aeec3255bb58 100644
--- a/ee/spec/factories/sbom/occurrences.rb
+++ b/ee/spec/factories/sbom/occurrences.rb
@@ -13,6 +13,32 @@
       packager_name { 'npm' }
     end
 
+    trait :bundler do
+      packager_name { 'bundler' }
+    end
+
+    trait :npm do
+      packager_name { 'npm' }
+    end
+
+    trait :apache_2 do
+      after(:build) do |occurrence|
+        occurrence.licenses.push({
+          'name' => 'Apache-2.0',
+          'url' => 'https://spdx.org/licenses/Apache-2.0.html'
+        })
+      end
+    end
+
+    trait :mit do
+      after(:build) do |occurrence|
+        occurrence.licenses.push({
+          'name' => 'MIT',
+          'url' => 'https://spdx.org/licenses/MIT.html'
+        })
+      end
+    end
+
     after(:build) do |occurrence|
       occurrence.uuid = Sbom::OccurrenceUUID.generate(
         project_id: occurrence.project.id,
diff --git a/ee/spec/requests/groups/dependencies_controller_spec.rb b/ee/spec/requests/groups/dependencies_controller_spec.rb
index 78cce786576621e0494dc3404236b566abc6bb90..4582fc7fcc2ca225e1f6d0e9293eae52214d4e4c 100644
--- a/ee/spec/requests/groups/dependencies_controller_spec.rb
+++ b/ee/spec/requests/groups/dependencies_controller_spec.rb
@@ -126,8 +126,8 @@
 
           context 'with existing dependencies' do
             let_it_be(:project) { create(:project, group: group) }
-            let_it_be(:sbom_occurrence_npm) { create(:sbom_occurrence, project: project, packager_name: 'npm') }
-            let_it_be(:sbom_occurrence_bundler) { create(:sbom_occurrence, project: project, packager_name: 'bundler') }
+            let_it_be(:sbom_occurrence_npm) { create(:sbom_occurrence, :mit, :npm, project: project) }
+            let_it_be(:sbom_occurrence_bundler) { create(:sbom_occurrence, :apache_2, :bundler, project: project) }
 
             let(:expected_response) do
               {
@@ -140,6 +140,12 @@
                     'name' => sbom_occurrence_npm.name,
                     'packager' => sbom_occurrence_npm.packager,
                     'version' => sbom_occurrence_npm.version,
+                    'licenses' => [
+                      {
+                        'name' => 'MIT',
+                        'url' => 'https://spdx.org/licenses/MIT.html'
+                      }
+                    ],
                     'occurrence_count' => 1,
                     'project_count' => 1,
                     "project" => { "full_path" => project.full_path, "name" => project.name },
@@ -150,6 +156,12 @@
                     'name' => sbom_occurrence_bundler.name,
                     'packager' => sbom_occurrence_bundler.packager,
                     'version' => sbom_occurrence_bundler.version,
+                    'licenses' => [
+                      {
+                        'name' => 'Apache-2.0',
+                        'url' => 'https://spdx.org/licenses/Apache-2.0.html'
+                      }
+                    ],
                     'occurrence_count' => 1,
                     'project_count' => 1,
                     "project" => { "full_path" => project.full_path, "name" => project.name },
@@ -159,6 +171,12 @@
               }
             end
 
+            it 'returns the expected response' do
+              subject
+
+              expect(json_response).to eq(expected_response)
+            end
+
             it 'includes pagination headers in the response' do
               subject
 
diff --git a/ee/spec/serializers/dependency_entity_spec.rb b/ee/spec/serializers/dependency_entity_spec.rb
index d54692f29597a476ce2c7a7d04f20e23a6e01d57..169e7faf54bbce8a2202c16465386d9336d2a681 100644
--- a/ee/spec/serializers/dependency_entity_spec.rb
+++ b/ee/spec/serializers/dependency_entity_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-RSpec.describe DependencyEntity do
+RSpec.describe DependencyEntity, feature_category: :dependency_management do
   describe '#as_json' do
     subject { described_class.represent(dependency, request: request).as_json }
 
@@ -49,10 +49,12 @@
       end
 
       context 'with project' do
+        let(:project) { create(:project, :repository, :private, :in_group) }
         let(:dependency) { build(:dependency, project: project) }
 
         before do
           allow(request).to receive(:project).and_return(nil)
+          allow(request).to receive(:group).and_return(project.group)
         end
 
         it 'includes project name and full_path' do
@@ -70,6 +72,7 @@
 
     context 'when all required features are unavailable' do
       before do
+        stub_feature_flags(group_level_licenses: false)
         project.add_developer(user)
       end
 
@@ -89,5 +92,36 @@
         expect(location[:path]).to eq('package_file.lock')
       end
     end
+
+    context 'with an Sbom::Occurrence' do
+      subject { described_class.represent(sbom_occurrence, request: request).as_json }
+
+      let(:project) { create(:project, :repository, :private, :in_group) }
+      let(:sbom_occurrence) { create(:sbom_occurrence, :mit, :bundler, project: project) }
+
+      before do
+        allow(request).to receive(:group).and_return(project.group)
+      end
+
+      it 'renders the proper representation' do
+        expect(subject.as_json).to eq({
+          "name" => sbom_occurrence.name,
+          "packager" => sbom_occurrence.packager,
+          "project" => {
+            "name" => project.name,
+            "full_path" => project.full_path
+          },
+          "version" => sbom_occurrence.version,
+          "licenses" => sbom_occurrence.licenses,
+          "component_id" => sbom_occurrence.component_id,
+          "location" => {
+            "ancestors" => nil,
+            "blob_path" => sbom_occurrence.location[:blob_path],
+            "path" => sbom_occurrence.location[:path],
+            "top_level" => sbom_occurrence.location[:top_level]
+          }
+        })
+      end
+    end
   end
 end