diff --git a/doc/source/admin/drivers/ilo.rst b/doc/source/admin/drivers/ilo.rst
index 74153cc9ce..40bb06735d 100644
--- a/doc/source/admin/drivers/ilo.rst
+++ b/doc/source/admin/drivers/ilo.rst
@@ -56,6 +56,7 @@ The hardware type ``ilo`` supports following HPE server features:
 * `Update Minimum Password Length security parameter as manual clean step`_
 * `Update Authentication Failure Logging security parameter as manual clean step`_
 * `Activating iLO Advanced license as manual clean step`_
+* `Removing CA certificates from iLO as manual clean step`_
 * `Firmware based UEFI iSCSI boot from volume support`_
 * `Certificate based validation in iLO`_
 * `Rescue mode support`_
@@ -702,6 +703,10 @@ Supported **Manual** Cleaning Operations
     delivered with a flexible-quantity kit or after completing an Activation
     Key Agreement (AKA), then the driver can still be used for executing
     this cleaning step.
+  ``clear_ca_certificates``:
+    Removes the CA certificates from iLO. See
+    `Removing CA certificates from iLO as manual clean step`_ for user
+    guidance on usage.
   ``apply_configuration``:
     Applies given BIOS settings on the node. See
     `BIOS configuration support`_. This step is part of the ``bios`` interface.
@@ -1477,6 +1482,37 @@ The different attributes of ``activate_license`` clean step are as follows:
     "``args``", "Keyword-argument entry (<name>: <value>) being passed to clean step"
     "``args.ilo_license_key``", "iLO Advanced license key to activate enterprise features. This is mandatory."
 
+Removing CA certificates from iLO as manual clean step
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+iLO driver can remove the invalidated CA certificates as a manual step.
+Any manual cleaning step can only be initiated when a node is in the
+``manageable`` state. Once the manual cleaning is finished, the node will be
+put in the ``manageable`` state again. User can follow steps from
+:ref:`manual_cleaning` to initiate manual cleaning operation on a node.
+
+An example of a manual clean step with ``clear_ca_certificates`` as the only clean
+step could be::
+
+    "clean_steps": [{
+        "interface": "management",
+        "step": "clear_ca_certificates",
+        "args": {
+            "certificate_files" : ["/path/to/certsA", "/path/to/certsB"]
+        }
+    }]
+
+The different attributes of ``clear_ca_certificates`` clean step are as follows:
+
+.. csv-table::
+    :header: "Attribute", "Description"
+    :widths: 30, 120
+
+    "``interface``", "Interface of clean step, here ``management``"
+    "``step``", "Name of clean step, here ``clear_ca_certificates``"
+    "``args``", "Keyword-argument entry (<name>: <value>) being passed to clean step"
+    "``args.certificate_files``", "List of CA certificates which are to be removed. "
+                                  "This is mandatory."
+
 Initiating firmware update as manual clean step
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 iLO driver can invoke secure firmware update as a manual cleaning step. Any
diff --git a/ironic/drivers/modules/ilo/boot.py b/ironic/drivers/modules/ilo/boot.py
index bcfb7bb967..60e0c3a25e 100644
--- a/ironic/drivers/modules/ilo/boot.py
+++ b/ironic/drivers/modules/ilo/boot.py
@@ -1022,11 +1022,16 @@ class IloUefiHttpsBoot(base.BootInterface):
         iso_ref = image_utils.prepare_deploy_iso(task, ramdisk_params,
                                                  mode, d_info)
 
+        # NOTE(vmud213): Do not call if it is in the middle of
+        # clear_ca_certificates clean step as the TLS pending settings will
+        # be overridden
+        if not node.driver_internal_info.get('clear_ca_certs_flag'):
+            ilo_common.add_certificates(task)
+
         LOG.debug("Set 'UEFIHTTP' as one time boot option on the node "
                   "%(node)s to boot from URL %(iso_ref)s.",
                   {'node': node.uuid, 'iso_ref': iso_ref})
 
-        ilo_common.add_certificates(task)
         ilo_common.setup_uefi_https(task, iso_ref)
 
     @METRICS.timer('IloUefiHttpsBoot.clean_up_ramdisk')
diff --git a/ironic/drivers/modules/ilo/common.py b/ironic/drivers/modules/ilo/common.py
index 69161499b6..a69a4e3ec0 100644
--- a/ironic/drivers/modules/ilo/common.py
+++ b/ironic/drivers/modules/ilo/common.py
@@ -1068,10 +1068,13 @@ def clear_certificates(task, cert_file_list=None):
     node = task.node
     operation = (_("Clearing certificates from node %(node)s.") %
                  {'node': node.uuid})
+    # NOTE(vmud213): Exclude the certificates used to boot deploy images
+    exclude_cfl = _get_certificate_file_list(None)
 
     try:
         ilo_object = get_ilo_object(node)
-        ilo_object.remove_tls_certificate(cert_file_list)
+        ilo_object.remove_tls_certificate(
+            cert_file_list=cert_file_list, excl_cert_file_list=exclude_cfl)
     except ilo_error.IloCommandNotSupportedInBiosError as ilo_exception:
         raise exception.IloOperationNotSupported(operation=operation,
                                                  error=ilo_exception)
diff --git a/ironic/drivers/modules/ilo/management.py b/ironic/drivers/modules/ilo/management.py
index 17516b4b82..e78db25ef5 100644
--- a/ironic/drivers/modules/ilo/management.py
+++ b/ironic/drivers/modules/ilo/management.py
@@ -186,6 +186,20 @@ _FIRMWARE_UPDATE_SUM_ARGSINFO = {
     }
 }
 
+_CLEAR_CA_CERTS_ARGSINFO = {
+    'certificate_files': {
+        'description': (
+            "The list of files containing the certificates to be cleared. "
+            "If empty list is specified, all the certificates on the ilo "
+            "will be cleared, except the certificates in the file "
+            "configured with configuration parameter 'webserver_verify_ca' "
+            "are spared as they are required for booting the deploy image "
+            "for some boot interfaces."
+        ),
+        'required': True
+    }
+}
+
 
 def _execute_ilo_step(node, step, *args, **kwargs):
     """Executes a particular deploy or clean step.
@@ -1128,3 +1142,51 @@ class Ilo5Management(IloManagement):
                        {'node': task.node.uuid, 'message': ilo_exception})
             manager_utils.cleaning_error_handler(task, log_msg,
                                                  errmsg=ilo_exception)
+
+    @base.clean_step(priority=0, argsinfo=_CLEAR_CA_CERTS_ARGSINFO)
+    def clear_ca_certificates(self, task, certificate_files):
+        """Clears the certificates provided in the list of files to iLO.
+
+        :param task: a task from TaskManager.
+        :param certificate_files: a list of cerificate files.
+        :raises: NodeCleaningFailure, on failure to execute of clean step.
+        :raises: InstanceDeployFailure, on failure to execute of deploy step.
+        """
+        node = task.node
+        driver_internal_info = node.driver_internal_info
+
+        if driver_internal_info.get('clear_ca_certs_flag'):
+            # NOTE(vmud213): Clear the flag and do nothing as this flow
+            # is part of the reboot required by the clean step that is
+            # already executed.
+            driver_internal_info.pop('clear_ca_certs_flag', None)
+            node.driver_internal_info = driver_internal_info
+            node.save()
+            return
+
+        try:
+            ilo_common.clear_certificates(task, certificate_files)
+        except (exception.IloOperationNotSupported,
+                exception.IloOperationError) as ir_exception:
+            msg = (_("Step 'clear_ca_certificates' failed on node %(node)s "
+                     "with error: %(err)s") %
+                   {'node': node.uuid, 'err': ir_exception})
+            if node.clean_step:
+                raise exception.NodeCleaningFailure(msg)
+            raise exception.InstanceDeployFailure(msg)
+
+        driver_internal_info['clear_ca_certs_flag'] = True
+        node.driver_internal_info = driver_internal_info
+        node.save()
+
+        deploy_opts = deploy_utils.build_agent_options(task.node)
+        task.driver.boot.prepare_ramdisk(task, deploy_opts)
+        manager_utils.node_power_action(task, states.REBOOT)
+
+        # set_async_step_flags calls node.save()
+        deploy_utils.set_async_step_flags(
+            node,
+            reboot=True,
+            skip_current_step=False)
+
+        return deploy_utils.get_async_step_return_state(task.node)
diff --git a/ironic/tests/unit/drivers/modules/ilo/test_boot.py b/ironic/tests/unit/drivers/modules/ilo/test_boot.py
index 2fae7b9c34..128f603c56 100644
--- a/ironic/tests/unit/drivers/modules/ilo/test_boot.py
+++ b/ironic/tests/unit/drivers/modules/ilo/test_boot.py
@@ -1812,7 +1812,11 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
                 task, ramdisk_params, mode, d_info)
             setup_uefi_https_mock.assert_called_once_with(task,
                                                           'recreated-iso')
-            add_mock.assert_called_once_with(task)
+            if task.node.driver_internal_info.get("clear_ca_certs_flag",
+                                                  False):
+                add_mock.assert_not_called()
+            else:
+                add_mock.assert_called_once_with(task)
 
     def test_prepare_ramdisk_rescue_glance_image(self):
         self._test_prepare_ramdisk(
@@ -1832,6 +1836,21 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
                          self.node.instance_info['boot_iso'])
 
     def test_prepare_ramdisk_glance_image(self):
+        driver_internal_info = self.node.driver_internal_info
+        driver_internal_info['clear_ca_certs_flag'] = False
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+        self._test_prepare_ramdisk(
+            ilo_boot_iso='swift:abcdef',
+            image_source='6b2f0c0c-79e8-4db6-842e-43c9764204af')
+        self.node.refresh()
+        self.assertNotIn('boot_iso', self.node.instance_info)
+
+    def test_prepare_ramdisk_middle_of_clean_step(self):
+        driver_internal_info = self.node.driver_internal_info
+        driver_internal_info['clear_ca_certs_flag'] = True
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
         self._test_prepare_ramdisk(
             ilo_boot_iso='swift:abcdef',
             image_source='6b2f0c0c-79e8-4db6-842e-43c9764204af')
diff --git a/ironic/tests/unit/drivers/modules/ilo/test_common.py b/ironic/tests/unit/drivers/modules/ilo/test_common.py
index f1d9cd241e..1d4bfd8b29 100644
--- a/ironic/tests/unit/drivers/modules/ilo/test_common.py
+++ b/ironic/tests/unit/drivers/modules/ilo/test_common.py
@@ -1370,34 +1370,50 @@ class IloCommonMethodsTestCase(BaseIloTest):
         get_cl_mock.assert_called_once_with(c_l)
         ilo_mock_object.add_tls_certificate.assert_called_once_with(c_l)
 
+    @mock.patch.object(ilo_common, '_get_certificate_file_list',
+                       spec_set=True, autospec=True)
     @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
                        autospec=True)
-    def test_clear_certificates(self, get_ilo_object_mock):
+    def test_clear_certificates(self, get_ilo_object_mock,
+                                get_certs_mock):
         ilo_mock_object = get_ilo_object_mock.return_value
         c_l = ['/file/path/a', '/file/path/b']
+        get_certs_mock.return_value = ['/file/path/x']
 
         with task_manager.acquire(self.context, self.node.uuid,
                                   shared=False) as task:
             ilo_common.clear_certificates(task, c_l)
 
-        ilo_mock_object.remove_tls_certificate.assert_called_once_with(c_l)
+        ilo_mock_object.remove_tls_certificate.assert_called_once_with(
+            cert_file_list=c_l, excl_cert_file_list=['/file/path/x'])
+        get_certs_mock.assert_called_once_with(None)
 
+    @mock.patch.object(ilo_common, '_get_certificate_file_list',
+                       spec_set=True, autospec=True)
     @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
                        autospec=True)
-    def test_clear_certificates_default(self, get_ilo_object_mock):
+    def test_clear_certificates_default(self, get_ilo_object_mock,
+                                        get_certs_mock):
         ilo_mock_object = get_ilo_object_mock.return_value
+        get_certs_mock.return_value = ['/file/path/x']
 
         with task_manager.acquire(self.context, self.node.uuid,
                                   shared=False) as task:
             ilo_common.clear_certificates(task)
 
-        ilo_mock_object.remove_tls_certificate.assert_called_once_with(None)
+        ilo_mock_object.remove_tls_certificate.assert_called_once_with(
+            cert_file_list=None, excl_cert_file_list=['/file/path/x'])
+        get_certs_mock.assert_called_once_with(None)
 
+    @mock.patch.object(ilo_common, '_get_certificate_file_list',
+                       spec_set=True, autospec=True)
     @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
                        autospec=True)
-    def test_clear_certificates_raises_ilo_error(self, get_ilo_object_mock):
+    def test_clear_certificates_raises_ilo_error(self, get_ilo_object_mock,
+                                                 get_certs_mock):
         ilo_mock_object = get_ilo_object_mock.return_value
         c_l = ['/file/path/a', '/file/path/b']
+        get_certs_mock.return_value = ['/file/path/x']
         exc = ilo_error.IloError('error')
         ilo_mock_object.remove_tls_certificate.side_effect = exc
 
@@ -1407,7 +1423,9 @@ class IloCommonMethodsTestCase(BaseIloTest):
                               ilo_common.clear_certificates,
                               task, c_l)
 
-        ilo_mock_object.remove_tls_certificate.assert_called_once_with(c_l)
+        ilo_mock_object.remove_tls_certificate.assert_called_once_with(
+            cert_file_list=c_l, excl_cert_file_list=['/file/path/x'])
+        get_certs_mock.assert_called_once_with(None)
 
     @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True,
                        autospec=True)
diff --git a/ironic/tests/unit/drivers/modules/ilo/test_management.py b/ironic/tests/unit/drivers/modules/ilo/test_management.py
index 80cb07c9fa..e4d891c3d0 100644
--- a/ironic/tests/unit/drivers/modules/ilo/test_management.py
+++ b/ironic/tests/unit/drivers/modules/ilo/test_management.py
@@ -1525,12 +1525,10 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
     def setUp(self):
         super(Ilo5ManagementTestCase, self).setUp()
         self.driver = mock.Mock(management=ilo_management.Ilo5Management())
-        self.clean_step = {'step': 'erase_devices',
-                           'interface': 'management'}
+
         n = {
             'driver': 'ilo5',
             'driver_info': INFO_DICT,
-            'clean_step': self.clean_step,
         }
         self.config(enabled_hardware_types=['ilo5'],
                     enabled_boot_interfaces=['ilo-virtual-media'],
@@ -1547,6 +1545,9 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
     @mock.patch.object(ilo_common, 'get_ilo_object', autospec=True)
     @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
     def test_erase_devices_hdd(self, mock_power, ilo_mock, build_agent_mock):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'erase_devices'}
+        self.node.save()
         ilo_mock_object = ilo_mock.return_value
         ilo_mock_object.get_available_disk_types.return_value = ['HDD']
         build_agent_mock.return_value = []
@@ -1572,6 +1573,9 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
     @mock.patch.object(ilo_common, 'get_ilo_object', autospec=True)
     @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
     def test_erase_devices_ssd(self, mock_power, ilo_mock, build_agent_mock):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'erase_devices'}
+        self.node.save()
         ilo_mock_object = ilo_mock.return_value
         ilo_mock_object.get_available_disk_types.return_value = ['SSD']
         build_agent_mock.return_value = []
@@ -1601,6 +1605,9 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
     @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
     def test_erase_devices_ssd_when_hdd_done(self, mock_power, ilo_mock,
                                              build_agent_mock):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'erase_devices'}
+        self.node.save()
         build_agent_mock.return_value = []
         ilo_mock_object = ilo_mock.return_value
         ilo_mock_object.get_available_disk_types.return_value = ['HDD', 'SSD']
@@ -1632,6 +1639,9 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
     @mock.patch.object(ilo_common, 'get_ilo_object', autospec=True)
     def test_erase_devices_completed(self, ilo_mock, disk_status_mock,
                                      log_mock):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'erase_devices'}
+        self.node.save()
         ilo_mock_object = ilo_mock.return_value
         ilo_mock_object.get_available_disk_types.return_value = ['HDD', 'SSD']
         disk_status_mock.return_value = True
@@ -1655,6 +1665,9 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
     @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
     def test_erase_devices_hdd_with_erase_pattern_zero(
             self, mock_power, ilo_mock, build_agent_mock):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'erase_devices'}
+        self.node.save()
         ilo_mock_object = ilo_mock.return_value
         ilo_mock_object.get_available_disk_types.return_value = ['HDD']
         build_agent_mock.return_value = []
@@ -1680,6 +1693,9 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
     @mock.patch.object(ilo_common, 'get_ilo_object', autospec=True)
     def test_erase_devices_when_no_drive_available(
             self, ilo_mock, log_mock):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'erase_devices'}
+        self.node.save()
         ilo_mock_object = ilo_mock.return_value
         ilo_mock_object.get_available_disk_types.return_value = []
         with task_manager.acquire(self.context, self.node.uuid,
@@ -1689,6 +1705,9 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
 
     def test_erase_devices_hdd_with_invalid_format_erase_pattern(
             self):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'erase_devices'}
+        self.node.save()
         with task_manager.acquire(self.context, self.node.uuid,
                                   shared=False) as task:
             self.assertRaises(exception.InvalidParameterValue,
@@ -1697,6 +1716,9 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
 
     def test_erase_devices_hdd_with_invalid_device_type_erase_pattern(
             self):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'erase_devices'}
+        self.node.save()
         with task_manager.acquire(self.context, self.node.uuid,
                                   shared=False) as task:
             self.assertRaises(exception.InvalidParameterValue,
@@ -1705,6 +1727,9 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
 
     def test_erase_devices_hdd_with_invalid_erase_pattern(
             self):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'erase_devices'}
+        self.node.save()
         with task_manager.acquire(self.context, self.node.uuid,
                                   shared=False) as task:
             self.assertRaises(exception.InvalidParameterValue,
@@ -1716,6 +1741,9 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
                        autospec=True)
     def test_erase_devices_hdd_ilo_error(self, clean_err_handler_mock,
                                          ilo_mock):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'erase_devices'}
+        self.node.save()
         ilo_mock_object = ilo_mock.return_value
         ilo_mock_object.get_available_disk_types.return_value = ['HDD']
         exc = ilo_error.IloError('error')
@@ -1776,3 +1804,131 @@ class Ilo5ManagementTestCase(db_base.DbTestCase):
                 errmsg=exc)
             self.assertTrue(
                 ilo_mock_object.do_one_button_secure_erase.called)
+
+    @mock.patch.object(deploy_utils, 'get_async_step_return_state',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(deploy_utils, 'set_async_step_flags',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(deploy_utils, 'build_agent_options',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
+    @mock.patch.object(ilo_boot.IloVirtualMediaBoot, 'prepare_ramdisk',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(ilo_common, 'clear_certificates', spec_set=True,
+                       autospec=True)
+    def test_clear_ca_certificates(self, clear_certs_mock,
+                                   prepare_ramdisk_mock, node_power_mock,
+                                   build_agent_mock, set_async_mock,
+                                   get_async_ret_mock):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'clear_ca_certificates'}
+        self.node.save()
+        build_agent_mock.return_value = {'a': 'x', 'b': 'y'}
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+
+            certificate_files = ["/path/to/certsA", "/path/to/certsB"]
+
+            task.driver.management.clear_ca_certificates(
+                task, certificate_files)
+            clear_certs_mock.assert_called_once_with(
+                task, certificate_files)
+            self.assertTrue(task.node.driver_internal_info.get(
+                'clear_ca_certs_flag'))
+            build_agent_mock.assert_called_once_with(task.node)
+            prepare_ramdisk_mock.assert_called_once_with(
+                mock.ANY, task, {'a': 'x', 'b': 'y'})
+            node_power_mock.assert_called_once_with(task, states.REBOOT)
+            set_async_mock.assert_called_once_with(
+                task.node, reboot=True, skip_current_step=False)
+            get_async_ret_mock.assert_called_once_with(task.node)
+
+    @mock.patch.object(deploy_utils, 'get_async_step_return_state',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(deploy_utils, 'set_async_step_flags',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(deploy_utils, 'build_agent_options',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
+    @mock.patch.object(ilo_boot.IloVirtualMediaBoot, 'prepare_ramdisk',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(ilo_common, 'clear_certificates', spec_set=True,
+                       autospec=True)
+    def test_clear_ca_certificates_clear_flag(
+            self, clear_certs_mock, prepare_ramdisk_mock, node_power_mock,
+            build_agent_mock, set_async_mock, get_async_ret_mock):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'clear_ca_certificates'}
+
+        self.node.save()
+        build_agent_mock.return_value = {'a': 'x', 'b': 'y'}
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+
+            certificate_files = ["/path/to/certsA", "/path/to/certsB"]
+            driver_internal_info = task.node.driver_internal_info
+            driver_internal_info['clear_ca_certs_flag'] = True
+            task.node.driver_internal_info = driver_internal_info
+
+            task.driver.management.clear_ca_certificates(
+                task, certificate_files)
+            clear_certs_mock.assert_not_called()
+
+            build_agent_mock.assert_not_called()
+            prepare_ramdisk_mock.assert_not_called()
+            node_power_mock.assert_not_called()
+            set_async_mock.assert_not_called()
+            get_async_ret_mock.assert_not_called()
+
+    @mock.patch.object(deploy_utils, 'get_async_step_return_state',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(deploy_utils, 'set_async_step_flags',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(deploy_utils, 'build_agent_options',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
+    @mock.patch.object(ilo_boot.IloVirtualMediaBoot, 'prepare_ramdisk',
+                       spec_set=True, autospec=True)
+    @mock.patch.object(ilo_common, 'clear_certificates', spec_set=True,
+                       autospec=True)
+    def test_clear_ca_certificates_ilo_operation_not_supported(
+            self, clear_certs_mock, prepare_ramdisk_mock, node_power_mock,
+            build_agent_mock, set_async_mock, get_async_ret_mock):
+        self.node.clean_step = {'interface': 'management',
+                                'step': 'clear_ca_certificates'}
+        self.node.save()
+        exc = exception.IloOperationNotSupported('error')
+        clear_certs_mock.side_effect = exc
+
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+
+            certificate_files = ["/path/to/certsA", "/path/to/certsB"]
+
+            self.assertRaises(exception.NodeCleaningFailure,
+                              task.driver.management.clear_ca_certificates,
+                              task, certificate_files)
+            build_agent_mock.assert_not_called()
+            prepare_ramdisk_mock.assert_not_called()
+            node_power_mock.assert_not_called()
+            set_async_mock.assert_not_called()
+            get_async_ret_mock.assert_not_called()
+
+    @mock.patch.object(ilo_common, 'clear_certificates', spec_set=True,
+                       autospec=True)
+    def test_clear_ca_certificates_ilo_operation_error(self, clear_certs_mock):
+        self.node.deploy_step = {'interface': 'management',
+                                 'step': 'clear_ca_certificates'}
+        self.node.save()
+
+        exc = exception.IloOperationError('error')
+        clear_certs_mock.side_effect = exc
+
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+
+            certificate_files = ["/path/to/certsA", "/path/to/certsB"]
+
+            self.assertRaises(exception.InstanceDeployFailure,
+                              task.driver.management.clear_ca_certificates,
+                              task, certificate_files)
diff --git a/releasenotes/notes/clear_ca_cert-db41e7be9723c0fb.yaml b/releasenotes/notes/clear_ca_cert-db41e7be9723c0fb.yaml
new file mode 100644
index 0000000000..4df3c382da
--- /dev/null
+++ b/releasenotes/notes/clear_ca_cert-db41e7be9723c0fb.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Manual clean step ``clear_ca_certificates`` is added to remove the
+    CA certificates from iLO.