diff --git a/cinder/privsep/nvmcli.py b/cinder/privsep/nvmcli.py
new file mode 100644
index 00000000000..95f5b1c569d
--- /dev/null
+++ b/cinder/privsep/nvmcli.py
@@ -0,0 +1,41 @@
+# Copyright 2018 Red Hat, Inc
+# Copyright 2017 Rackspace Australia
+# Copyright 2018 Michael Still and Aptira
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+"""
+Helpers for nvmetcli related routines.
+"""
+
+from oslo_concurrency import processutils
+
+import cinder.privsep
+
+
+@cinder.privsep.sys_admin_pctxt.entrypoint
+def restore(path):
+    cmd = [
+        'nvmetcli',
+        'restore',
+        path]
+    return processutils.execute(*cmd)
+
+
+@cinder.privsep.sys_admin_pctxt.entrypoint
+def save(path):
+    cmd = [
+        'nvmetcli',
+        'save',
+        path]
+    return processutils.execute(*cmd)
diff --git a/cinder/privsep/utils.py b/cinder/privsep/utils.py
new file mode 100644
index 00000000000..fc76c6e6c20
--- /dev/null
+++ b/cinder/privsep/utils.py
@@ -0,0 +1,39 @@
+# Copyright 2018 Red Hat, Inc
+# Copyright 2017 Rackspace Australia
+# Copyright 2018 Michael Still and Aptira
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+"""
+Helpers for cgroup related routines.
+"""
+
+import os
+
+from cinder import exception
+import cinder.privsep
+
+
+@cinder.privsep.sys_admin_pctxt.entrypoint
+def readfile(path):
+    if not os.path.exists(path):
+        raise exception.FileNotFound(file_path=path)
+    with open(path, 'r') as f:
+        return f.read()
+
+
+@cinder.privsep.sys_admin_pctxt.entrypoint
+def removefile(path):
+    if not os.path.exists(path):
+        raise exception.FileNotFound(file_path=path)
+    os.unlink(path)
diff --git a/cinder/volume/targets/nvmet.py b/cinder/volume/targets/nvmet.py
index 58c1485dd00..f8f2b5b9fdc 100644
--- a/cinder/volume/targets/nvmet.py
+++ b/cinder/volume/targets/nvmet.py
@@ -20,6 +20,7 @@ from oslo_utils import uuidutils
 import six
 
 from cinder import exception
+import cinder.privsep
 from cinder import utils
 from cinder.volume.targets import nvmeof
 
@@ -76,13 +77,8 @@ class NVMET(nvmeof.NVMeOF):
         with tempfile.NamedTemporaryFile() as tmp_fd:
             tmp_fd.write(json.dumps(nvmf_subsystems))
             tmp_fd.flush()
-            cmd = [
-                'nvmetcli',
-                'restore',
-                tmp_fd.name]
             try:
-                out, err = utils.execute(*cmd, run_as_root=True)
-
+                out, err = cinder.privsep.nvmcli.restore(tmp_fd.name)
             except putils.ProcessExecutionError:
                 with excutils.save_and_reraise_exception():
                     LOG.exception('Error from nvmetcli restore')
@@ -156,22 +152,22 @@ class NVMET(nvmeof.NVMeOF):
                      "for volume: %s", volume['id'])
 
     def _delete_nvmf_subsystem(self, nvmf_subsystems, subsystem_name):
-            LOG.debug(
-                'Removing this subsystem: %s', subsystem_name)
+        LOG.debug(
+            'Removing this subsystem: %s', subsystem_name)
 
-            for port in nvmf_subsystems['ports']:
-                if subsystem_name in port['subsystems']:
-                    port['subsystems'].remove(subsystem_name)
-                    break
-            for subsys in nvmf_subsystems['subsystems']:
-                if subsys['nqn'] == subsystem_name:
-                    nvmf_subsystems['subsystems'].remove(subsys)
-                    break
+        for port in nvmf_subsystems['ports']:
+            if subsystem_name in port['subsystems']:
+                port['subsystems'].remove(subsystem_name)
+                break
+        for subsys in nvmf_subsystems['subsystems']:
+            if subsys['nqn'] == subsystem_name:
+                nvmf_subsystems['subsystems'].remove(subsys)
+                break
 
-            LOG.debug(
-                'Newly loaded subsystems will be: %s', nvmf_subsystems)
-            self._restore(nvmf_subsystems)
-            return subsystem_name
+        LOG.debug(
+            'Newly loaded subsystems will be: %s', nvmf_subsystems)
+        self._restore(nvmf_subsystems)
+        return subsystem_name
 
     def _get_nvmf_subsystem(self, nvmf_subsystems, volume_id):
         subsystem_name = self._get_target_info(
@@ -184,12 +180,8 @@ class NVMET(nvmeof.NVMeOF):
         __, tmp_file_path = tempfile.mkstemp(prefix='nvmet')
 
         # nvmetcli doesn't support printing to stdout yet,
-        cmd = [
-            'nvmetcli',
-            'save',
-            tmp_file_path]
         try:
-            out, err = utils.execute(*cmd, run_as_root=True)
+            out, err = cinder.privsep.nvmcli.save(tmp_file_path)
         except putils.ProcessExecutionError:
             with excutils.save_and_reraise_exception():
                 LOG.exception('Error from nvmetcli save')
@@ -198,9 +190,8 @@ class NVMET(nvmeof.NVMeOF):
         # temp file must be readable by this process user
         # in order to avoid executing cat as root
         with utils.temporary_chown(tmp_file_path):
-            cmd = ['cat', tmp_file_path]
             try:
-                out, err = utils.execute(*cmd)
+                out = cinder.privsep.utils.readfile(tmp_file_path)
             except putils.ProcessExecutionError:
                 with excutils.save_and_reraise_exception():
                     LOG.exception('Failed to read: %s', tmp_file_path)
@@ -215,8 +206,7 @@ class NVMET(nvmeof.NVMeOF):
         return "nqn.%s-%s" % (subsystem, volume_id)
 
     def _delete_file(self, file_path):
-        cmd = ['rm', '-f', file_path]
         try:
-            out, err = utils.execute(*cmd, run_as_root=True)
+            cinder.privsep.utils.removefile(file_path)
         except putils.ProcessExecutionError:
             LOG.exception('Failed to delete file: %s', file_path)
diff --git a/etc/cinder/rootwrap.d/volume.filters b/etc/cinder/rootwrap.d/volume.filters
index 81a9d185b80..7d4b27f72b6 100644
--- a/etc/cinder/rootwrap.d/volume.filters
+++ b/etc/cinder/rootwrap.d/volume.filters
@@ -223,6 +223,3 @@ drv_cfg: CommandFilter, /opt/emc/scaleio/sdc/bin/drv_cfg, root, /opt/emc/scaleio
 # cinder/volume/drivers/quobyte.py
 mount.quobyte: CommandFilter, mount.quobyte, root
 umount.quobyte: CommandFilter, umount.quobyte, root
-
-# cinder/volume/targets/nvmet.py
-nvmetcli: CommandFilter, nvmetcli, root