diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md
index 05a118d40d1fd63602b54cc8955f2c5e659ba34c..de7924463fd389e5edb8304834f310581c8ab580 100644
--- a/doc/api/graphql/reference/_index.md
+++ b/doc/api/graphql/reference/_index.md
@@ -5255,6 +5255,29 @@ Input type: `DestroyComplianceRequirementInput`
 | <a id="mutationdestroycompliancerequirementclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
 | <a id="mutationdestroycompliancerequirementerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
 
+### `Mutation.destroyComplianceRequirementsControl`
+
+{{< details >}}
+**Introduced** in GitLab 17.9.
+**Status**: Experiment.
+{{< /details >}}
+
+Input type: `DestroyComplianceRequirementsControlInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationdestroycompliancerequirementscontrolclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationdestroycompliancerequirementscontrolid"></a>`id` | [`ComplianceManagementComplianceFrameworkComplianceRequirementsControlID!`](#compliancemanagementcomplianceframeworkcompliancerequirementscontrolid) | Global ID of the compliance requirement control to destroy. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationdestroycompliancerequirementscontrolclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationdestroycompliancerequirementscontrolerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+
 ### `Mutation.destroyContainerRepository`
 
 Input type: `DestroyContainerRepositoryInput`
diff --git a/doc/user/compliance/audit_event_types.md b/doc/user/compliance/audit_event_types.md
index a0b9911c98549750460ca6c033ad7ef117e45af6..05ad559276c7606011caca847bb1b50e180c4cd6 100644
--- a/doc/user/compliance/audit_event_types.md
+++ b/doc/user/compliance/audit_event_types.md
@@ -159,6 +159,7 @@ Audit event types belong to the following product categories.
 | [`delete_status_check`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84624) | An external status check is deleted | {{< icon name="check-circle" >}} Yes | GitLab [15.9](https://gitlab.com/gitlab-org/gitlab/-/issues/355805) | Project |
 | [`destroy_compliance_framework`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74292) | A compliance framework is successfully deleted | {{< icon name="check-circle" >}} Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/340649) | Group |
 | [`destroyed_compliance_requirement`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/170380) | A compliance framework requirement is destroyed | {{< icon name="check-circle" >}} Yes | GitLab [17.7](https://gitlab.com/gitlab-org/gitlab/-/issues/470695) | Group |
+| [`destroyed_compliance_requirement_control`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177878) | A compliance requirement control is destroyed. | {{< icon name="check-circle" >}} Yes | GitLab [17.9](https://gitlab.com/gitlab-org/gitlab/-/issues/512381) | Group |
 | [`email_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114546) | An email is created | {{< icon name="check-circle" >}} Yes | GitLab [15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | User |
 | [`email_destroyed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114546) | An email is destroyed | {{< icon name="check-circle" >}} Yes | GitLab [15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | User |
 | [`external_status_check_name_updated`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106095) | The name of an external status check is updated | {{< icon name="check-circle" >}} Yes | GitLab [15.7](https://gitlab.com/gitlab-org/gitlab/-/issues/369333) | Project |
diff --git a/ee/app/graphql/ee/types/mutation_type.rb b/ee/app/graphql/ee/types/mutation_type.rb
index 3b18eeae4faf50c5721b75a9e5b081a9c97fa258..1cdcb6b9ef56490e76aa18c1e3718c7c0be84508 100644
--- a/ee/app/graphql/ee/types/mutation_type.rb
+++ b/ee/app/graphql/ee/types/mutation_type.rb
@@ -276,6 +276,8 @@ def self.authorization_scopes
           experiment: { milestone: '17.9' }
         mount_mutation ::Mutations::ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::Update,
           experiment: { milestone: '17.9' }
+        mount_mutation ::Mutations::ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::Destroy,
+          experiment: { milestone: '17.9' }
         mount_mutation ::Mutations::Ai::DuoSettings::Update, experiment: { milestone: '17.9' }
         mount_mutation ::Mutations::Ai::DeleteConversationThread, experiment: { milestone: '17.9' }
 
diff --git a/ee/app/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy.rb b/ee/app/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy.rb
new file mode 100644
index 0000000000000000000000000000000000000000..09d87e10a4fe3c6a0b40dbc99ce747d088f5fbca
--- /dev/null
+++ b/ee/app/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Mutations
+  module ComplianceManagement
+    module ComplianceFramework
+      module ComplianceRequirementsControls
+        class Destroy < BaseMutation
+          graphql_name 'DestroyComplianceRequirementsControl'
+
+          authorize :admin_compliance_framework
+
+          argument :id, ::Types::GlobalIDType[
+            ::ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl
+          ],
+            required: true,
+            description: 'Global ID of the compliance requirement control to destroy.'
+
+          def resolve(id:)
+            control = authorized_find!(id: id)
+
+            result = ::ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::DestroyService.new(
+              control: control, current_user: current_user).execute
+
+            { errors: result.success? ? [] : Array.wrap(result.message) }
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/ee/app/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service.rb b/ee/app/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3c5e00fdf6c2a40f643adf138663a2d2d8491cc3
--- /dev/null
+++ b/ee/app/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module ComplianceManagement
+  module ComplianceFramework
+    module ComplianceRequirementsControls
+      class DestroyService < BaseService
+        attr_reader :current_user, :control
+
+        def initialize(control:, current_user:)
+          @control = control
+          @current_user = current_user
+        end
+
+        def execute
+          return ServiceResponse.error(message: _('Not permitted to destroy requirement control')) unless permitted?
+
+          control.destroy ? success : error
+        end
+
+        private
+
+        def permitted?
+          can? current_user, :admin_compliance_framework, control.compliance_requirement.framework
+        end
+
+        def success
+          audit_destroy
+
+          ServiceResponse.success(message: _('Compliance requirement control successfully deleted'))
+        end
+
+        def audit_destroy
+          audit_context = {
+            name: 'destroyed_compliance_requirement_control',
+            author: current_user,
+            scope: control.namespace,
+            target: control,
+            message: "Destroyed compliance requirement control #{control.name}"
+          }
+
+          ::Gitlab::Audit::Auditor.audit(audit_context)
+        end
+
+        def error
+          ServiceResponse.error(message: _('Failed to destroy compliance requirement control'), payload: control.errors)
+        end
+      end
+    end
+  end
+end
diff --git a/ee/config/audit_events/types/destroyed_compliance_requirement_control.yml b/ee/config/audit_events/types/destroyed_compliance_requirement_control.yml
new file mode 100644
index 0000000000000000000000000000000000000000..da2a413c87d34a46edafd633f2f8d70edd793641
--- /dev/null
+++ b/ee/config/audit_events/types/destroyed_compliance_requirement_control.yml
@@ -0,0 +1,10 @@
+---
+name: destroyed_compliance_requirement_control
+description: A compliance requirement control is destroyed.
+introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/512381
+introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177878
+milestone: '17.9'
+feature_category: compliance_management
+saved_to_database: true
+streamed: true
+scope: [Group]
diff --git a/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..952a3e03319a70a1c587f470d75e5e2dac2b1c55
--- /dev/null
+++ b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::Destroy,
+  feature_category: :compliance_management do
+  include GraphqlHelpers
+
+  let_it_be(:namespace) { create(:group) }
+  let_it_be(:requirement) do
+    create(:compliance_requirement, framework: create(:compliance_framework, namespace: namespace))
+  end
+
+  let_it_be(:control) { create(:compliance_requirements_control, compliance_requirement: requirement) }
+
+  let_it_be(:current_user) { create(:user) }
+  let(:mutation) { described_class.new(object: nil, context: query_context, field: nil) }
+
+  subject(:mutate) { mutation.resolve(id: global_id_of(control)) }
+
+  before_all do
+    namespace.add_owner(current_user)
+  end
+
+  context 'when feature is unlicensed' do
+    before do
+      stub_licensed_features(custom_compliance_frameworks: false)
+    end
+
+    it 'raises an error' do
+      expect { mutate }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+    end
+  end
+
+  context 'when feature is licensed' do
+    before do
+      stub_licensed_features(custom_compliance_frameworks: true)
+    end
+
+    it 'destroys a compliance requirement control' do
+      expect { mutate }.to change {
+        ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.exists?(id: control.id)
+      }.from(true).to(false)
+    end
+
+    it 'expects zero errors in the response' do
+      expect(mutate[:errors]).to be_empty
+    end
+  end
+end
diff --git a/ee/spec/requests/api/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb b/ee/spec/requests/api/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3989e90d370eb6836368778197024d44c6a3f302
--- /dev/null
+++ b/ee/spec/requests/api/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Destroy a Compliance Requirement Control', feature_category: :compliance_management do
+  include GraphqlHelpers
+
+  let_it_be(:namespace) { create(:group) }
+  let_it_be(:requirement) do
+    create(:compliance_requirement, framework: create(:compliance_framework, namespace: namespace))
+  end
+
+  let_it_be(:control) { create(:compliance_requirements_control, compliance_requirement: requirement) }
+
+  let_it_be(:current_user) { create(:user) }
+  let(:mutation) { graphql_mutation(:destroy_compliance_requirements_control, { id: global_id_of(control) }) }
+
+  subject(:mutate) { post_graphql_mutation(mutation, current_user: current_user) }
+
+  def mutation_response
+    graphql_mutation_response(:destroy_compliance_requirements_control)
+  end
+
+  context 'when feature is unlicensed' do
+    before do
+      stub_licensed_features(custom_compliance_frameworks: false)
+    end
+
+    it 'does not destroy a compliance requirement control' do
+      expect { mutate }.not_to change { ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.count }
+    end
+
+    it_behaves_like 'a mutation that returns top-level errors',
+      errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+  end
+
+  context 'when licensed' do
+    before do
+      stub_licensed_features(custom_compliance_frameworks: true)
+    end
+
+    context 'when current_user is namespace owner' do
+      before_all do
+        namespace.add_owner(current_user)
+      end
+
+      it 'has no errors' do
+        mutate
+
+        expect(mutation_response['errors']).to be_empty
+      end
+
+      it 'destroys a compliance requirement control' do
+        expect { mutate }.to change {
+          ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.exists?(id: control.id)
+        }.from(true).to(false)
+      end
+    end
+
+    context 'when current_user is not namespace owner' do
+      it_behaves_like 'a mutation that returns top-level errors',
+        errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+
+      it 'does not destroy a compliance requirement control' do
+        expect { mutate }
+          .not_to change { ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.count }
+      end
+    end
+  end
+end
diff --git a/ee/spec/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service_spec.rb b/ee/spec/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..18ccd241f189eea20962ddad3902b07c24edd49c
--- /dev/null
+++ b/ee/spec/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service_spec.rb
@@ -0,0 +1,114 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::DestroyService,
+  feature_category: :compliance_management do
+  let_it_be_with_refind(:namespace) { create(:group) }
+  let_it_be(:requirement) do
+    create(:compliance_requirement, framework: create(:compliance_framework, namespace: namespace))
+  end
+
+  let_it_be(:control) { create(:compliance_requirements_control, compliance_requirement: requirement) }
+  let_it_be(:owner) { create(:user, owner_of: namespace) }
+  let_it_be(:non_owner) { create(:user) }
+
+  shared_examples 'unsuccessful destruction' do |error_message|
+    it 'does not destroy the compliance requirement control' do
+      expect { service.execute }
+        .not_to change { ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.count }
+    end
+
+    it 'is unsuccessful' do
+      result = service.execute
+
+      expect(result.success?).to be false
+      expect(result.message).to eq _(error_message)
+    end
+
+    it 'does not audit the destruction' do
+      service.execute
+
+      expect(::Gitlab::Audit::Auditor).not_to have_received(:audit)
+    end
+  end
+
+  context 'when feature is disabled' do
+    before do
+      stub_licensed_features(custom_compliance_frameworks: false)
+      allow(::Gitlab::Audit::Auditor).to receive(:audit)
+    end
+
+    context 'when current user is namespace owner' do
+      subject(:service) { described_class.new(control: control, current_user: owner) }
+
+      it_behaves_like 'unsuccessful destruction', 'Not permitted to destroy requirement control'
+    end
+
+    context 'when current user is not the namespace owner' do
+      subject(:service) { described_class.new(control: control, current_user: non_owner) }
+
+      it_behaves_like 'unsuccessful destruction', 'Not permitted to destroy requirement control'
+    end
+  end
+
+  context 'when feature is enabled' do
+    before do
+      stub_licensed_features(custom_compliance_frameworks: true)
+      allow(::Gitlab::Audit::Auditor).to receive(:audit)
+    end
+
+    context 'when current user is namespace owner' do
+      subject(:service) { described_class.new(control: control, current_user: owner) }
+
+      it 'destroys the compliance requirement control' do
+        expect { service.execute }.to change {
+          ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.exists?(id: control.id)
+        }.from(true).to(false)
+      end
+
+      it 'is successful' do
+        result = service.execute
+
+        expect(result.success?).to be true
+        expect(result.message).to eq _('Compliance requirement control successfully deleted')
+      end
+
+      it 'audits the destruction' do
+        service.execute
+
+        expect(::Gitlab::Audit::Auditor).to have_received(:audit).with(
+          name: 'destroyed_compliance_requirement_control',
+          author: owner,
+          scope: control.namespace,
+          target: control,
+          message: "Destroyed compliance requirement control #{control.name}"
+        )
+      end
+
+      context 'when destruction fails' do
+        before do
+          allow(control).to receive(:destroy).and_return(false)
+        end
+
+        it 'is unsuccessful' do
+          result = service.execute
+
+          expect(result.success?).to be false
+          expect(result.message).to eq _('Failed to destroy compliance requirement control')
+        end
+      end
+    end
+
+    context 'when current user is not the namespace owner' do
+      subject(:service) { described_class.new(control: control, current_user: non_owner) }
+
+      it 'does not destroy the compliance requirement control' do
+        expect { service.execute }
+          .not_to change { ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.count }
+      end
+
+      it_behaves_like 'unsuccessful destruction', 'Not permitted to destroy requirement control'
+    end
+  end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index e34d594479ae1f19519a388e7d63bc7c3ebc135b..959bc33dfd99093b0fc33f82e10921d8d72caf91 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -14613,6 +14613,9 @@ msgstr ""
 msgid "Compliance frameworks"
 msgstr ""
 
+msgid "Compliance requirement control successfully deleted"
+msgstr ""
+
 msgid "Compliance requirement successfully deleted"
 msgstr ""
 
@@ -24277,6 +24280,9 @@ msgstr ""
 msgid "Failed to destroy compliance requirement"
 msgstr ""
 
+msgid "Failed to destroy compliance requirement control"
+msgstr ""
+
 msgid "Failed to enqueue the rebase operation, possibly due to a long-lived transaction. Try again later."
 msgstr ""
 
@@ -38485,6 +38491,9 @@ msgstr ""
 msgid "Not permitted to destroy requirement"
 msgstr ""
 
+msgid "Not permitted to destroy requirement control"
+msgstr ""
+
 msgid "Not permitted to reset user feed token"
 msgstr ""