diff --git a/ee/app/models/compliance_management/framework.rb b/ee/app/models/compliance_management/framework.rb
index 76f6b162e44a03128dfc1c46374ea9b940f8a9e2..a1e801d5d380dc407fe48e5a836d79f10e73b342 100644
--- a/ee/app/models/compliance_management/framework.rb
+++ b/ee/app/models/compliance_management/framework.rb
@@ -22,7 +22,18 @@ class Framework < ApplicationRecord
     validates :namespace_id, uniqueness: { scope: :name }
     validates :pipeline_configuration_full_path, length: { maximum: 255 }
 
+    # Remove this validation once support for user namespaces is added.
+    # https://gitlab.com/gitlab-org/gitlab/-/issues/358423
+    validate :namespace_is_root_level_group
+
     scope :with_projects, ->(project_ids) { includes(:projects).where(projects: { id: project_ids }) }
     scope :with_namespaces, ->(namespace_ids) { includes(:namespace).where(namespaces: { id: namespace_ids })}
+
+    private
+
+    def namespace_is_root_level_group
+      errors.add(:namespace, 'must be a group, user namespaces are not supported.') unless namespace.group_namespace?
+      errors.add(:namespace, 'must be a root group.') if namespace.has_parent?
+    end
   end
 end
diff --git a/ee/spec/controllers/projects_controller_spec.rb b/ee/spec/controllers/projects_controller_spec.rb
index fa58e4e36f5414108cfa95b043b1e62ea141cf3d..225cee28534e6926db1216001d6b61612514ffe3 100644
--- a/ee/spec/controllers/projects_controller_spec.rb
+++ b/ee/spec/controllers/projects_controller_spec.rb
@@ -526,11 +526,14 @@
     end
 
     context 'compliance framework settings' do
+      let(:group) { create(:group) }
+      let(:project) { create(:project, group: group) }
+
       shared_examples 'no compliance framework is set' do
         it 'does not change compliance framework for project' do
           put :update,
               params: {
-                namespace_id: project.namespace,
+                namespace_id: project.group,
                 id: project,
                 project: params
               }
@@ -541,7 +544,7 @@
       end
 
       context 'when unlicensed' do
-        let(:framework) { create(:compliance_framework, namespace: project.namespace.root_ancestor) }
+        let(:framework) { create(:compliance_framework, namespace: project.group.root_ancestor) }
         let(:params) { { compliance_framework_setting_attributes: { framework: framework.id } } }
 
         before do
@@ -552,22 +555,23 @@
       end
 
       context 'when licensed' do
-        let(:framework) { create(:compliance_framework, namespace: project.namespace.root_ancestor) }
+        let(:framework) { create(:compliance_framework, namespace: project.group.root_ancestor) }
         let(:params) { { compliance_framework_setting_attributes: { framework: framework.id } } }
 
         before do
           stub_licensed_features(compliance_framework: true)
+          project.add_owner(user)
         end
 
         context 'current_user is a project owner' do
           before do
-            sign_in(project.first_owner)
+            sign_in(user)
           end
 
           it 'sets the compliance framework' do
             put :update,
                 params: {
-                  namespace_id: project.namespace,
+                  namespace_id: project.group,
                   id: project,
                   project: params
                 }
diff --git a/ee/spec/graphql/mutations/compliance_management/frameworks/create_spec.rb b/ee/spec/graphql/mutations/compliance_management/frameworks/create_spec.rb
index 42b8e8db919aba59ffee36d9833aa633ac0e67e5..b64c8444bcd78752b0f6e98860e258e1425674b8 100644
--- a/ee/spec/graphql/mutations/compliance_management/frameworks/create_spec.rb
+++ b/ee/spec/graphql/mutations/compliance_management/frameworks/create_spec.rb
@@ -4,7 +4,7 @@
 
 RSpec.describe Mutations::ComplianceManagement::Frameworks::Create do
   let_it_be(:current_user) { create(:user) }
-  let_it_be(:namespace) { create(:namespace) }
+  let_it_be(:namespace) { create(:group) }
 
   let(:params) { valid_params }
   let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) }
@@ -31,7 +31,7 @@
         stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: true)
       end
 
-      context 'current_user is not namespace owner' do
+      context 'current_user is not group namespace owner' do
         it 'does not create a new compliance framework' do
           expect { subject }.not_to change { namespace.compliance_management_frameworks.count }
         end
@@ -42,8 +42,6 @@
       end
 
       context 'current_user is group owner' do
-        let_it_be(:namespace) { create(:group) }
-
         before do
           namespace.add_owner(current_user)
         end
@@ -53,12 +51,14 @@
         end
       end
 
-      context 'current_user is namespace owner' do
+      context 'current_user is personal namespace owner' do
+        let_it_be(:namespace) { create(:user_namespace) }
+
         let(:current_user) { namespace.owner }
 
         context 'framework parameters are valid' do
-          it 'creates a new compliance framework' do
-            expect { subject }.to change { namespace.compliance_management_frameworks.count }.by 1
+          it 'does not create a new compliance framework' do
+            expect { subject }.not_to change { namespace.compliance_management_frameworks.count }
           end
         end
 
diff --git a/ee/spec/graphql/mutations/projects/set_compliance_framework_spec.rb b/ee/spec/graphql/mutations/projects/set_compliance_framework_spec.rb
index b52a4a4f9d16ac63a20b8551999a33e459161377..e36d14f6388d7cf50afb0a45dc1d0cafcef59e88 100644
--- a/ee/spec/graphql/mutations/projects/set_compliance_framework_spec.rb
+++ b/ee/spec/graphql/mutations/projects/set_compliance_framework_spec.rb
@@ -3,9 +3,9 @@
 require 'spec_helper'
 
 RSpec.describe Mutations::Projects::SetComplianceFramework do
-  let_it_be(:namespace) { create(:namespace) }
-  let_it_be(:framework) { create(:compliance_framework, namespace: namespace) }
-  let_it_be(:project) { create(:project, :repository, namespace: namespace) }
+  let_it_be(:group) { create(:group) }
+  let_it_be(:framework) { create(:compliance_framework, namespace: group) }
+  let_it_be(:project) { create(:project, :repository, group: group) }
   let_it_be(:current_user) { create(:user) }
 
   let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) }
@@ -67,7 +67,10 @@
       end
 
       context 'current_user is a project owner' do
-        let(:current_user) { project.first_owner }
+        before do
+          group.add_owner(current_user)
+          project.add_owner(current_user)
+        end
 
         it_behaves_like "the user can change a project's compliance framework"
       end
diff --git a/ee/spec/lib/ee/audit/compliance_framework_changes_auditor_spec.rb b/ee/spec/lib/ee/audit/compliance_framework_changes_auditor_spec.rb
index 67876a0b77750d376d016c166b9234e929c713b9..3869f7edce4bac8f8f620ee3c89c6969b0c6f4c9 100644
--- a/ee/spec/lib/ee/audit/compliance_framework_changes_auditor_spec.rb
+++ b/ee/spec/lib/ee/audit/compliance_framework_changes_auditor_spec.rb
@@ -5,8 +5,9 @@
 RSpec.describe EE::Audit::ComplianceFrameworkChangesAuditor do
   describe 'auditing compliance framework changes' do
     let_it_be(:user) { create(:user) }
+    let_it_be(:group) { create(:group) }
 
-    let(:project) { create(:project) }
+    let(:project) { create(:project, group: group) }
 
     before do
       project.reload
@@ -54,7 +55,7 @@
 
       context 'when the framework is changed' do
         before do
-          project.update!(compliance_management_framework: create(:compliance_framework, namespace: project.namespace, name: 'SOX'))
+          project.update!(compliance_management_framework: create(:compliance_framework, namespace: project.group, name: 'SOX'))
         end
 
         it 'adds an audit event' do
diff --git a/ee/spec/models/compliance_management/framework_spec.rb b/ee/spec/models/compliance_management/framework_spec.rb
index ca7d9c5b6d1b7ea96e05cf17ae3148411b02ff64..f79d85f32acf4a0f2d2220046201e0e5b4163266 100644
--- a/ee/spec/models/compliance_management/framework_spec.rb
+++ b/ee/spec/models/compliance_management/framework_spec.rb
@@ -3,7 +3,7 @@
 require 'spec_helper'
 
 RSpec.describe ComplianceManagement::Framework do
-  context 'validation' do
+  describe 'validations' do
     let_it_be(:framework) { create(:compliance_framework) }
 
     subject { framework }
@@ -14,6 +14,37 @@
     it { is_expected.to validate_length_of(:description).is_at_most(255) }
     it { is_expected.to validate_length_of(:color).is_at_most(10) }
     it { is_expected.to validate_length_of(:pipeline_configuration_full_path).is_at_most(255) }
+
+    describe 'namespace_is_root_level_group' do
+      context 'when namespace is a root group' do
+        let_it_be(:namespace) { create(:group) }
+        let_it_be(:framework) { build(:compliance_framework, namespace: namespace) }
+
+        it 'is valid' do
+          expect(framework).to be_valid
+        end
+      end
+
+      context 'when namespace is a user namespace' do
+        let_it_be(:namespace) { create(:user_namespace) }
+        let_it_be(:framework) { build(:compliance_framework, namespace: namespace) }
+
+        it 'is invalid' do
+          expect(framework).not_to be_valid
+          expect(framework.errors[:namespace]).to include('must be a group, user namespaces are not supported.')
+        end
+      end
+
+      context 'when namespace is a subgroup' do
+        let_it_be(:namespace) { create(:group, :nested) }
+        let_it_be(:framework) { build(:compliance_framework, namespace: namespace) }
+
+        it 'is invalid' do
+          expect(framework).not_to be_valid
+          expect(framework.errors[:namespace]).to include('must be a root group.')
+        end
+      end
+    end
   end
 
   describe 'color' do
diff --git a/ee/spec/requests/api/graphql/mutations/compliance_management/frameworks/create_spec.rb b/ee/spec/requests/api/graphql/mutations/compliance_management/frameworks/create_spec.rb
index b7a3638f5d5909838a04f6672b793f26a5a7e4bd..dc7b1dc83ee065dd7fbdd5e31500d007075120c6 100644
--- a/ee/spec/requests/api/graphql/mutations/compliance_management/frameworks/create_spec.rb
+++ b/ee/spec/requests/api/graphql/mutations/compliance_management/frameworks/create_spec.rb
@@ -5,8 +5,8 @@
 RSpec.describe 'Create a Compliance Framework' do
   include GraphqlHelpers
 
-  let_it_be(:namespace) { create(:namespace) }
-  let_it_be(:current_user) { namespace.owner }
+  let_it_be(:namespace) { create(:group) }
+  let_it_be(:current_user) { create(:user) }
 
   let(:mutation) do
     graphql_mutation(
@@ -54,6 +54,7 @@ def mutation_response
   context 'pipeline configuration feature is unlicensed' do
     before do
       stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: false)
+      namespace.add_owner(current_user)
       post_graphql_mutation(mutation, current_user: current_user)
     end
 
@@ -65,29 +66,43 @@ def mutation_response
       stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: true)
     end
 
-    context 'current_user is namespace owner' do
-      it_behaves_like 'a mutation that creates a compliance framework'
-    end
+    context 'namespace is a personal namespace' do
+      let_it_be(:namespace) { create(:user_namespace) }
 
-    context 'current_user is group owner' do
-      let_it_be(:namespace) { create(:group) }
-      let_it_be(:current_user) { create(:user) }
+      context 'current_user is namespace owner' do
+        let(:current_user) { namespace.owner }
 
-      before do
-        namespace.add_owner(current_user)
-      end
+        it_behaves_like 'a mutation that returns errors in the response', errors: ['Failed to create framework',
+                                                                                   'Namespace must be a group, user namespaces are not supported.']
 
-      it_behaves_like 'a mutation that creates a compliance framework'
+        it 'does not create a new compliance framework' do
+          expect { subject }.not_to change { namespace.compliance_management_frameworks.count }
+        end
+      end
     end
 
-    context 'current_user is not namespace owner' do
-      let_it_be(:current_user) { create(:user) }
+    context 'namespace is a group' do
+      context 'current_user is group owner' do
+        before do
+          namespace.add_owner(current_user)
+        end
 
-      it 'does not create a new compliance framework' do
-        expect { subject }.not_to change { namespace.compliance_management_frameworks.count }
+        it_behaves_like 'a mutation that creates a compliance framework'
       end
 
-      it_behaves_like 'a mutation that returns errors in the response', errors: ['Not permitted to create framework']
+      context 'current_user is not a group owner' do
+        context 'current_user is group owner' do
+          before do
+            namespace.add_maintainer(current_user)
+          end
+
+          it 'does not create a new compliance framework' do
+            expect { subject }.not_to change { namespace.compliance_management_frameworks.count }
+          end
+
+          it_behaves_like 'a mutation that returns errors in the response', errors: ['Not permitted to create framework']
+        end
+      end
     end
   end
 end
diff --git a/ee/spec/requests/api/graphql/mutations/projects/set_compliance_framework_spec.rb b/ee/spec/requests/api/graphql/mutations/projects/set_compliance_framework_spec.rb
index 66fb84f17a6f459cc3a56e6d59eaea70c3fa38ff..72076e5db4fd1ef9ed37e88bdd4c9078e83fbacd 100644
--- a/ee/spec/requests/api/graphql/mutations/projects/set_compliance_framework_spec.rb
+++ b/ee/spec/requests/api/graphql/mutations/projects/set_compliance_framework_spec.rb
@@ -5,10 +5,14 @@
 RSpec.describe 'Set project compliance framework' do
   include GraphqlHelpers
 
-  let_it_be(:namespace) { create(:namespace) }
+  let_it_be(:namespace) { create(:group) }
   let_it_be(:project) { create(:project, namespace: namespace) }
   let_it_be(:framework) { create(:compliance_framework, namespace: namespace) }
-  let_it_be(:current_user) { project.first_owner }
+  let_it_be(:current_user) { create(:user) }
+
+  before do
+    namespace.add_owner(current_user)
+  end
 
   let(:variables) { { project_id: GitlabSchema.id_from_object(project).to_s, compliance_framework_id: GitlabSchema.id_from_object(framework).to_s } }
 
diff --git a/ee/spec/requests/api/graphql/namespace/compliance_frameworks_spec.rb b/ee/spec/requests/api/graphql/namespace/compliance_frameworks_spec.rb
index d96845aa264c1b548bb963aea2c63480c5dd38be..c31f1d3b1c324cc89f223bdbce5956de693d5578 100644
--- a/ee/spec/requests/api/graphql/namespace/compliance_frameworks_spec.rb
+++ b/ee/spec/requests/api/graphql/namespace/compliance_frameworks_spec.rb
@@ -5,9 +5,10 @@
 RSpec.describe 'getting a list of compliance frameworks for a root namespace' do
   include GraphqlHelpers
 
-  let_it_be(:namespace) { create(:namespace) }
+  let_it_be(:namespace) { create(:group) }
   let_it_be(:compliance_framework_1) { create(:compliance_framework, namespace: namespace, name: 'Test1') }
   let_it_be(:compliance_framework_2) { create(:compliance_framework, namespace: namespace, name: 'Test2') }
+  let_it_be(:current_user) { create(:user) }
 
   let(:path) { %i[namespace compliance_frameworks nodes] }
 
@@ -20,10 +21,9 @@
   context 'when authenticated as the namespace owner' do
     before do
       stub_licensed_features(custom_compliance_frameworks: true)
+      namespace.add_owner(current_user)
     end
 
-    let(:current_user) { namespace.owner }
-
     it 'returns the groups compliance frameworks' do
       post_graphql(query, current_user: current_user)
 
diff --git a/ee/spec/services/compliance_management/frameworks/create_service_spec.rb b/ee/spec/services/compliance_management/frameworks/create_service_spec.rb
index 9b74a3a6cb2a1b53384f0398d3d1be0392751b40..0585cf152188f658d691e9d2077466bbb1210eae 100644
--- a/ee/spec/services/compliance_management/frameworks/create_service_spec.rb
+++ b/ee/spec/services/compliance_management/frameworks/create_service_spec.rb
@@ -3,7 +3,12 @@
 require 'spec_helper'
 
 RSpec.describe ComplianceManagement::Frameworks::CreateService do
-  let_it_be_with_refind(:namespace) { create(:user_namespace) }
+  let_it_be_with_refind(:namespace) { create(:group) }
+  let_it_be(:current_user) { create(:user) }
+
+  before do
+    namespace.add_owner(current_user)
+  end
 
   let(:params) do
     {
@@ -18,7 +23,7 @@
       stub_licensed_features(custom_compliance_frameworks: false)
     end
 
-    subject { described_class.new(namespace: namespace, params: params, current_user: namespace.owner) }
+    subject { described_class.new(namespace: namespace, params: params, current_user: current_user) }
 
     it 'does not create a new compliance framework' do
       expect { subject.execute }.not_to change { ComplianceManagement::Framework.count }
@@ -56,7 +61,7 @@
     end
 
     context 'when using invalid parameters' do
-      subject { described_class.new(namespace: namespace, params: params.except(:name), current_user: namespace.owner) }
+      subject { described_class.new(namespace: namespace, params: params.except(:name), current_user: current_user) }
 
       let(:response) { subject.execute }
 
@@ -79,7 +84,7 @@
     end
 
     context 'when pipeline_configuration_full_path parameter is used and feature is not available' do
-      subject { described_class.new(namespace: namespace, params: params, current_user: namespace.owner) }
+      subject { described_class.new(namespace: namespace, params: params, current_user: current_user) }
 
       before do
         params[:pipeline_configuration_full_path] = '.compliance-gitlab-ci.yml@compliance/hipaa'
@@ -95,7 +100,7 @@
     end
 
     context 'when using parameters for a valid compliance framework' do
-      subject { described_class.new(namespace: namespace, params: params, current_user: namespace.owner) }
+      subject { described_class.new(namespace: namespace, params: params, current_user: current_user) }
 
       it 'audits the changes' do
         expect { subject.execute }.to change { AuditEvent.count }.by(1)
diff --git a/ee/spec/services/compliance_management/frameworks/destroy_service_spec.rb b/ee/spec/services/compliance_management/frameworks/destroy_service_spec.rb
index fffc9d5e91820f29726cf4642d3ea96000568baa..ca07c1a4c28ee33808aec2749810352e4c19e2d7 100644
--- a/ee/spec/services/compliance_management/frameworks/destroy_service_spec.rb
+++ b/ee/spec/services/compliance_management/frameworks/destroy_service_spec.rb
@@ -3,15 +3,20 @@
 require 'spec_helper'
 
 RSpec.describe ComplianceManagement::Frameworks::DestroyService do
-  let_it_be_with_refind(:namespace) { create(:user_namespace) }
+  let_it_be_with_refind(:namespace) { create(:group) }
   let_it_be_with_refind(:framework) { create(:compliance_framework, namespace: namespace) }
+  let_it_be(:user) { create(:user) }
+
+  before do
+    namespace.add_owner(user)
+  end
 
   context 'when feature is disabled' do
     before do
       stub_licensed_features(custom_compliance_frameworks: false)
     end
 
-    subject { described_class.new(framework: framework, current_user: namespace.owner) }
+    subject { described_class.new(framework: framework, current_user: user) }
 
     it 'does not destroy the compliance framework' do
       expect { subject.execute }.not_to change { ComplianceManagement::Framework.count }
@@ -28,7 +33,7 @@
     end
 
     context 'when current user is namespace owner' do
-      subject { described_class.new(framework: framework, current_user: namespace.owner) }
+      subject { described_class.new(framework: framework, current_user: user) }
 
       it 'destroys the compliance framework' do
         expect { subject.execute }.to change { ComplianceManagement::Framework.count }.by(-1)
diff --git a/ee/spec/services/compliance_management/frameworks/update_service_spec.rb b/ee/spec/services/compliance_management/frameworks/update_service_spec.rb
index f7c0177e49811605bc9233edf239f84a4c8d1810..c242d1c244ddda4351bec732f07bf967b0432e98 100644
--- a/ee/spec/services/compliance_management/frameworks/update_service_spec.rb
+++ b/ee/spec/services/compliance_management/frameworks/update_service_spec.rb
@@ -3,10 +3,14 @@
 require 'spec_helper'
 
 RSpec.describe ComplianceManagement::Frameworks::UpdateService do
-  let_it_be_with_refind(:namespace) { create(:user_namespace) }
+  let_it_be_with_refind(:namespace) { create(:group) }
   let_it_be_with_refind(:framework) { create(:compliance_framework, namespace: namespace) }
+  let_it_be(:current_user) { create(:user) }
+
+  before do
+    namespace.add_owner(current_user)
+  end
 
-  let(:current_user) { namespace.owner }
   let(:params) { { color: '#000001', description: 'New Description', name: 'New Name' } }
 
   subject { described_class.new(framework: framework, current_user: current_user, params: params) }
diff --git a/ee/spec/services/projects/update_service_spec.rb b/ee/spec/services/projects/update_service_spec.rb
index 5b4107207cc89dfa329f0bd26e34957bc6ee5ae4..5d1dba4e756f85e02c95a956ebb43231ce71fc03 100644
--- a/ee/spec/services/projects/update_service_spec.rb
+++ b/ee/spec/services/projects/update_service_spec.rb
@@ -348,12 +348,16 @@
   end
 
   context 'custom compliance frameworks' do
-    let(:framework) { create(:compliance_framework, namespace: project.namespace) }
+    let(:group) { create(:group) }
+    let(:project) { create(:project, group: group) }
+    let(:framework) { create(:compliance_framework, namespace: group) }
     let(:opts) { { compliance_framework_setting_attributes: { framework: framework.id } } }
 
     context 'when current_user has :admin_compliance_framework ability' do
       before do
         stub_licensed_features(compliance_framework: true)
+        group.add_owner(user)
+        project.add_owner(user)
       end
 
       it 'updates the framework' do