Merge "Switch back to built-in md5 method"
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index b974b52..3ac2b46 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -44,7 +44,7 @@
 
     # TODO(andreaf) We should care also for the alt_manager here
     # but only once client lazy load in the manager is done
-    credentials = ['primary']
+    credentials = ['primary', 'project_reader']
 
     @classmethod
     def skip_checks(cls):
@@ -78,6 +78,10 @@
     def setup_clients(cls):
         super(BaseV2ComputeTest, cls).setup_clients()
         cls.servers_client = cls.os_primary.servers_client
+        if CONF.enforce_scope.nova and hasattr(cls, 'os_project_reader'):
+            cls.reader_servers_client = cls.os_project_reader.servers_client
+        else:
+            cls.reader_servers_client = cls.servers_client
         cls.server_groups_client = cls.os_primary.server_groups_client
         cls.flavors_client = cls.os_primary.flavors_client
         cls.compute_images_client = cls.os_primary.compute_images_client
@@ -680,7 +684,7 @@
 class BaseV2ComputeAdminTest(BaseV2ComputeTest):
     """Base test case class for Compute Admin API tests."""
 
-    credentials = ['primary', 'admin']
+    credentials = ['primary', 'admin', 'project_reader']
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index 2916de5..752a48d 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -24,8 +24,6 @@
 class FlavorsV2TestJSON(base.BaseV2ComputeTest):
     """Tests Flavors"""
 
-    credentials = ['primary', 'project_reader']
-
     @classmethod
     def setup_clients(cls):
         super(FlavorsV2TestJSON, cls).setup_clients()
diff --git a/tempest/api/compute/flavors/test_flavors_negative.py b/tempest/api/compute/flavors/test_flavors_negative.py
index 682ca58..5700ecd 100644
--- a/tempest/api/compute/flavors/test_flavors_negative.py
+++ b/tempest/api/compute/flavors/test_flavors_negative.py
@@ -28,8 +28,6 @@
 
 class FlavorsV2NegativeTest(base.BaseV2ComputeTest):
 
-    credentials = ['primary', 'project_reader']
-
     @classmethod
     def setup_clients(cls):
         super(FlavorsV2NegativeTest, cls).setup_clients()
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index eddfd73..1ba4e58 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -60,6 +60,13 @@
         super(AttachInterfacesTestBase, cls).setup_clients()
         cls.subnets_client = cls.os_primary.subnets_client
         cls.ports_client = cls.os_primary.ports_client
+        if CONF.enforce_scope.nova:
+            cls.reader_interfaces_client = (
+                cls.os_project_reader.interfaces_client)
+            cls.reader_ports_client = cls.os_project_reader.ports_client
+        else:
+            cls.reader_interfaces_client = cls.interfaces_client
+            cls.reader_ports_client = cls.ports_client
 
     def _wait_for_validation(self, server, validation_resources):
         linux_client = remote_client.RemoteClient(
@@ -81,7 +88,8 @@
             wait_until='ACTIVE')
         # NOTE(mgoddard): Get detailed server to ensure addresses are present
         # in fixed IP case.
-        server = self.servers_client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(
+            server['id'])['server']
         # NOTE(artom) self.create_test_server adds cleanups, but this is
         # apparently not enough? Add cleanup here.
         self.addCleanup(self.delete_server, server['id'])
@@ -90,7 +98,7 @@
             fip = set([validation_resources['floating_ip']['ip']])
         except KeyError:
             fip = ()
-        ifs = (self.interfaces_client.list_interfaces(server['id'])
+        ifs = (self.reader_interfaces_client.list_interfaces(server['id'])
                ['interfaceAttachments'])
         body = waiters.wait_for_interface_status(
             self.interfaces_client, server['id'], ifs[0]['port_id'], 'ACTIVE')
@@ -107,7 +115,7 @@
         :param port_id: The id of the port being detached.
         :returns: The final port dict from the show_port response.
         """
-        port = self.ports_client.show_port(port_id)['port']
+        port = self.reader_ports_client.show_port(port_id)['port']
         device_id = port['device_id']
         start = int(time.time())
 
@@ -115,7 +123,7 @@
         # None, but it's not contractual so handle Falsey either way.
         while device_id:
             time.sleep(self.build_interval)
-            port = self.ports_client.show_port(port_id)['port']
+            port = self.reader_ports_client.show_port(port_id)['port']
             device_id = port['device_id']
 
             timed_out = int(time.time()) - start >= self.build_timeout
@@ -205,13 +213,13 @@
         # NOTE(danms): delete not the first or last, but one in the middle
         iface = ifs[1]
         self.interfaces_client.delete_interface(server['id'], iface['port_id'])
-        _ifs = (self.interfaces_client.list_interfaces(server['id'])
+        _ifs = (self.reader_interfaces_client.list_interfaces(server['id'])
                 ['interfaceAttachments'])
         start = int(time.time())
 
         while len(ifs) == len(_ifs):
             time.sleep(self.build_interval)
-            _ifs = (self.interfaces_client.list_interfaces(server['id'])
+            _ifs = (self.reader_interfaces_client.list_interfaces(server['id'])
                     ['interfaceAttachments'])
             timed_out = int(time.time()) - start >= self.build_timeout
             if len(ifs) == len(_ifs) and timed_out:
@@ -254,7 +262,7 @@
         iface = self._test_create_interface_by_port_id(server, ifs)
         ifs.append(iface)
 
-        _ifs = (self.interfaces_client.list_interfaces(server['id'])
+        _ifs = (self.reader_interfaces_client.list_interfaces(server['id'])
                 ['interfaceAttachments'])
         self._compare_iface_list(ifs, _ifs)
 
@@ -284,7 +292,7 @@
         iface = self._test_create_interface_by_fixed_ips(server, ifs)
         ifs.append(iface)
 
-        _ifs = (self.interfaces_client.list_interfaces(server['id'])
+        _ifs = (self.reader_interfaces_client.list_interfaces(server['id'])
                 ['interfaceAttachments'])
         self._compare_iface_list(ifs, _ifs)
 
@@ -340,7 +348,8 @@
         for server in servers:
             # NOTE(mgoddard): Get detailed server to ensure addresses are
             # present in fixed IP case.
-            server = self.servers_client.show_server(server['id'])['server']
+            server = self.reader_servers_client.show_server(server['id'])[
+                'server']
             compute.wait_for_ssh_or_ping(server, self.os_primary, network,
                                          True, validation_resources,
                                          'SSHABLE', True)
@@ -419,7 +428,7 @@
                 'Timed out while waiting for IP count to increase.')
 
         # Remove the fixed IP that we just added.
-        server_detail = self.os_primary.servers_client.show_server(
+        server_detail = self.reader_servers_client.show_server(
             server['id'])['server']
         # Get the Fixed IP from server.
         fixed_ip = None
@@ -467,4 +476,4 @@
             # just to check the response schema
             self.interfaces_client.show_interface(
                 server['id'], iface['port_id'])
-            self.interfaces_client.list_interfaces(server['id'])
+            self.reader_interfaces_client.list_interfaces(server['id'])
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index d239149..8e2b660 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -14,9 +14,13 @@
 #    under the License.
 
 from tempest.api.compute import base
+from tempest import config
 from tempest.lib import decorators
 
 
+CONF = config.CONF
+
+
 class AZV2TestJSON(base.BaseV2ComputeTest):
     """Tests Availability Zone API List"""
 
@@ -24,9 +28,14 @@
     def setup_clients(cls):
         super(AZV2TestJSON, cls).setup_clients()
         cls.client = cls.availability_zone_client
+        if CONF.enforce_scope.nova:
+            cls.reader_az_client = (
+                cls.os_project_reader.availability_zone_client)
+        else:
+            cls.reader_az_client = cls.client
 
     @decorators.idempotent_id('a8333aa2-205c-449f-a828-d38c2489bf25')
     def test_get_availability_zone_list_with_non_admin_user(self):
         """List of availability zone with non-administrator user"""
-        availability_zone = self.client.list_availability_zones()
+        availability_zone = self.reader_az_client.list_availability_zones()
         self.assertNotEmpty(availability_zone['availabilityZoneInfo'])
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 1454deb..a61f5fb 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -33,7 +33,6 @@
 
     This is to create server booted from image and with disk_config 'AUTO'
     """
-    credentials = ['primary', 'project_reader']
     disk_config = 'AUTO'
     volume_backed = False
 
@@ -45,11 +44,6 @@
     @classmethod
     def setup_clients(cls):
         super(ServersTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
-        if CONF.enforce_scope.nova:
-            cls.reader_client = cls.os_project_reader.servers_client
-        else:
-            cls.reader_client = cls.client
 
     @classmethod
     def resource_setup(cls):
@@ -75,7 +69,7 @@
             disk_config=disk_config,
             adminPass=cls.password,
             volume_backed=cls.volume_backed)
-        cls.server = cls.reader_client.show_server(
+        cls.server = cls.reader_servers_client.show_server(
             server_initial['id'])['server']
 
     @decorators.attr(type='smoke')
@@ -100,7 +94,7 @@
     @decorators.idempotent_id('9a438d88-10c6-4bcd-8b5b-5b6e25e1346f')
     def test_list_servers(self):
         """The created server should be in the list of all servers"""
-        body = self.reader_client.list_servers()
+        body = self.reader_servers_client.list_servers()
         servers = body['servers']
         found = [i for i in servers if i['id'] == self.server['id']]
         self.assertNotEmpty(found)
@@ -108,7 +102,7 @@
     @decorators.idempotent_id('585e934c-448e-43c4-acbf-d06a9b899997')
     def test_list_servers_with_detail(self):
         """The created server should be in the detailed list of all servers"""
-        body = self.reader_client.list_servers(detail=True)
+        body = self.reader_servers_client.list_servers(detail=True)
         servers = body['servers']
         found = [i for i in servers if i['id'] == self.server['id']]
         self.assertNotEmpty(found)
@@ -131,7 +125,7 @@
             self.password,
             validation_resources['keypair']['private_key'],
             server=self.server,
-            servers_client=self.client)
+            servers_client=self.servers_client)
         output = linux_client.exec_command('grep -c ^processor /proc/cpuinfo')
         self.assertEqual(flavor['vcpus'], int(output))
 
@@ -148,7 +142,7 @@
             self.password,
             validation_resources['keypair']['private_key'],
             server=self.server,
-            servers_client=self.client)
+            servers_client=self.servers_client)
         hostname = linux_client.exec_command("hostname").rstrip()
         msg = ('Failed while verifying servername equals hostname. Expected '
                'hostname "%s" but got "%s".' %
@@ -198,8 +192,6 @@
     server hostname with dashes. This test verifies the same.
     """
 
-    credentials = ['primary', 'project_reader']
-
     @classmethod
     def setup_credentials(cls):
         cls.prepare_instance_network()
@@ -208,11 +200,6 @@
     @classmethod
     def setup_clients(cls):
         super(ServersTestFqdnHostnames, cls).setup_clients()
-        cls.client = cls.servers_client
-        if CONF.enforce_scope.nova:
-            cls.reader_client = cls.os_project_reader.servers_client
-        else:
-            cls.reader_client = cls.client
 
     @decorators.idempotent_id('622066d2-39fc-4c09-9eeb-35903c114a0a')
     @testtools.skipUnless(
@@ -245,7 +232,7 @@
             self.password,
             validation_resources['keypair']['private_key'],
             server=test_server,
-            servers_client=self.client)
+            servers_client=self.servers_client)
         hostname = linux_client.exec_command("hostname").rstrip()
         self.assertEqual('guest-instance-1-domain-com', hostname)
 
@@ -261,7 +248,6 @@
     more than 64 characters
     """
 
-    credentials = ['primary', 'project_reader']
     min_microversion = '2.94'
 
     @classmethod
@@ -272,11 +258,6 @@
     @classmethod
     def setup_clients(cls):
         super(ServersV294TestFqdnHostnames, cls).setup_clients()
-        cls.client = cls.servers_client
-        if CONF.enforce_scope.nova:
-            cls.reader_client = cls.os_project_reader.servers_client
-        else:
-            cls.reader_client = cls.client
 
     @classmethod
     def resource_setup(cls):
@@ -295,7 +276,7 @@
             accessIPv4=cls.accessIPv4,
             adminPass=cls.password,
             hostname=cls.hostname)
-        cls.server = cls.reader_client.show_server(
+        cls.server = cls.reader_servers_client.show_server(
             cls.test_server['id'])['server']
 
     def verify_metadata_hostname(self, md_json):
@@ -324,6 +305,6 @@
             self.password,
             self.validation_resources['keypair']['private_key'],
             server=self.test_server,
-            servers_client=self.client)
+            servers_client=self.servers_client)
         self.verify_metadata_from_api(
             self.test_server, linux_client, self.verify_metadata_hostname)
diff --git a/tempest/api/compute/servers/test_create_server_multi_nic.py b/tempest/api/compute/servers/test_create_server_multi_nic.py
index 828ee32..fc75e2f 100644
--- a/tempest/api/compute/servers/test_create_server_multi_nic.py
+++ b/tempest/api/compute/servers/test_create_server_multi_nic.py
@@ -48,8 +48,6 @@
 class ServersTestMultiNic(base.BaseV2ComputeTest):
     """Test multiple networks in servers"""
 
-    credentials = ['primary', 'project_reader']
-
     @classmethod
     def skip_checks(cls):
         super(ServersTestMultiNic, cls).skip_checks()
@@ -64,10 +62,6 @@
     @classmethod
     def setup_clients(cls):
         super(ServersTestMultiNic, cls).setup_clients()
-        if CONF.enforce_scope.nova:
-            cls.reader_client = cls.os_project_reader.servers_client
-        else:
-            cls.reader_client = cls.servers_client
         cls.networks_client = cls.os_primary.networks_client
         cls.subnets_client = cls.os_primary.subnets_client
 
@@ -112,8 +106,8 @@
         # we're OK.
         self.addCleanup(self.delete_server, server_multi_nics['id'])
 
-        addresses = (self.reader_client.list_addresses(server_multi_nics['id'])
-                     ['addresses'])
+        addresses = (self.reader_servers_client.list_addresses(
+            server_multi_nics['id'])['addresses'])
 
         # We can't predict the ip addresses assigned to the server on networks.
         # So we check if the first address is in first network, similarly
@@ -147,8 +141,8 @@
             networks=networks, wait_until='ACTIVE')
         self.addCleanup(self.delete_server, server_multi_nics['id'])
 
-        addresses = (self.reader_client.list_addresses(server_multi_nics['id'])
-                     ['addresses'])
+        addresses = (self.reader_servers_client.list_addresses(
+            server_multi_nics['id'])['addresses'])
 
         addr = [addresses[net1['network']['name']][0]['addr'],
                 addresses[net2['network']['name']][0]['addr'],
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index 596d2bd..5fb669e 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -35,30 +35,30 @@
     @classmethod
     def setup_clients(cls):
         super(DeleteServersTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @decorators.idempotent_id('9e6e0c87-3352-42f7-9faf-5d6210dbd159')
     def test_delete_server_while_in_building_state(self):
         """Test deleting a server while it's VM state is Building"""
         server = self.create_test_server(wait_until='BUILD')
-        self.client.delete_server(server['id'])
-        waiters.wait_for_server_termination(self.client, server['id'])
+        self.servers_client.delete_server(server['id'])
+        waiters.wait_for_server_termination(self.servers_client, server['id'])
 
     @decorators.idempotent_id('925fdfb4-5b13-47ea-ac8a-c36ae6fddb05')
     def test_delete_active_server(self):
         """Test deleting a server while it's VM state is Active"""
         server = self.create_test_server(wait_until='ACTIVE')
-        self.client.delete_server(server['id'])
-        waiters.wait_for_server_termination(self.client, server['id'])
+        self.servers_client.delete_server(server['id'])
+        waiters.wait_for_server_termination(self.servers_client, server['id'])
 
     @decorators.idempotent_id('546d368c-bb6c-4645-979a-83ed16f3a6be')
     def test_delete_server_while_in_shutoff_state(self):
         """Test deleting a server while it's VM state is Shutoff"""
         server = self.create_test_server(wait_until='ACTIVE')
-        self.client.stop_server(server['id'])
-        waiters.wait_for_server_status(self.client, server['id'], 'SHUTOFF')
-        self.client.delete_server(server['id'])
-        waiters.wait_for_server_termination(self.client, server['id'])
+        self.servers_client.stop_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'SHUTOFF')
+        self.servers_client.delete_server(server['id'])
+        waiters.wait_for_server_termination(self.servers_client, server['id'])
 
     @decorators.idempotent_id('943bd6e8-4d7a-4904-be83-7a6cc2d4213b')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
@@ -66,10 +66,11 @@
     def test_delete_server_while_in_pause_state(self):
         """Test deleting a server while it's VM state is Pause"""
         server = self.create_test_server(wait_until='ACTIVE')
-        self.client.pause_server(server['id'])
-        waiters.wait_for_server_status(self.client, server['id'], 'PAUSED')
-        self.client.delete_server(server['id'])
-        waiters.wait_for_server_termination(self.client, server['id'])
+        self.servers_client.pause_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'PAUSED')
+        self.servers_client.delete_server(server['id'])
+        waiters.wait_for_server_termination(self.servers_client, server['id'])
 
     @decorators.idempotent_id('1f82ebd3-8253-4f4e-b93f-de9b7df56d8b')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
@@ -77,10 +78,11 @@
     def test_delete_server_while_in_suspended_state(self):
         """Test deleting a server while it's VM state is Suspended"""
         server = self.create_test_server(wait_until='ACTIVE')
-        self.client.suspend_server(server['id'])
-        waiters.wait_for_server_status(self.client, server['id'], 'SUSPENDED')
-        self.client.delete_server(server['id'])
-        waiters.wait_for_server_termination(self.client, server['id'])
+        self.servers_client.suspend_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'SUSPENDED')
+        self.servers_client.delete_server(server['id'])
+        waiters.wait_for_server_termination(self.servers_client, server['id'])
 
     @decorators.idempotent_id('bb0cb402-09dd-4947-b6e5-5e7e1cfa61ad')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
@@ -88,10 +90,10 @@
     def test_delete_server_while_in_shelved_state(self):
         """Test deleting a server while it's VM state is Shelved"""
         server = self.create_test_server(wait_until='ACTIVE')
-        compute.shelve_server(self.client, server['id'])
+        compute.shelve_server(self.servers_client, server['id'])
 
-        self.client.delete_server(server['id'])
-        waiters.wait_for_server_termination(self.client, server['id'])
+        self.servers_client.delete_server(server['id'])
+        waiters.wait_for_server_termination(self.servers_client, server['id'])
 
     @decorators.idempotent_id('ab0c38b4-cdd8-49d3-9b92-0cb898723c01')
     @testtools.skipIf(not CONF.compute_feature_enabled.resize,
@@ -99,14 +101,16 @@
     def test_delete_server_while_in_verify_resize_state(self):
         """Test deleting a server while it's VM state is VERIFY_RESIZE"""
         server = self.create_test_server(wait_until='ACTIVE')
-        body = self.client.resize_server(server['id'], self.flavor_ref_alt)
+        body = self.servers_client.resize_server(server['id'],
+                                                 self.flavor_ref_alt)
         request_id = body.response['x-openstack-request-id']
         waiters.wait_for_server_status(
-            self.client, server['id'], 'VERIFY_RESIZE', request_id=request_id)
-        body = self.client.delete_server(server['id'])
+            self.servers_client, server['id'], 'VERIFY_RESIZE',
+            request_id=request_id)
+        body = self.servers_client.delete_server(server['id'])
         request_id = body.response['x-openstack-request-id']
         waiters.wait_for_server_termination(
-            self.client, server['id'], request_id=request_id)
+            self.servers_client, server['id'], request_id=request_id)
 
     @decorators.idempotent_id('d0f3f0d6-d9b6-4a32-8da4-23015dcab23c')
     @utils.services('volume')
@@ -117,7 +121,7 @@
         volume = self.create_volume()
         self.attach_volume(server, volume)
 
-        self.client.delete_server(server['id'])
-        waiters.wait_for_server_termination(self.client, server['id'])
+        self.servers_client.delete_server(server['id'])
+        waiters.wait_for_server_termination(self.servers_client, server['id'])
         waiters.wait_for_volume_resource_status(self.volumes_client,
                                                 volume['id'], 'available')
diff --git a/tempest/api/compute/servers/test_device_tagging.py b/tempest/api/compute/servers/test_device_tagging.py
index d2fdd52..fd087ea 100644
--- a/tempest/api/compute/servers/test_device_tagging.py
+++ b/tempest/api/compute/servers/test_device_tagging.py
@@ -256,7 +256,8 @@
 
         self.addCleanup(self.delete_server, server['id'])
 
-        server = self.servers_client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(
+            server['id'])['server']
         ssh_client = remote_client.RemoteClient(
             self.get_server_ip(server, validation_resources),
             CONF.validation.image_ssh_user,
@@ -388,7 +389,8 @@
 
         # NOTE(mgoddard): Get detailed server to ensure addresses are present
         # in fixed IP case.
-        server = self.servers_client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(
+            server['id'])['server']
 
         # Attach tagged nic and volume
         interface = self.interfaces_client.create_interface(
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index e5e051a..fc79e37 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -38,53 +38,56 @@
     @classmethod
     def setup_clients(cls):
         super(ServerDiskConfigTestJSON, cls).setup_clients()
-        cls.client = cls.os_primary.servers_client
 
     def _update_server_with_disk_config(self, server_id, disk_config):
-        server = self.client.show_server(server_id)['server']
+        server = self.reader_servers_client.show_server(server_id)['server']
         if disk_config != server['OS-DCF:diskConfig']:
-            server = self.client.update_server(
+            server = self.servers_client.update_server(
                 server_id, disk_config=disk_config)['server']
-            waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
-            server = self.client.show_server(server['id'])['server']
+            waiters.wait_for_server_status(self.servers_client, server['id'],
+                                           'ACTIVE')
+            server = self.reader_servers_client.show_server(
+                server['id'])['server']
             self.assertEqual(disk_config, server['OS-DCF:diskConfig'])
 
     @decorators.idempotent_id('bef56b09-2e8c-4883-a370-4950812f430e')
     def test_rebuild_server_with_manual_disk_config(self):
         """A server should be rebuilt using the manual disk config option"""
         server = self.create_test_server(wait_until='ACTIVE')
-        self.addCleanup(self.client.delete_server, server['id'])
+        self.addCleanup(self.servers_client.delete_server, server['id'])
         self._update_server_with_disk_config(server['id'],
                                              disk_config='AUTO')
 
-        server = self.client.rebuild_server(server['id'],
-                                            self.image_ref_alt,
-                                            disk_config='MANUAL')['server']
+        server = self.servers_client.rebuild_server(
+            server['id'], self.image_ref_alt,
+            disk_config='MANUAL')['server']
 
         # Wait for the server to become active
-        waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'ACTIVE')
 
         # Verify the specified attributes are set correctly
-        server = self.client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
     @decorators.idempotent_id('9c9fae77-4feb-402f-8450-bf1c8b609713')
     def test_rebuild_server_with_auto_disk_config(self):
         """A server should be rebuilt using the auto disk config option"""
         server = self.create_test_server(wait_until='ACTIVE')
-        self.addCleanup(self.client.delete_server, server['id'])
+        self.addCleanup(self.servers_client.delete_server, server['id'])
         self._update_server_with_disk_config(server['id'],
                                              disk_config='MANUAL')
 
-        server = self.client.rebuild_server(server['id'],
-                                            self.image_ref_alt,
-                                            disk_config='AUTO')['server']
+        server = self.servers_client.rebuild_server(
+            server['id'], self.image_ref_alt,
+            disk_config='AUTO')['server']
 
         # Wait for the server to become active
-        waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'ACTIVE')
 
         # Verify the specified attributes are set correctly
-        server = self.client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
         self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
 
     @decorators.idempotent_id('414e7e93-45b5-44bc-8e03-55159c6bfc97')
@@ -93,14 +96,14 @@
     def test_resize_server_from_manual_to_auto(self):
         """A server should be resized from manual to auto disk config"""
         server = self.create_test_server(wait_until='ACTIVE')
-        self.addCleanup(self.client.delete_server, server['id'])
+        self.addCleanup(self.servers_client.delete_server, server['id'])
         self._update_server_with_disk_config(server['id'],
                                              disk_config='MANUAL')
         # Resize with auto option
         self.resize_server(server['id'], self.flavor_ref_alt,
                            disk_config='AUTO')
 
-        server = self.client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
         self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
 
     @decorators.idempotent_id('693d16f3-556c-489a-8bac-3d0ca2490bad')
@@ -109,29 +112,30 @@
     def test_resize_server_from_auto_to_manual(self):
         """A server should be resized from auto to manual disk config"""
         server = self.create_test_server(wait_until='ACTIVE')
-        self.addCleanup(self.client.delete_server, server['id'])
+        self.addCleanup(self.servers_client.delete_server, server['id'])
         self._update_server_with_disk_config(server['id'],
                                              disk_config='AUTO')
         # Resize with manual option
         self.resize_server(server['id'], self.flavor_ref_alt,
                            disk_config='MANUAL')
 
-        server = self.client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
     @decorators.idempotent_id('5ef18867-358d-4de9-b3c9-94d4ba35742f')
     def test_update_server_from_auto_to_manual(self):
         """A server should be updated from auto to manual disk config"""
         server = self.create_test_server(wait_until='ACTIVE')
-        self.addCleanup(self.client.delete_server, server['id'])
+        self.addCleanup(self.servers_client.delete_server, server['id'])
         self._update_server_with_disk_config(server['id'],
                                              disk_config='AUTO')
 
         # Update the disk_config attribute to manual
-        server = self.client.update_server(server['id'],
-                                           disk_config='MANUAL')['server']
-        waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
+        server = self.servers_client.update_server(
+            server['id'], disk_config='MANUAL')['server']
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'ACTIVE')
 
         # Verify the disk_config attribute is set correctly
-        server = self.client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
diff --git a/tempest/api/compute/servers/test_instance_actions.py b/tempest/api/compute/servers/test_instance_actions.py
index 028da68..6a68aab 100644
--- a/tempest/api/compute/servers/test_instance_actions.py
+++ b/tempest/api/compute/servers/test_instance_actions.py
@@ -15,9 +15,13 @@
 
 from tempest.api.compute import base
 from tempest.common import waiters
+from tempest import config
 from tempest.lib import decorators
 
 
+CONF = config.CONF
+
+
 class InstanceActionsTestJSON(base.BaseV2ComputeTest):
     """Test instance actions API"""
 
@@ -26,7 +30,6 @@
     @classmethod
     def setup_clients(cls):
         super(InstanceActionsTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @classmethod
     def resource_setup(cls):
@@ -39,8 +42,8 @@
         """Test listing actions of the provided server"""
         self.reboot_server(self.server['id'], type='HARD')
 
-        body = (self.client.list_instance_actions(self.server['id'])
-                ['instanceActions'])
+        body = (self.reader_servers_client.list_instance_actions(
+            self.server['id'])['instanceActions'])
         self.assertEqual(len(body), 2, str(body))
         self.assertEqual(sorted([i['action'] for i in body]),
                          ['create', 'reboot'])
@@ -48,7 +51,7 @@
     @decorators.idempotent_id('aacc71ca-1d70-4aa5-bbf6-0ff71470e43c')
     def test_get_instance_action(self):
         """Test getting the action details of the provided server"""
-        body = self.client.show_instance_action(
+        body = self.reader_servers_client.show_instance_action(
             self.server['id'], self.request_id)['instanceAction']
         self.assertEqual(self.server['id'], body['instance_uuid'])
         self.assertEqual('create', body['action'])
@@ -65,7 +68,6 @@
     @classmethod
     def setup_clients(cls):
         super(InstanceActionsV221TestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @decorators.idempotent_id('0a0f85d4-10fa-41f6-bf80-a54fb4aa2ae1')
     def test_get_list_deleted_instance_actions(self):
@@ -75,9 +77,9 @@
         actions should contain 'create' and 'delete'.
         """
         server = self.create_test_server(wait_until='ACTIVE')
-        self.client.delete_server(server['id'])
-        waiters.wait_for_server_termination(self.client, server['id'])
-        body = (self.client.list_instance_actions(server['id'])
+        self.servers_client.delete_server(server['id'])
+        waiters.wait_for_server_termination(self.servers_client, server['id'])
+        body = (self.reader_servers_client.list_instance_actions(server['id'])
                 ['instanceActions'])
         self.assertEqual(len(body), 2, str(body))
         self.assertEqual(sorted([i['action'] for i in body]),
diff --git a/tempest/api/compute/servers/test_instance_actions_negative.py b/tempest/api/compute/servers/test_instance_actions_negative.py
index dd2bf06..8e5b883 100644
--- a/tempest/api/compute/servers/test_instance_actions_negative.py
+++ b/tempest/api/compute/servers/test_instance_actions_negative.py
@@ -27,7 +27,6 @@
     @classmethod
     def setup_clients(cls):
         super(InstanceActionsNegativeTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @classmethod
     def resource_setup(cls):
@@ -40,12 +39,13 @@
         """Test listing actions for non existent instance should fail"""
         non_existent_server_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.list_instance_actions,
+                          self.reader_servers_client.list_instance_actions,
                           non_existent_server_id)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('0269f40a-6f18-456c-b336-c03623c897f1')
     def test_get_instance_action_invalid_request(self):
         """Test getting instance action with invalid request_id should fail"""
-        self.assertRaises(lib_exc.NotFound, self.client.show_instance_action,
+        self.assertRaises(lib_exc.NotFound,
+                          self.reader_servers_client.show_instance_action,
                           self.server['id'], '999')
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 45f3348..20d460c 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -28,8 +28,6 @@
 class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
     """Test listing servers filtered by specified attribute"""
 
-    credentials = ['primary', 'project_reader']
-
     @classmethod
     def setup_credentials(cls):
         cls.set_network_resources(network=True, subnet=True, dhcp=True)
@@ -38,11 +36,6 @@
     @classmethod
     def setup_clients(cls):
         super(ListServerFiltersTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
-        if CONF.enforce_scope.nova:
-            cls.reader_client = cls.os_project_reader.servers_client
-        else:
-            cls.reader_client = cls.client
 
     @classmethod
     def resource_setup(cls):
@@ -75,9 +68,9 @@
                                         flavor=cls.flavor_ref_alt,
                                         wait_until='ACTIVE')
 
-        waiters.wait_for_server_status(cls.client, cls.s1['id'],
+        waiters.wait_for_server_status(cls.servers_client, cls.s1['id'],
                                        'ACTIVE')
-        waiters.wait_for_server_status(cls.client, cls.s2['id'],
+        waiters.wait_for_server_status(cls.servers_client, cls.s2['id'],
                                        'ACTIVE')
 
     @decorators.idempotent_id('05e8a8e7-9659-459a-989d-92c2f501f4ba')
@@ -86,7 +79,7 @@
     def test_list_servers_filter_by_image(self):
         """Filter the list of servers by image"""
         params = {'image': self.image_ref}
-        body = self.reader_client.list_servers(**params)
+        body = self.reader_servers_client.list_servers(**params)
         servers = body['servers']
 
         self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -97,7 +90,7 @@
     def test_list_servers_filter_by_flavor(self):
         """Filter the list of servers by flavor"""
         params = {'flavor': self.flavor_ref_alt}
-        body = self.reader_client.list_servers(**params)
+        body = self.reader_servers_client.list_servers(**params)
         servers = body['servers']
 
         self.assertNotIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -108,7 +101,7 @@
     def test_list_servers_filter_by_server_name(self):
         """Filter the list of servers by server name"""
         params = {'name': self.s1_name}
-        body = self.reader_client.list_servers(**params)
+        body = self.reader_servers_client.list_servers(**params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -119,7 +112,7 @@
     def test_list_servers_filter_by_active_status(self):
         """Filter the list of servers by server active status"""
         params = {'status': 'active'}
-        body = self.reader_client.list_servers(**params)
+        body = self.reader_servers_client.list_servers(**params)
         servers = body['servers']
 
         self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -130,12 +123,12 @@
     def test_list_servers_filter_by_shutoff_status(self):
         """Filter the list of servers by server shutoff status"""
         params = {'status': 'shutoff'}
-        self.client.stop_server(self.s1['id'])
-        waiters.wait_for_server_status(self.client, self.s1['id'],
+        self.servers_client.stop_server(self.s1['id'])
+        waiters.wait_for_server_status(self.servers_client, self.s1['id'],
                                        'SHUTOFF')
-        body = self.reader_client.list_servers(**params)
-        self.client.start_server(self.s1['id'])
-        waiters.wait_for_server_status(self.client, self.s1['id'],
+        body = self.reader_servers_client.list_servers(**params)
+        self.servers_client.start_server(self.s1['id'])
+        waiters.wait_for_server_status(self.servers_client, self.s1['id'],
                                        'ACTIVE')
         servers = body['servers']
 
@@ -150,7 +143,7 @@
         Verify only the expected number of servers are returned (one server)
         """
         params = {'limit': 1}
-        servers = self.reader_client.list_servers(**params)
+        servers = self.reader_servers_client.list_servers(**params)
         self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
 
     @decorators.idempotent_id('b1495414-2d93-414c-8019-849afe8d319e')
@@ -160,7 +153,7 @@
         Verify only the expected number of servers are returned (no server)
         """
         params = {'limit': 0}
-        servers = self.reader_client.list_servers(**params)
+        servers = self.reader_servers_client.list_servers(**params)
         self.assertEmpty(servers['servers'])
 
     @decorators.idempotent_id('37791bbd-90c0-4de0-831e-5f38cba9c6b3')
@@ -170,8 +163,8 @@
         Verify only the expected number of servers are returned (all servers)
         """
         params = {'limit': 100000}
-        servers = self.reader_client.list_servers(**params)
-        all_servers = self.reader_client.list_servers()
+        servers = self.reader_servers_client.list_servers(**params)
+        all_servers = self.reader_servers_client.list_servers()
         self.assertEqual(len([x for x in all_servers['servers'] if 'id' in x]),
                          len([x for x in servers['servers'] if 'id' in x]))
 
@@ -181,7 +174,7 @@
     def test_list_servers_detailed_filter_by_image(self):
         """"Filter the detailed list of servers by image"""
         params = {'image': self.image_ref}
-        body = self.reader_client.list_servers(detail=True, **params)
+        body = self.reader_servers_client.list_servers(detail=True, **params)
         servers = body['servers']
 
         self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -192,7 +185,7 @@
     def test_list_servers_detailed_filter_by_flavor(self):
         """Filter the detailed list of servers by flavor"""
         params = {'flavor': self.flavor_ref_alt}
-        body = self.reader_client.list_servers(detail=True, **params)
+        body = self.reader_servers_client.list_servers(detail=True, **params)
         servers = body['servers']
 
         self.assertNotIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -203,7 +196,7 @@
     def test_list_servers_detailed_filter_by_server_name(self):
         """Filter the detailed list of servers by server name"""
         params = {'name': self.s1_name}
-        body = self.reader_client.list_servers(detail=True, **params)
+        body = self.reader_servers_client.list_servers(detail=True, **params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -214,7 +207,7 @@
     def test_list_servers_detailed_filter_by_server_status(self):
         """Filter the detailed list of servers by server status"""
         params = {'status': 'active'}
-        body = self.reader_client.list_servers(detail=True, **params)
+        body = self.reader_servers_client.list_servers(detail=True, **params)
         servers = body['servers']
         test_ids = [s['id'] for s in (self.s1, self.s2, self.s3)]
 
@@ -229,7 +222,7 @@
         """Filter the list of servers by part of server name"""
         # List all servers that contains '-instance' in name
         params = {'name': '-instance'}
-        body = self.reader_client.list_servers(**params)
+        body = self.reader_servers_client.list_servers(**params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -240,7 +233,7 @@
         part_name = self.s1_name[6:-1]
 
         params = {'name': part_name}
-        body = self.reader_client.list_servers(**params)
+        body = self.reader_servers_client.list_servers(**params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -254,7 +247,7 @@
         regexes = [r'^.*\-instance\-[0-9]+$', r'^.*\-instance\-.*$']
         for regex in regexes:
             params = {'name': regex}
-            body = self.reader_client.list_servers(**params)
+            body = self.reader_servers_client.list_servers(**params)
             servers = body['servers']
 
             self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -265,7 +258,7 @@
         part_name = self.s1_name[-10:]
 
         params = {'name': part_name}
-        body = self.reader_client.list_servers(**params)
+        body = self.reader_servers_client.list_servers(**params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -285,22 +278,25 @@
         # so here look for the longest server ip, and filter by that ip,
         # so as to ensure only one server is returned.
         ip_list = {}
-        self.s1 = self.reader_client.show_server(self.s1['id'])['server']
+        self.s1 = self.reader_servers_client.show_server(
+            self.s1['id'])['server']
         # Get first ip address in spite of v4 or v6
         ip_addr = self.s1['addresses'][self.fixed_network_name][0]['addr']
         ip_list[ip_addr] = self.s1['id']
 
-        self.s2 = self.reader_client.show_server(self.s2['id'])['server']
+        self.s2 = self.reader_servers_client.show_server(
+            self.s2['id'])['server']
         ip_addr = self.s2['addresses'][self.fixed_network_name][0]['addr']
         ip_list[ip_addr] = self.s2['id']
 
-        self.s3 = self.reader_client.show_server(self.s3['id'])['server']
+        self.s3 = self.reader_servers_client.show_server(
+            self.s3['id'])['server']
         ip_addr = self.s3['addresses'][self.fixed_network_name][0]['addr']
         ip_list[ip_addr] = self.s3['id']
 
         longest_ip = max([[len(ip), ip] for ip in ip_list])[1]
         params = {'ip': longest_ip}
-        body = self.reader_client.list_servers(**params)
+        body = self.reader_servers_client.list_servers(**params)
         servers = body['servers']
 
         self.assertIn(ip_list[longest_ip], map(lambda x: x['id'], servers))
@@ -317,7 +313,7 @@
         # query addresses of the 3 servers
         addrs = []
         for s in [self.s1, self.s2, self.s3]:
-            s_show = self.reader_client.show_server(s['id'])['server']
+            s_show = self.reader_servers_client.show_server(s['id'])['server']
             addr_spec = s_show['addresses'][self.fixed_network_name][0]
             addrs.append(addr_spec['addr'])
         # find common part of the 3 ip addresses
@@ -335,8 +331,8 @@
         else:
             params = {'ip6': prefix}
         # capture all servers in case something goes wrong
-        all_servers = self.reader_client.list_servers(detail=True)
-        body = self.reader_client.list_servers(**params)
+        all_servers = self.reader_servers_client.list_servers(detail=True)
+        body = self.reader_servers_client.list_servers(**params)
         servers = body['servers']
 
         self.assertIn(self.s1_name, map(lambda x: x['name'], servers),
@@ -356,5 +352,6 @@
         Verify only the expected number of servers are returned (one server)
         """
         params = {'limit': 1}
-        servers = self.reader_client.list_servers(detail=True, **params)
+        servers = self.reader_servers_client.list_servers(detail=True,
+                                                          **params)
         self.assertEqual(1, len(servers['servers']))
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 140e5c3..afa785c 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -26,17 +26,11 @@
 class ListServersNegativeTestJSON(base.BaseV2ComputeTest):
     """Negative tests of listing servers"""
 
-    credentials = ['primary', 'project_reader']
     create_default_network = True
 
     @classmethod
     def setup_clients(cls):
         super(ListServersNegativeTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
-        if CONF.enforce_scope.nova:
-            cls.reader_client = cls.os_project_reader.servers_client
-        else:
-            cls.reader_client = cls.client
 
     @classmethod
     def resource_setup(cls):
@@ -50,15 +44,16 @@
 
         # delete one of the created servers
         cls.deleted_id = body['server']['id']
-        cls.client.delete_server(cls.deleted_id)
-        waiters.wait_for_server_termination(cls.client, cls.deleted_id)
+        cls.servers_client.delete_server(cls.deleted_id)
+        waiters.wait_for_server_termination(
+            cls.servers_client, cls.deleted_id)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('24a26f1a-1ddc-4eea-b0d7-a90cc874ad8f')
     def test_list_servers_with_a_deleted_server(self):
         """Test that deleted servers do not show by default in list servers"""
         # List servers and verify server not returned
-        body = self.reader_client.list_servers()
+        body = self.reader_servers_client.list_servers()
         servers = body['servers']
         actual = [srv for srv in servers
                   if srv['id'] == self.deleted_id]
@@ -68,7 +63,8 @@
     @decorators.idempotent_id('ff01387d-c7ad-47b4-ae9e-64fa214638fe')
     def test_list_servers_by_non_existing_image(self):
         """Test listing servers for a non existing image returns empty list"""
-        body = self.reader_client.list_servers(image='non_existing_image')
+        body = self.reader_servers_client.list_servers(
+            image='non_existing_image')
         servers = body['servers']
         self.assertEmpty(servers)
 
@@ -76,7 +72,8 @@
     @decorators.idempotent_id('5913660b-223b-44d4-a651-a0fbfd44ca75')
     def test_list_servers_by_non_existing_flavor(self):
         """Test listing servers by non existing flavor returns empty list"""
-        body = self.reader_client.list_servers(flavor='non_existing_flavor')
+        body = self.reader_servers_client.list_servers(
+            flavor='non_existing_flavor')
         servers = body['servers']
         self.assertEmpty(servers)
 
@@ -89,7 +86,8 @@
         list.
         """
 
-        body = self.reader_client.list_servers(name='non_existing_server_name')
+        body = self.reader_servers_client.list_servers(
+            name='non_existing_server_name')
         servers = body['servers']
         self.assertEmpty(servers)
 
@@ -104,13 +102,14 @@
         """
 
         if self.is_requested_microversion_compatible('2.37'):
-            body = self.reader_client.list_servers(
+            body = self.reader_servers_client.list_servers(
                 status='non_existing_status')
             servers = body['servers']
             self.assertEmpty(servers)
         else:
             self.assertRaises(
-                lib_exc.BadRequest, self.reader_client.list_servers,
+                lib_exc.BadRequest,
+                self.reader_servers_client.list_servers,
                 status='non_existing_status')
 
     @decorators.attr(type=['negative'])
@@ -123,33 +122,39 @@
         """
 
         # Gather the complete list of servers in the project for reference
-        full_list = self.reader_client.list_servers()['servers']
+        full_list = self.reader_servers_client.list_servers()['servers']
         # List servers by specifying a greater value for limit
         limit = len(full_list) + 100
-        body = self.reader_client.list_servers(limit=limit)
+        body = self.reader_servers_client.list_servers(limit=limit)
         self.assertEqual(len(full_list), len(body['servers']))
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('679bc053-5e70-4514-9800-3dfab1a380a6')
     def test_list_servers_by_limits_pass_string(self):
         """Test listing servers by non-integer limit should fail"""
-        self.assertRaises(lib_exc.BadRequest, self.reader_client.list_servers,
-                          limit='testing')
+        self.assertRaises(
+            lib_exc.BadRequest,
+            self.reader_servers_client.list_servers,
+            limit='testing')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('62610dd9-4713-4ee0-8beb-fd2c1aa7f950')
     def test_list_servers_by_limits_pass_negative_value(self):
         """Test listing servers by negative limit should fail"""
-        self.assertRaises(lib_exc.BadRequest, self.reader_client.list_servers,
-                          limit=-1)
+        self.assertRaises(
+            lib_exc.BadRequest,
+            self.reader_servers_client.list_servers,
+            limit=-1)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('87d12517-e20a-4c9c-97b6-dd1628d6d6c9')
     def test_list_servers_by_changes_since_invalid_date(self):
         """Test listing servers by invalid changes-since format should fail"""
         params = {'changes-since': '2011/01/01'}
-        self.assertRaises(lib_exc.BadRequest, self.reader_client.list_servers,
-                          **params)
+        self.assertRaises(
+            lib_exc.BadRequest,
+            self.reader_servers_client.list_servers,
+            **params)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('74745ad8-b346-45b5-b9b8-509d7447fc1f')
@@ -165,14 +170,14 @@
         # {'status': 'ACTIVE'} along with changes-since as filter.
         changes_since = {'changes-since': '2051-01-01T12:34:00Z',
                          'status': 'ACTIVE'}
-        body = self.reader_client.list_servers(**changes_since)
+        body = self.reader_servers_client.list_servers(**changes_since)
         self.assertEmpty(body['servers'])
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('93055106-2d34-46fe-af68-d9ddbf7ee570')
     def test_list_servers_detail_server_is_deleted(self):
         """Test listing servers detail should not contain deleted server"""
-        body = self.reader_client.list_servers(detail=True)
+        body = self.reader_servers_client.list_servers(detail=True)
         servers = body['servers']
         actual = [srv for srv in servers
                   if srv['id'] == self.deleted_id]
diff --git a/tempest/api/compute/servers/test_novnc.py b/tempest/api/compute/servers/test_novnc.py
index a9f68e6..95f5b99 100644
--- a/tempest/api/compute/servers/test_novnc.py
+++ b/tempest/api/compute/servers/test_novnc.py
@@ -51,7 +51,6 @@
     @classmethod
     def setup_clients(cls):
         super(NoVNCConsoleTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @classmethod
     def resource_setup(cls):
@@ -65,12 +64,12 @@
     def test_novnc(self):
         """Test accessing novnc console of server"""
         if self.use_get_remote_console:
-            body = self.client.get_remote_console(
+            body = self.servers_client.get_remote_console(
                 self.server['id'], console_type='novnc',
                 protocol='vnc')['remote_console']
         else:
-            body = self.client.get_vnc_console(self.server['id'],
-                                               type='novnc')['console']
+            body = self.servers_client.get_vnc_console(self.server['id'],
+                                                       type='novnc')['console']
         self.assertEqual('novnc', body['type'])
         # Do the initial HTTP Request to novncproxy to get the NoVNC JavaScript
         self.validate_novnc_html(body['url'])
@@ -89,12 +88,12 @@
         the novnc proxy should reject the connection and closed it.
         """
         if self.use_get_remote_console:
-            body = self.client.get_remote_console(
+            body = self.servers_client.get_remote_console(
                 self.server['id'], console_type='novnc',
                 protocol='vnc')['remote_console']
         else:
-            body = self.client.get_vnc_console(self.server['id'],
-                                               type='novnc')['console']
+            body = self.servers_client.get_vnc_console(self.server['id'],
+                                                       type='novnc')['console']
         self.assertEqual('novnc', body['type'])
         # Do the WebSockify HTTP Request to novncproxy with a bad token
         parts = urlparse.urlparse(body['url'])
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 10153bb..1fe4a65 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -45,7 +45,7 @@
         try:
             self.validation_resources = self.get_class_validation_resources(
                 self.os_primary)
-            waiters.wait_for_server_status(self.client,
+            waiters.wait_for_server_status(self.servers_client,
                                            self.server_id, 'ACTIVE')
         except lib_exc.NotFound:
             # The server was deleted by previous test, create a new one
@@ -78,7 +78,6 @@
     @classmethod
     def setup_clients(cls):
         super(ServerActionsBase, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @classmethod
     def resource_setup(cls):
@@ -89,14 +88,15 @@
     def _test_reboot_server(self, reboot_type):
         if CONF.validation.run_validation:
             # Get the time the server was last rebooted,
-            server = self.client.show_server(self.server_id)['server']
+            server = self.reader_servers_client.show_server(
+                self.server_id)['server']
             linux_client = remote_client.RemoteClient(
                 self.get_server_ip(server, self.validation_resources),
                 self.ssh_user,
                 self.password,
                 self.validation_resources['keypair']['private_key'],
                 server=server,
-                servers_client=self.client)
+                servers_client=self.servers_client)
             boot_time = linux_client.get_boot_time()
 
             # NOTE: This sync is for avoiding the loss of pub key data
@@ -113,22 +113,23 @@
                 self.password,
                 self.validation_resources['keypair']['private_key'],
                 server=server,
-                servers_client=self.client)
+                servers_client=self.servers_client)
             new_boot_time = linux_client.get_boot_time()
             self.assertGreater(new_boot_time, boot_time,
                                '%s > %s' % (new_boot_time, boot_time))
 
     def _test_rebuild_server(self, server_id, **kwargs):
         # Get the IPs the server has before rebuilding it
-        original_addresses = (self.client.show_server(server_id)['server']
-                              ['addresses'])
+        original_addresses = (
+            self.reader_servers_client.show_server(server_id)['server']
+            ['addresses'])
         # The server should be rebuilt using the provided image and data
         meta = {'rebuild': 'server'}
         new_name = data_utils.rand_name(
             prefix=CONF.resource_name_prefix,
             name=self.__class__.__name__ + '-server')
         password = 'rebuildPassw0rd'
-        rebuilt_server = self.client.rebuild_server(
+        rebuilt_server = self.servers_client.rebuild_server(
             server_id,
             self.image_ref_alt,
             name=new_name,
@@ -142,9 +143,10 @@
         self.assert_flavor_equal(self.flavor_ref, rebuilt_server['flavor'])
 
         # Verify the server properties after the rebuild completes
-        waiters.wait_for_server_status(self.client,
+        waiters.wait_for_server_status(self.servers_client,
                                        rebuilt_server['id'], 'ACTIVE')
-        server = self.client.show_server(rebuilt_server['id'])['server']
+        server = self.reader_servers_client.show_server(
+            rebuilt_server['id'])['server']
         rebuilt_image_id = server['image']['id']
         self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
         self.assertEqual(new_name, server['name'])
@@ -169,7 +171,7 @@
                 password,
                 validation_resources['keypair']['private_key'],
                 server=rebuilt_server,
-                servers_client=self.client)
+                servers_client=self.servers_client)
             linux_client.validate_authentication()
 
     def _test_resize_server_confirm(self, server_id, stop=False):
@@ -177,31 +179,31 @@
         # the provided flavor
 
         if stop:
-            self.client.stop_server(server_id)
-            waiters.wait_for_server_status(self.client, server_id,
+            self.servers_client.stop_server(server_id)
+            waiters.wait_for_server_status(self.servers_client, server_id,
                                            'SHUTOFF')
 
-        self.client.resize_server(server_id, self.flavor_ref_alt)
+        self.servers_client.resize_server(server_id, self.flavor_ref_alt)
         # NOTE(jlk): Explicitly delete the server to get a new one for later
         # tests. Avoids resize down race issues.
         self.addCleanup(self.delete_server, server_id)
-        waiters.wait_for_server_status(self.client, server_id,
+        waiters.wait_for_server_status(self.servers_client, server_id,
                                        'VERIFY_RESIZE')
 
-        self.client.confirm_resize_server(server_id)
+        self.servers_client.confirm_resize_server(server_id)
         expected_status = 'SHUTOFF' if stop else 'ACTIVE'
-        waiters.wait_for_server_status(self.client, server_id,
+        waiters.wait_for_server_status(self.servers_client, server_id,
                                        expected_status)
 
-        server = self.client.show_server(server_id)['server']
+        server = self.reader_servers_client.show_server(server_id)['server']
         self.assert_flavor_equal(self.flavor_ref_alt, server['flavor'])
 
         if stop:
             # NOTE(mriedem): tearDown requires the server to be started.
-            self.client.start_server(server_id)
+            self.servers_client.start_server(server_id)
 
     def _get_output(self, server_id):
-        output = self.client.get_console_output(
+        output = self.servers_client.get_console_output(
             server_id, length=3)['output']
         self.assertTrue(output, "Console output was empty.")
         lines = len(output.split('\n'))
@@ -234,18 +236,21 @@
         self.addCleanup(self.delete_server, newserver['id'])
         # The server's password should be set to the provided password
         new_password = 'Newpass1234'
-        self.client.change_password(newserver['id'], adminPass=new_password)
-        waiters.wait_for_server_status(self.client, newserver['id'], 'ACTIVE')
+        self.servers_client.change_password(newserver['id'],
+                                            adminPass=new_password)
+        waiters.wait_for_server_status(self.servers_client, newserver['id'],
+                                       'ACTIVE')
 
         if CONF.validation.run_validation:
             # Verify that the user can authenticate with the new password
-            server = self.client.show_server(newserver['id'])['server']
+            server = self.reader_servers_client.show_server(
+                newserver['id'])['server']
             linux_client = remote_client.RemoteClient(
                 self.get_server_ip(server, self.validation_resources),
                 self.ssh_user,
                 new_password,
                 server=server,
-                servers_client=self.client)
+                servers_client=self.servers_client)
             linux_client.validate_authentication()
 
     @decorators.attr(type='smoke')
@@ -279,13 +284,13 @@
         # ip attached at the beginning of the test_rebuild_server let's
         # make sure right here the floating ip is attached
         waiters.wait_for_server_floating_ip(
-            self.client,
+            self.servers_client,
             server,
             validation_resources['floating_ip'])
 
         self.addCleanup(waiters.wait_for_server_termination,
-                        self.client, server['id'])
-        self.addCleanup(self.client.delete_server, server['id'])
+                        self.servers_client, server['id'])
+        self.addCleanup(self.servers_client.delete_server, server['id'])
 
         self._test_rebuild_server(
             server_id=server['id'],
@@ -308,17 +313,19 @@
         values after a resize is reverted.
         """
 
-        self.client.resize_server(self.server_id, self.flavor_ref_alt)
+        self.servers_client.resize_server(self.server_id, self.flavor_ref_alt)
         # NOTE(zhufl): Explicitly delete the server to get a new one for later
         # tests. Avoids resize down race issues.
         self.addCleanup(self.delete_server, self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id,
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
                                        'VERIFY_RESIZE')
 
-        self.client.revert_resize_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+        self.servers_client.revert_resize_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'ACTIVE')
 
-        server = self.client.show_server(self.server_id)['server']
+        server = self.reader_servers_client.show_server(
+            self.server_id)['server']
         self.assert_flavor_equal(self.flavor_ref, server['flavor'])
 
     @decorators.idempotent_id('4b8867e6-fffa-4d54-b1d1-6fdda57be2f3')
@@ -344,29 +351,34 @@
                           'Pause is not available.')
     def test_pause_unpause_server(self):
         """Test pausing and unpausing server"""
-        self.client.pause_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id, 'PAUSED')
-        self.client.unpause_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+        self.servers_client.pause_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'PAUSED')
+        self.servers_client.unpause_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'ACTIVE')
 
     @decorators.idempotent_id('0d8ee21e-b749-462d-83da-b85b41c86c7f')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     def test_suspend_resume_server(self):
         """Test suspending and resuming server"""
-        self.client.suspend_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id,
+        self.servers_client.suspend_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
                                        'SUSPENDED')
-        self.client.resume_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+        self.servers_client.resume_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'ACTIVE')
 
     @decorators.idempotent_id('af8eafd4-38a7-4a4b-bdbc-75145a580560')
     def test_stop_start_server(self):
         """Test stopping and starting server"""
-        self.client.stop_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
-        self.client.start_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+        self.servers_client.stop_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'SHUTOFF')
+        self.servers_client.start_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'ACTIVE')
 
     @decorators.idempotent_id('80a8094c-211e-440a-ab88-9e59d556c7ee')
     def test_lock_unlock_server(self):
@@ -377,18 +389,21 @@
         Then unlock the server, now the server can be stopped and started.
         """
         # Lock the server,try server stop(exceptions throw),unlock it and retry
-        self.client.lock_server(self.server_id)
-        self.addCleanup(self.client.unlock_server, self.server_id)
-        server = self.client.show_server(self.server_id)['server']
+        self.servers_client.lock_server(self.server_id)
+        self.addCleanup(self.servers_client.unlock_server, self.server_id)
+        server = self.reader_servers_client.show_server(
+            self.server_id)['server']
         self.assertEqual(server['status'], 'ACTIVE')
         # Locked server is not allowed to be stopped by non-admin user
         self.assertRaises(lib_exc.Conflict,
-                          self.client.stop_server, self.server_id)
-        self.client.unlock_server(self.server_id)
-        self.client.stop_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
-        self.client.start_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+                          self.servers_client.stop_server, self.server_id)
+        self.servers_client.unlock_server(self.server_id)
+        self.servers_client.stop_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'SHUTOFF')
+        self.servers_client.start_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'ACTIVE')
 
 
 class ServerActionsTestOtherA(ServerActionsBase):
@@ -398,11 +413,11 @@
         server = self.create_test_server(wait_until='ACTIVE')
 
         # Remove all Security group
-        self.client.remove_security_group(
+        self.servers_client.remove_security_group(
             server['id'], name=server['security_groups'][0]['name'])
 
         # Verify all Security group
-        server = self.client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
         self.assertNotIn('security_groups', server)
 
     @decorators.idempotent_id('30449a88-5aff-4f9b-9866-6ee9b17f906d')
@@ -420,16 +435,17 @@
         server = servers[0]
 
         self.addCleanup(waiters.wait_for_server_termination,
-                        self.client, server['id'])
-        self.addCleanup(self.client.delete_server, server['id'])
-        server = self.client.show_server(server['id'])['server']
+                        self.servers_client, server['id'])
+        self.addCleanup(self.servers_client.delete_server, server['id'])
+        server = self.reader_servers_client.show_server(server['id'])['server']
         old_image = server['image']['id']
         new_image = (self.image_ref_alt
                      if old_image == self.image_ref else self.image_ref)
-        self.client.stop_server(server['id'])
-        waiters.wait_for_server_status(self.client, server['id'], 'SHUTOFF')
-        rebuilt_server = (self.client.rebuild_server(server['id'], new_image)
-                          ['server'])
+        self.servers_client.stop_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'SHUTOFF')
+        rebuilt_server = (self.servers_client.rebuild_server(
+            server['id'], new_image)['server'])
 
         # Verify the properties in the initial response are correct
         self.assertEqual(server['id'], rebuilt_server['id'])
@@ -438,9 +454,10 @@
         self.assert_flavor_equal(self.flavor_ref, rebuilt_server['flavor'])
 
         # Verify the server properties after the rebuild completes
-        waiters.wait_for_server_status(self.client,
+        waiters.wait_for_server_status(self.servers_client,
                                        rebuilt_server['id'], 'SHUTOFF')
-        server = self.client.show_server(rebuilt_server['id'])['server']
+        server = self.reader_servers_client.show_server(
+            rebuilt_server['id'])['server']
         rebuilt_image_id = server['image']['id']
         self.assertEqual(new_image, rebuilt_image_id)
 
@@ -468,10 +485,10 @@
             wait_until='SSHABLE')
         server = servers[0]
         self.addCleanup(waiters.wait_for_server_termination,
-                        self.client, server['id'])
-        self.addCleanup(self.client.delete_server, server['id'])
+                        self.servers_client, server['id'])
+        self.addCleanup(self.servers_client.delete_server, server['id'])
 
-        server = self.client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
         waiters.wait_for_volume_resource_status(self.volumes_client,
                                                 volume['id'], 'available')
         self.attach_volume(server, volume)
@@ -506,7 +523,7 @@
 
         # NOTE(mgoddard): Get detailed server to ensure addresses are present
         # in fixed IP case.
-        server = self.servers_client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
 
         self._test_resize_server_confirm(server['id'])
 
@@ -514,7 +531,7 @@
             # Now do something interactive with the guest like get its console
             # output; we don't actually care about the output,
             # just that it doesn't raise an error.
-            self.client.get_console_output(server['id'])
+            self.servers_client.get_console_output(server['id'])
         if CONF.validation.run_validation:
             linux_client = remote_client.RemoteClient(
                 self.get_server_ip(server, self.validation_resources),
@@ -522,7 +539,7 @@
                 password=None,
                 pkey=self.validation_resources['keypair']['private_key'],
                 server=server,
-                servers_client=self.client)
+                servers_client=self.servers_client)
             linux_client.validate_authentication()
 
 
@@ -550,21 +567,24 @@
 
         # Create a blank volume and attach it to the server created in setUp.
         volume = self.create_volume()
-        server = self.client.show_server(self.server_id)['server']
+        server = self.reader_servers_client.show_server(
+            self.server_id)['server']
         self.attach_volume(server, volume)
         # Now resize the server with the blank volume attached.
-        self.client.resize_server(self.server_id, self.flavor_ref_alt)
+        self.servers_client.resize_server(self.server_id, self.flavor_ref_alt)
         # Explicitly delete the server to get a new one for later
         # tests. Avoids resize down race issues.
         self.addCleanup(self.delete_server, self.server_id)
         waiters.wait_for_server_status(
-            self.client, self.server_id, 'VERIFY_RESIZE')
+            self.servers_client, self.server_id, 'VERIFY_RESIZE')
         # Now revert the resize which should move the instance and it's volume
         # attachment back to the original source compute host.
-        self.client.revert_resize_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+        self.servers_client.revert_resize_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'ACTIVE')
         # Make sure everything still looks OK.
-        server = self.client.show_server(self.server_id)['server']
+        server = self.reader_servers_client.show_server(
+            self.server_id)['server']
         self.assert_flavor_equal(self.flavor_ref, server['flavor'])
         attached_volumes = server['os-extended-volumes:volumes_attached']
         self.assertEqual(1, len(attached_volumes))
@@ -593,10 +613,10 @@
 
         backup1 = data_utils.rand_name(
             prefix=CONF.resource_name_prefix, name='backup-1')
-        resp = self.client.create_backup(self.server_id,
-                                         backup_type='daily',
-                                         rotation=2,
-                                         name=backup1)
+        resp = self.servers_client.create_backup(self.server_id,
+                                                 backup_type='daily',
+                                                 rotation=2,
+                                                 name=backup1)
         oldest_backup_exist = True
 
         # the oldest one should be deleted automatically in this test
@@ -630,11 +650,12 @@
 
         backup2 = data_utils.rand_name(
             prefix=CONF.resource_name_prefix, name='backup-2')
-        waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
-        resp = self.client.create_backup(self.server_id,
-                                         backup_type='daily',
-                                         rotation=2,
-                                         name=backup2)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'ACTIVE')
+        resp = self.servers_client.create_backup(self.server_id,
+                                                 backup_type='daily',
+                                                 rotation=2,
+                                                 name=backup2)
         if api_version_utils.compare_version_header_to_response(
                 "OpenStack-API-Version", "compute 2.45", resp.response, "lt"):
             image2_id = resp['image_id']
@@ -669,11 +690,12 @@
         # the first one will be deleted
         backup3 = data_utils.rand_name(
             prefix=CONF.resource_name_prefix, name='backup-3')
-        waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
-        resp = self.client.create_backup(self.server_id,
-                                         backup_type='daily',
-                                         rotation=2,
-                                         name=backup3)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'ACTIVE')
+        resp = self.servers_client.create_backup(self.server_id,
+                                                 backup_type='daily',
+                                                 rotation=2,
+                                                 name=backup3)
         if api_version_utils.compare_version_header_to_response(
                 "OpenStack-API-Version", "compute 2.45", resp.response, "lt"):
             image3_id = resp['image_id']
@@ -683,7 +705,8 @@
                                             image3_id, 'success')
         self.addCleanup(glance_client.delete_image, image3_id)
         # the first back up should be deleted
-        waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'ACTIVE')
         glance_client.wait_for_resource_deletion(image1_id)
         oldest_backup_exist = False
         image_list = glance_client.list_images(params)['images']
@@ -707,7 +730,8 @@
         server = self.create_test_server(wait_until='ACTIVE')
 
         def _check_full_length_console_log():
-            output = self.client.get_console_output(server['id'])['output']
+            output = self.servers_client.get_console_output(server['id'])[
+                'output']
             self.assertTrue(output, "Console output was empty.")
             lines = len(output.split('\n'))
 
@@ -735,8 +759,9 @@
         server = self.create_test_server(wait_until='ACTIVE')
         temp_server_id = server['id']
 
-        self.client.stop_server(temp_server_id)
-        waiters.wait_for_server_status(self.client, temp_server_id, 'SHUTOFF')
+        self.servers_client.stop_server(temp_server_id)
+        waiters.wait_for_server_status(self.servers_client, temp_server_id,
+                                       'SHUTOFF')
         self.wait_for(self._get_output, temp_server_id)
 
     @decorators.idempotent_id('77eba8e0-036e-4635-944b-f7a8f3b78dc9')
@@ -750,19 +775,20 @@
         else:
             raise lib_exc.InvalidConfiguration(
                 'api_v2 must be True in [image-feature-enabled].')
-        compute.shelve_server(self.client, self.server_id,
+        compute.shelve_server(self.servers_client, self.server_id,
                               force_shelve_offload=True)
 
-        server = self.client.show_server(self.server_id)['server']
+        server = self.reader_servers_client.show_server(
+            self.server_id)['server']
         image_name = server['name'] + '-shelved'
         params = {'name': image_name}
         images = glance_client.list_images(params)['images']
         self.assertEqual(1, len(images))
         self.assertEqual(image_name, images[0]['name'])
 
-        body = self.client.unshelve_server(self.server_id)
+        body = self.servers_client.unshelve_server(self.server_id)
         waiters.wait_for_server_status(
-            self.client,
+            self.servers_client,
             self.server_id,
             "ACTIVE",
             request_id=body.response["x-openstack-request-id"],
@@ -778,10 +804,11 @@
     def test_shelve_paused_server(self):
         """Test shelving a paused server"""
         server = self.create_test_server(wait_until='ACTIVE')
-        self.client.pause_server(server['id'])
-        waiters.wait_for_server_status(self.client, server['id'], 'PAUSED')
+        self.servers_client.pause_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'PAUSED')
         # Check if Shelve operation is successful on paused server.
-        compute.shelve_server(self.client, server['id'],
+        compute.shelve_server(self.servers_client, server['id'],
                               force_shelve_offload=True)
 
     @decorators.idempotent_id('c6bc11bf-592e-4015-9319-1c98dc64daf5')
@@ -793,10 +820,10 @@
         The returned vnc console url should be in valid format.
         """
         if self.is_requested_microversion_compatible('2.5'):
-            body = self.client.get_vnc_console(
+            body = self.servers_client.get_vnc_console(
                 self.server_id, type='novnc')['console']
         else:
-            body = self.client.get_remote_console(
+            body = self.servers_client.get_remote_console(
                 self.server_id, console_type='novnc',
                 protocol='vnc')['remote_console']
         self.assertEqual('novnc', body['type'])
@@ -853,6 +880,10 @@
         super(ServerActionsV293TestJSON, cls).setup_credentials()
 
     @classmethod
+    def setup_clients(cls):
+        super(ServerActionsV293TestJSON, cls).setup_clients()
+
+    @classmethod
     def resource_setup(cls):
         super(ServerActionsV293TestJSON, cls).resource_setup()
         cls.server_id = cls.recreate_server(None, volume_backed=True,
@@ -863,7 +894,8 @@
         """Test rebuilding a volume backed server"""
         self.validation_resources = self.get_class_validation_resources(
             self.os_primary)
-        server = self.servers_client.show_server(self.server_id)['server']
+        server = self.reader_servers_client.show_server(
+            self.server_id)['server']
         volume_id = server['os-extended-volumes:volumes_attached'][0]['id']
         volume_before_rebuild = self.volumes_client.show_volume(volume_id)
         image_before_rebuild = (
@@ -912,7 +944,7 @@
         # Verify the server properties after the rebuild completes
         waiters.wait_for_server_status(self.servers_client,
                                        rebuilt_server['id'], 'ACTIVE')
-        server = self.servers_client.show_server(
+        server = self.reader_servers_client.show_server(
             rebuilt_server['id'])['server']
         volume_id = server['os-extended-volumes:volumes_attached'][0]['id']
         volume_after_rebuild = self.volumes_client.show_volume(volume_id)
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index 978a9da..429ffff 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -14,9 +14,13 @@
 #    under the License.
 
 from tempest.api.compute import base
+from tempest import config
 from tempest.lib import decorators
 
 
+CONF = config.CONF
+
+
 class ServerAddressesTestJSON(base.BaseV2ComputeTest):
     """Test server addresses"""
     create_default_network = True
@@ -24,7 +28,6 @@
     @classmethod
     def setup_clients(cls):
         super(ServerAddressesTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @classmethod
     def resource_setup(cls):
@@ -40,7 +43,8 @@
         All public and private addresses for a server should be returned.
         """
 
-        addresses = self.client.list_addresses(self.server['id'])['addresses']
+        addresses = self.reader_servers_client.list_addresses(
+            self.server['id'])['addresses']
 
         # We do not know the exact network configuration, but an instance
         # should at least have a single public or private address
@@ -57,14 +61,16 @@
         the specified one.
         """
 
-        addresses = self.client.list_addresses(self.server['id'])['addresses']
+        addresses = self.reader_servers_client.list_addresses(
+            self.server['id'])['addresses']
 
         # Once again we don't know the environment's exact network config,
         # but the response for each individual network should be the same
         # as the partial result of the full address list
         id = self.server['id']
         for addr_type in addresses:
-            addr = self.client.list_addresses_by_network(id, addr_type)
+            addr = self.reader_servers_client.list_addresses_by_network(
+                id, addr_type)
 
             addr = addr[addr_type]
             for address in addresses[addr_type]:
diff --git a/tempest/api/compute/servers/test_server_addresses_negative.py b/tempest/api/compute/servers/test_server_addresses_negative.py
index bb21594..8688cd7 100644
--- a/tempest/api/compute/servers/test_server_addresses_negative.py
+++ b/tempest/api/compute/servers/test_server_addresses_negative.py
@@ -25,7 +25,6 @@
     @classmethod
     def setup_clients(cls):
         super(ServerAddressesNegativeTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @classmethod
     def resource_setup(cls):
@@ -36,13 +35,13 @@
     @decorators.idempotent_id('02c3f645-2d2e-4417-8525-68c0407d001b')
     def test_list_server_addresses_invalid_server_id(self):
         """List addresses request should fail if server id not in system"""
-        self.assertRaises(lib_exc.NotFound, self.client.list_addresses,
-                          '999')
+        self.assertRaises(lib_exc.NotFound,
+                          self.reader_servers_client.list_addresses, '999')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a2ab5144-78c0-4942-a0ed-cc8edccfd9ba')
     def test_list_server_addresses_by_network_neg(self):
         """List addresses by network should fail if network name not valid"""
         self.assertRaises(lib_exc.NotFound,
-                          self.client.list_addresses_by_network,
+                          self.reader_servers_client.list_addresses_by_network,
                           self.server['id'], 'invalid')
diff --git a/tempest/api/compute/servers/test_server_group.py b/tempest/api/compute/servers/test_server_group.py
index f92b5ba..c4408ed 100644
--- a/tempest/api/compute/servers/test_server_group.py
+++ b/tempest/api/compute/servers/test_server_group.py
@@ -37,6 +37,10 @@
     def setup_clients(cls):
         super(ServerGroupTestJSON, cls).setup_clients()
         cls.client = cls.server_groups_client
+        if CONF.enforce_scope.nova:
+            cls.reader_sg_client = cls.os_project_reader.server_groups_client
+        else:
+            cls.reader_sg_client = cls.client
 
     @classmethod
     def _set_policy(cls, policy):
@@ -78,7 +82,8 @@
         # delete the test server-group
         self.client.delete_server_group(server_group['id'])
         # validation of server-group deletion
-        server_group_list = self.client.list_server_groups()['server_groups']
+        server_group_list = self.reader_sg_client.list_server_groups()[
+            'server_groups']
         self.assertNotIn(server_group, server_group_list)
 
     def _create_delete_server_group(self, policy):
@@ -118,14 +123,14 @@
     @decorators.idempotent_id('b3545034-dd78-48f0-bdc2-a4adfa6d0ead')
     def test_show_server_group(self):
         """Test getting the server-group detail"""
-        body = self.client.show_server_group(
+        body = self.reader_sg_client.show_server_group(
             self.created_server_group['id'])['server_group']
         self.assertEqual(self.created_server_group, body)
 
     @decorators.idempotent_id('d4874179-27b4-4d7d-80e4-6c560cdfe321')
     def test_list_server_groups(self):
         """Test listing the server-groups"""
-        body = self.client.list_server_groups()['server_groups']
+        body = self.reader_sg_client.list_server_groups()['server_groups']
         self.assertIn(self.created_server_group, body)
 
     @decorators.idempotent_id('ed20d3fb-9d1f-4329-b160-543fbd5d9811')
@@ -140,7 +145,7 @@
         self.addCleanup(self.delete_server, server['id'])
 
         # Check a server is in the group
-        server_group = (self.server_groups_client.show_server_group(
+        server_group = (self.reader_sg_client.show_server_group(
             self.created_server_group['id'])['server_group'])
         self.assertIn(server['id'], server_group['members'])
 
@@ -154,6 +159,14 @@
     create_default_network = True
     min_microversion = '2.64'
 
+    @classmethod
+    def setup_clients(cls):
+        super(ServerGroup264TestJSON, cls).setup_clients()
+        if CONF.enforce_scope.nova:
+            cls.reader_client = cls.os_project_reader.server_groups_client
+        else:
+            cls.reader_client = cls.server_groups_client
+
     @decorators.idempotent_id('b52f09dd-2133-4037-9a5d-bdb260096a88')
     def test_create_get_server_group(self):
         # create, get the test server-group with given policy
@@ -162,5 +175,5 @@
         self.addCleanup(
             self.server_groups_client.delete_server_group,
             server_group['id'])
-        self.server_groups_client.list_server_groups()
-        self.server_groups_client.show_server_group(server_group['id'])
+        self.reader_client.list_server_groups()
+        self.reader_client.show_server_group(server_group['id'])
diff --git a/tempest/api/compute/servers/test_server_metadata.py b/tempest/api/compute/servers/test_server_metadata.py
index 5f35b15..3e82202 100644
--- a/tempest/api/compute/servers/test_server_metadata.py
+++ b/tempest/api/compute/servers/test_server_metadata.py
@@ -29,7 +29,6 @@
     @classmethod
     def setup_clients(cls):
         super(ServerMetadataTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @classmethod
     def resource_setup(cls):
@@ -39,7 +38,7 @@
     def setUp(self):
         super(ServerMetadataTestJSON, self).setUp()
         meta = {'key1': 'value1', 'key2': 'value2'}
-        self.client.set_server_metadata(self.server['id'], meta)
+        self.servers_client.set_server_metadata(self.server['id'], meta)
 
     @decorators.idempotent_id('479da087-92b3-4dcf-aeb3-fd293b2d14ce')
     def test_list_server_metadata(self):
@@ -47,8 +46,9 @@
 
         All metadata key/value pairs for a server should be returned.
         """
-        resp_metadata = (self.client.list_server_metadata(self.server['id'])
-                         ['metadata'])
+        resp_metadata = (
+            self.reader_servers_client.list_server_metadata(self.server['id'])
+            ['metadata'])
 
         # Verify the expected metadata items are in the list
         expected = {'key1': 'value1', 'key2': 'value2'}
@@ -62,12 +62,14 @@
         """
         # Create a new set of metadata for the server
         req_metadata = {'meta2': 'data2', 'meta3': 'data3'}
-        self.client.set_server_metadata(self.server['id'], req_metadata)
+        self.servers_client.set_server_metadata(self.server['id'],
+                                                req_metadata)
 
         # Verify the expected values are correct, and that the
         # previous values have been removed
-        resp_metadata = (self.client.list_server_metadata(self.server['id'])
-                         ['metadata'])
+        resp_metadata = (
+            self.reader_servers_client.list_server_metadata(self.server['id'])
+            ['metadata'])
         self.assertEqual(resp_metadata, req_metadata)
 
     @decorators.idempotent_id('344d981e-0c33-4997-8a5d-6c1d803e4134')
@@ -77,11 +79,12 @@
         The server's metadata values should be updated to the provided values.
         """
         meta = {'key1': 'alt1', 'key3': 'value3'}
-        self.client.update_server_metadata(self.server['id'], meta)
+        self.servers_client.update_server_metadata(self.server['id'], meta)
 
         # Verify the values have been updated to the proper values
-        resp_metadata = (self.client.list_server_metadata(self.server['id'])
-                         ['metadata'])
+        resp_metadata = (
+            self.reader_servers_client.list_server_metadata(self.server['id'])
+            ['metadata'])
         expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
         self.assertEqual(expected, resp_metadata)
 
@@ -93,17 +96,18 @@
         body is passed.
         """
         meta = {}
-        self.client.update_server_metadata(self.server['id'], meta)
-        resp_metadata = (self.client.list_server_metadata(self.server['id'])
-                         ['metadata'])
+        self.servers_client.update_server_metadata(self.server['id'], meta)
+        resp_metadata = (
+            self.reader_servers_client.list_server_metadata(self.server['id'])
+            ['metadata'])
         expected = {'key1': 'value1', 'key2': 'value2'}
         self.assertEqual(expected, resp_metadata)
 
     @decorators.idempotent_id('3043c57d-7e0e-49a6-9a96-ad569c265e6a')
     def test_get_server_metadata_item(self):
         """Test getting specific server metadata item"""
-        meta = self.client.show_server_metadata_item(self.server['id'],
-                                                     'key2')['meta']
+        meta = self.reader_servers_client.show_server_metadata_item(
+            self.server['id'], 'key2')['meta']
         self.assertEqual('value2', meta['key2'])
 
     @decorators.idempotent_id('58c02d4f-5c67-40be-8744-d3fa5982eb1c')
@@ -115,11 +119,13 @@
 
         # Update the metadata value.
         meta = {'nova': 'alt'}
-        self.client.set_server_metadata_item(self.server['id'], 'nova', meta)
+        self.servers_client.set_server_metadata_item(self.server['id'],
+                                                     'nova', meta)
 
         # Verify the meta item's value has been updated
-        resp_metadata = (self.client.list_server_metadata(self.server['id'])
-                         ['metadata'])
+        resp_metadata = (
+            self.reader_servers_client.list_server_metadata(self.server['id'])
+            ['metadata'])
         expected = {'key1': 'value1', 'key2': 'value2', 'nova': 'alt'}
         self.assertEqual(expected, resp_metadata)
 
@@ -129,10 +135,12 @@
 
         The metadata value/key pair should be deleted from the server.
         """
-        self.client.delete_server_metadata_item(self.server['id'], 'key1')
+        self.servers_client.delete_server_metadata_item(self.server['id'],
+                                                        'key1')
 
         # Verify the metadata item has been removed
-        resp_metadata = (self.client.list_server_metadata(self.server['id'])
-                         ['metadata'])
+        resp_metadata = (
+            self.reader_servers_client.list_server_metadata(self.server['id'])
+            ['metadata'])
         expected = {'key2': 'value2'}
         self.assertEqual(expected, resp_metadata)
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index 2059dfa..5ba83ad 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -27,12 +27,11 @@
     @classmethod
     def setup_clients(cls):
         super(ServerMetadataNegativeTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @classmethod
     def resource_setup(cls):
         super(ServerMetadataNegativeTestJSON, cls).resource_setup()
-        cls.tenant_id = cls.client.tenant_id
+        cls.tenant_id = cls.servers_client.tenant_id
         cls.server = cls.create_test_server(metadata={}, wait_until='ACTIVE')
 
     @decorators.attr(type=['negative'])
@@ -68,7 +67,7 @@
         # GET on a non-existent server should not succeed
         non_existent_server_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.show_server_metadata_item,
+                          self.reader_servers_client.show_server_metadata_item,
                           non_existent_server_id,
                           'test2')
 
@@ -78,7 +77,7 @@
         """Test listing metadata for a non existent server should fail"""
         non_existent_server_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.list_server_metadata,
+                          self.reader_servers_client.list_server_metadata,
                           non_existent_server_id)
 
     @decorators.attr(type=['negative'])
@@ -90,7 +89,7 @@
         """
         meta = {'testkey': 'testvalue'}
         self.assertRaises(lib_exc.BadRequest,
-                          self.client.set_server_metadata_item,
+                          self.servers_client.set_server_metadata_item,
                           self.server['id'], 'key', meta)
 
     @decorators.attr(type=['negative'])
@@ -100,7 +99,7 @@
         non_existent_server_id = data_utils.rand_uuid()
         meta = {'meta1': 'data1'}
         self.assertRaises(lib_exc.NotFound,
-                          self.client.set_server_metadata,
+                          self.servers_client.set_server_metadata,
                           non_existent_server_id,
                           meta)
 
@@ -111,7 +110,7 @@
         non_existent_server_id = data_utils.rand_uuid()
         meta = {'key1': 'value1', 'key2': 'value2'}
         self.assertRaises(lib_exc.NotFound,
-                          self.client.update_server_metadata,
+                          self.servers_client.update_server_metadata,
                           non_existent_server_id,
                           meta)
 
@@ -121,7 +120,7 @@
         """Test updating server metadata to blank key should fail"""
         meta = {'': 'data1'}
         self.assertRaises(lib_exc.BadRequest,
-                          self.client.update_server_metadata,
+                          self.servers_client.update_server_metadata,
                           self.server['id'], meta=meta)
 
     @decorators.attr(type=['negative'])
@@ -133,7 +132,7 @@
         """
         non_existent_server_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.delete_server_metadata_item,
+                          self.servers_client.delete_server_metadata_item,
                           non_existent_server_id,
                           'd')
 
@@ -155,14 +154,14 @@
         for num in range(1, quota_metadata + 2):
             req_metadata['key' + str(num)] = 'val' + str(num)
         self.assertRaises((lib_exc.OverLimit, lib_exc.Forbidden),
-                          self.client.set_server_metadata,
+                          self.servers_client.set_server_metadata,
                           self.server['id'], req_metadata)
 
         # A 403 Forbidden or 413 Overlimit (old behaviour) exception
         # will be raised while exceeding metadata items limit for
         # tenant.
         self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
-                          self.client.update_server_metadata,
+                          self.servers_client.update_server_metadata,
                           self.server['id'], req_metadata)
 
     @decorators.attr(type=['negative'])
@@ -171,7 +170,7 @@
         """Test setting server metadata with blank key should fail"""
         meta = {'': 'data1'}
         self.assertRaises(lib_exc.BadRequest,
-                          self.client.set_server_metadata,
+                          self.servers_client.set_server_metadata,
                           self.server['id'], meta=meta)
 
     @decorators.attr(type=['negative'])
@@ -180,5 +179,5 @@
         """Test setting server metadata without metadata field should fail"""
         meta = {'meta1': 'data1'}
         self.assertRaises(lib_exc.BadRequest,
-                          self.client.set_server_metadata,
+                          self.servers_client.set_server_metadata,
                           self.server['id'], meta=meta, no_metadata_field=True)
diff --git a/tempest/api/compute/servers/test_server_password.py b/tempest/api/compute/servers/test_server_password.py
index f61d4fd..205b0ec 100644
--- a/tempest/api/compute/servers/test_server_password.py
+++ b/tempest/api/compute/servers/test_server_password.py
@@ -15,15 +15,23 @@
 
 
 from tempest.api.compute import base
+from tempest import config
 from tempest.lib import decorators
 
 
+CONF = config.CONF
+
+
 class ServerPasswordTestJSON(base.BaseV2ComputeTest):
     """Test server password"""
 
     create_default_network = True
 
     @classmethod
+    def setup_clients(cls):
+        super(ServerPasswordTestJSON, cls).setup_clients()
+
+    @classmethod
     def resource_setup(cls):
         super(ServerPasswordTestJSON, cls).resource_setup()
         cls.server = cls.create_test_server(wait_until="ACTIVE")
@@ -31,7 +39,7 @@
     @decorators.idempotent_id('f83b582f-62a8-4f22-85b0-0dee50ff783a')
     def test_get_server_password(self):
         """Test getting password of a server"""
-        self.servers_client.show_password(self.server['id'])
+        self.reader_servers_client.show_password(self.server['id'])
 
     @decorators.idempotent_id('f8229e8b-b625-4493-800a-bde86ac611ea')
     def test_delete_server_password(self):
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index 8a05e7a..a4b2ad3 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -45,7 +45,10 @@
     @classmethod
     def setup_clients(cls):
         super(ServerPersonalityTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
+        if CONF.enforce_scope.nova:
+            cls.reader_limits_client = cls.os_project_reader.limits_client
+        else:
+            cls.reader_limits_client = cls.limits_client
 
     # NOTE(mriedem): Marked as slow because personality (file injection) is
     # deprecated in nova so we don't care as much about running this all the
@@ -70,14 +73,15 @@
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.servers_client.delete_server,
                         created_server['id'])
-        server = self.client.show_server(created_server['id'])['server']
+        server = self.reader_servers_client.show_server(
+            created_server['id'])['server']
         if CONF.validation.run_validation:
             linux_client = remote_client.RemoteClient(
                 self.get_server_ip(server, validation_resources),
                 self.ssh_user, password,
                 validation_resources['keypair']['private_key'],
                 server=server,
-                servers_client=self.client)
+                servers_client=self.servers_client)
             self.assertEqual(file_contents,
                              linux_client.exec_command(
                                  'sudo cat %s' % file_path))
@@ -102,10 +106,10 @@
         file_contents = 'Test server rebuild.'
         personality = [{'path': 'rebuild.txt',
                         'contents': base64.encode_as_text(file_contents)}]
-        rebuilt_server = self.client.rebuild_server(server_id,
-                                                    self.image_ref_alt,
-                                                    personality=personality)
-        waiters.wait_for_server_status(self.client, server_id, 'ACTIVE')
+        rebuilt_server = self.servers_client.rebuild_server(
+            server_id, self.image_ref_alt, personality=personality)
+        waiters.wait_for_server_status(self.servers_client, server_id,
+                                       'ACTIVE')
         self.assertEqual(self.image_ref_alt,
                          rebuilt_server['server']['image']['id'])
 
@@ -118,7 +122,7 @@
         """
         file_contents = 'This is a test file.'
         personality = []
-        limits = self.limits_client.show_limits()['limits']
+        limits = self.reader_limits_client.show_limits()['limits']
         max_file_limit = limits['absolute']['maxPersonality']
         if max_file_limit == -1:
             raise self.skipException("No limit for personality files")
@@ -144,7 +148,7 @@
         files is injected into the server during creation.
         """
         file_contents = 'This is a test file.'
-        limits = self.limits_client.show_limits()['limits']
+        limits = self.reader_limits_client.show_limits()['limits']
         max_file_limit = limits['absolute']['maxPersonality']
         if max_file_limit == -1:
             raise self.skipException("No limit for personality files")
@@ -168,14 +172,15 @@
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.servers_client.delete_server,
                         created_server['id'])
-        server = self.client.show_server(created_server['id'])['server']
+        server = self.reader_servers_client.show_server(
+            created_server['id'])['server']
         if CONF.validation.run_validation:
             linux_client = remote_client.RemoteClient(
                 self.get_server_ip(server, validation_resources),
                 self.ssh_user, password,
                 validation_resources['keypair']['private_key'],
                 server=server,
-                servers_client=self.client)
+                servers_client=self.servers_client)
             for i in person:
                 self.assertEqual(base64.decode_as_text(i['contents']),
                                  linux_client.exec_command(
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 9f96385..d9ecadc 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -245,7 +245,8 @@
         server, rescue_image_id = self._create_server_and_rescue_image(
             hw_rescue_device='disk', hw_rescue_bus='virtio', validatable=True,
             validation_resources=validation_resources, wait_until="SSHABLE")
-        server = self.servers_client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(
+            server['id'])['server']
         waiters.wait_for_volume_resource_status(self.volumes_client,
                                                 volume['id'], 'available')
         self.attach_volume(server, volume)
diff --git a/tempest/api/compute/servers/test_server_tags.py b/tempest/api/compute/servers/test_server_tags.py
index 0b5870a..5eb5ea5 100644
--- a/tempest/api/compute/servers/test_server_tags.py
+++ b/tempest/api/compute/servers/test_server_tags.py
@@ -32,7 +32,6 @@
     @classmethod
     def setup_clients(cls):
         super(ServerTagsTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @classmethod
     def resource_setup(cls):
@@ -43,14 +42,15 @@
         if not isinstance(tags, (list, tuple)):
             tags = [tags]
         for tag in tags:
-            self.client.update_tag(server_id, tag)
-        self.addCleanup(self.client.delete_all_tags, server_id)
+            self.servers_client.update_tag(server_id, tag)
+        self.addCleanup(self.servers_client.delete_all_tags, server_id)
 
     @decorators.idempotent_id('8d95abe2-c658-4c42-9a44-c0258500306b')
     def test_create_delete_tag(self):
         """Test creating and deleting server tag"""
         # Check that no tags exist.
-        fetched_tags = self.client.list_tags(self.server['id'])['tags']
+        fetched_tags = self.reader_servers_client.list_tags(
+            self.server['id'])['tags']
         self.assertEmpty(fetched_tags)
 
         # Add server tag to the server.
@@ -59,12 +59,14 @@
         self._update_server_tags(self.server['id'], assigned_tag)
 
         # Check that added tag exists.
-        fetched_tags = self.client.list_tags(self.server['id'])['tags']
+        fetched_tags = self.reader_servers_client.list_tags(
+            self.server['id'])['tags']
         self.assertEqual([assigned_tag], fetched_tags)
 
         # Remove assigned tag from server and check that it was removed.
-        self.client.delete_tag(self.server['id'], assigned_tag)
-        fetched_tags = self.client.list_tags(self.server['id'])['tags']
+        self.servers_client.delete_tag(self.server['id'], assigned_tag)
+        fetched_tags = self.reader_servers_client.list_tags(
+            self.server['id'])['tags']
         self.assertEmpty(fetched_tags)
 
     @decorators.idempotent_id('a2c1af8c-127d-417d-974b-8115f7e3d831')
@@ -81,12 +83,13 @@
         # Replace tags with new tags and check that they are present.
         new_tags = [data_utils.rand_name(**kwargs),
                     data_utils.rand_name(**kwargs)]
-        replaced_tags = self.client.update_all_tags(
+        replaced_tags = self.servers_client.update_all_tags(
             self.server['id'], new_tags)['tags']
         self.assertCountEqual(new_tags, replaced_tags)
 
         # List the tags and check that the tags were replaced.
-        fetched_tags = self.client.list_tags(self.server['id'])['tags']
+        fetched_tags = self.reader_servers_client.list_tags(
+            self.server['id'])['tags']
         self.assertCountEqual(new_tags, fetched_tags)
 
     @decorators.idempotent_id('a63b2a74-e918-4b7c-bcab-10c855f3a57e')
@@ -102,8 +105,9 @@
         self._update_server_tags(self.server['id'], assigned_tags)
 
         # Delete tags from the server and check that they were deleted.
-        self.client.delete_all_tags(self.server['id'])
-        fetched_tags = self.client.list_tags(self.server['id'])['tags']
+        self.servers_client.delete_all_tags(self.server['id'])
+        fetched_tags = self.reader_servers_client.list_tags(
+            self.server['id'])['tags']
         self.assertEmpty(fetched_tags)
 
     @decorators.idempotent_id('81279a66-61c3-4759-b830-a2dbe64cbe08')
@@ -116,4 +120,5 @@
 
         # Check that added tag exists. Throws a 404 if not found, else a 204,
         # which was already checked by the schema validation.
-        self.client.check_tag_existence(self.server['id'], assigned_tag)
+        self.servers_client.check_tag_existence(self.server['id'],
+                                                assigned_tag)
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index ea3a710..b529b6b 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -28,16 +28,9 @@
     """Test servers API"""
     create_default_network = True
 
-    credentials = ['primary', 'project_reader']
-
     @classmethod
     def setup_clients(cls):
         super(ServersTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
-        if CONF.enforce_scope.nova:
-            cls.reader_client = cls.os_project_reader.servers_client
-        else:
-            cls.reader_client = cls.client
 
     @decorators.idempotent_id('b92d5ec7-b1dd-44a2-87e4-45e888c46ef0')
     @testtools.skipUnless(CONF.compute_feature_enabled.
@@ -71,9 +64,9 @@
         id2 = server['id']
         self.addCleanup(self.delete_server, id2)
         self.assertNotEqual(id1, id2, "Did not create a new server")
-        server = self.reader_client.show_server(id1)['server']
+        server = self.reader_servers_client.show_server(id1)['server']
         name1 = server['name']
-        server = self.reader_client.show_server(id2)['server']
+        server = self.reader_servers_client.show_server(id2)['server']
         name2 = server['name']
         self.assertEqual(name1, name2)
 
@@ -88,7 +81,7 @@
         server = self.create_test_server(key_name=key_name,
                                          wait_until='ACTIVE')
         self.addCleanup(self.delete_server, server['id'])
-        server = self.reader_client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
         self.assertEqual(key_name, server['key_name'])
 
     def _update_server_name(self, server_id, status, prefix_name='server'):
@@ -97,12 +90,12 @@
             prefix=CONF.resource_name_prefix, name=prefix_name)
 
         # Update the server with a new name
-        self.client.update_server(server_id,
-                                  name=new_name)
-        waiters.wait_for_server_status(self.client, server_id, status)
+        self.servers_client.update_server(server_id,
+                                          name=new_name)
+        waiters.wait_for_server_status(self.servers_client, server_id, status)
 
         # Verify the name of the server has changed
-        server = self.reader_client.show_server(server_id)['server']
+        server = self.reader_servers_client.show_server(server_id)['server']
         self.assertEqual(new_name, server['name'])
         return server
 
@@ -116,8 +109,9 @@
         self._update_server_name(server['id'], 'ACTIVE', prefix_name)
 
         # stop server and check server name update again
-        self.client.stop_server(server['id'])
-        waiters.wait_for_server_status(self.client, server['id'], 'SHUTOFF')
+        self.servers_client.stop_server(server['id'])
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'SHUTOFF')
         # Update instance name with non-ASCII characters
         updated_server = self._update_server_name(server['id'],
                                                   'SHUTOFF',
@@ -131,13 +125,14 @@
         self.addCleanup(self.delete_server, server['id'])
 
         # Update the IPv4 and IPv6 access addresses
-        self.client.update_server(server['id'],
-                                  accessIPv4='1.1.1.1',
-                                  accessIPv6='::babe:202:202')
-        waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
+        self.servers_client.update_server(server['id'],
+                                          accessIPv4='1.1.1.1',
+                                          accessIPv6='::babe:202:202')
+        waiters.wait_for_server_status(self.servers_client, server['id'],
+                                       'ACTIVE')
 
         # Verify the access addresses have been updated
-        server = self.reader_client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
         self.assertEqual('1.1.1.1', server['accessIPv4'])
         self.assertEqual('::babe:202:202', server['accessIPv6'])
 
@@ -147,7 +142,7 @@
         server = self.create_test_server(accessIPv6='2001:2001::3',
                                          wait_until='ACTIVE')
         self.addCleanup(self.delete_server, server['id'])
-        server = self.reader_client.show_server(server['id'])['server']
+        server = self.reader_servers_client.show_server(server['id'])['server']
         self.assertEqual('2001:2001::3', server['accessIPv6'])
 
     @decorators.related_bug('1730756')
@@ -180,22 +175,16 @@
     # also. 2.47 APIs schema are on top of 2.9->2.19->2.26 schema so
     # below tests cover all of the schema.
 
-    credentials = ['primary', 'project_reader']
-
     @classmethod
     def setup_clients(cls):
         super(ServerShowV247Test, cls).setup_clients()
-        if CONF.enforce_scope.nova:
-            cls.reader_client = cls.os_project_reader.servers_client
-        else:
-            cls.reader_client = cls.servers_client
 
     @decorators.idempotent_id('88b0bdb2-494c-11e7-a919-92ebcb67fe33')
     def test_show_server(self):
         """Test getting server detail"""
         server = self.create_test_server()
         # All fields will be checked by API schema
-        self.reader_client.show_server(server['id'])
+        self.reader_servers_client.show_server(server['id'])
 
     @decorators.idempotent_id('8de397c2-57d0-4b90-aa30-e5d668f21a8b')
     def test_update_rebuild_list_server(self):
@@ -210,7 +199,7 @@
         waiters.wait_for_server_status(self.servers_client,
                                        server['id'], 'ACTIVE')
         # Checking list details API response schema
-        self.servers_client.list_servers(detail=True)
+        self.reader_servers_client.list_servers(detail=True)
 
 
 class ServerShowV263Test(base.BaseV2ComputeTest):
@@ -219,15 +208,9 @@
     min_microversion = '2.63'
     max_microversion = 'latest'
 
-    credentials = ['primary', 'project_reader']
-
     @classmethod
     def setup_clients(cls):
         super(ServerShowV263Test, cls).setup_clients()
-        if CONF.enforce_scope.nova:
-            cls.reader_client = cls.os_project_reader.servers_client
-        else:
-            cls.reader_client = cls.servers_client
 
     @testtools.skipUnless(CONF.compute.certified_image_ref,
                           '``[compute]/certified_image_ref`` required to test '
@@ -245,7 +228,7 @@
             wait_until='ACTIVE')
 
         # Check show API response schema
-        self.reader_client.show_server(server['id'])['server']
+        self.reader_servers_client.show_server(server['id'])['server']
 
         # Check update API response schema
         self.servers_client.update_server(server['id'])
@@ -260,7 +243,7 @@
 
         # Check list details API response schema
         params = {'trusted_image_certificates': trusted_certs}
-        servers = self.servers_client.list_servers(
+        servers = self.reader_servers_client.list_servers(
             detail=True, **params)['servers']
         self.assertNotEmpty(servers)
 
@@ -275,13 +258,17 @@
     min_microversion = '2.96'
     max_microversion = 'latest'
 
+    @classmethod
+    def setup_clients(cls):
+        super(ServersListShow296Test, cls).setup_clients()
+
     @decorators.idempotent_id('4eee1ffe-9e00-4c99-a431-0d3e0f323a8f')
     def test_list_show_update_rebuild_server_296(self):
         server = self.create_test_server(wait_until='ACTIVE')
         # Checking list API response schema.
-        self.servers_client.list_servers(detail=True)
+        self.reader_servers_client.list_servers(detail=True)
         # Checking show API response schema
-        self.servers_client.show_server(server['id'])
+        self.reader_servers_client.show_server(server['id'])
         # Checking update API response schema
         self.servers_client.update_server(server['id'])
         # Check rebuild API response schema
@@ -296,13 +283,17 @@
     min_microversion = '2.98'
     max_microversion = 'latest'
 
+    @classmethod
+    def setup_clients(cls):
+        super(ServersListShow298Test, cls).setup_clients()
+
     @decorators.idempotent_id('3981e496-3bf7-4015-b807-63ffee7c520c')
     def test_list_show_update_rebuild_server_298(self):
         server = self.create_test_server(wait_until='ACTIVE')
         # Check list details API response schema
-        self.servers_client.list_servers(detail=True)
+        self.reader_servers_client.list_servers(detail=True)
         # Check show API response schema
-        self.servers_client.show_server(server['id'])
+        self.reader_servers_client.show_server(server['id'])
         # Checking update API response schema
         self.servers_client.update_server(server['id'])
         # Check rebuild API response schema
@@ -321,13 +312,17 @@
     min_microversion = '2.100'
     max_microversion = 'latest'
 
+    @classmethod
+    def setup_clients(cls):
+        super(ServersListShow2100Test, cls).setup_clients()
+
     @decorators.idempotent_id('2c3a8270-e6f7-4400-af0f-db003c117e48')
     def test_list_show_rebuild_update_server_2100(self):
         server = self.create_test_server(wait_until='ACTIVE')
         # Checking list API response schema.
-        self.servers_client.list_servers(detail=True)
+        self.reader_servers_client.list_servers(detail=True)
         # Checking show API response schema
-        self.servers_client.show_server(server['id'])
+        self.reader_servers_client.show_server(server['id'])
         # Checking update API response schema
         self.servers_client.update_server(server['id'])
         waiters.wait_for_server_status(self.servers_client,
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index fa40629..582819a 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -37,7 +37,7 @@
     def setUp(self):
         super(ServersNegativeTestJSON, self).setUp()
         try:
-            waiters.wait_for_server_status(self.client, self.server_id,
+            waiters.wait_for_server_status(self.servers_client, self.server_id,
                                            'ACTIVE')
         except Exception:
             self.__class__.server_id = self.recreate_server(self.server_id)
@@ -52,7 +52,6 @@
     @classmethod
     def setup_clients(cls):
         super(ServersNegativeTestJSON, cls).setup_clients()
-        cls.client = cls.servers_client
 
     @classmethod
     def resource_setup(cls):
@@ -62,8 +61,8 @@
 
         # Wait until the instance is active to avoid the delete racing
         server = cls.create_test_server(wait_until='ACTIVE')
-        cls.client.delete_server(server['id'])
-        waiters.wait_for_server_termination(cls.client, server['id'])
+        cls.servers_client.delete_server(server['id'])
+        waiters.wait_for_server_termination(cls.servers_client, server['id'])
         cls.deleted_server_id = server['id']
 
     @decorators.attr(type=['negative'])
@@ -135,7 +134,7 @@
         """Resizing a non-existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.resize_server,
+                          self.servers_client.resize_server,
                           nonexistent_server, self.flavor_ref)
 
     @decorators.idempotent_id('ced1a1d7-2ab6-45c9-b90f-b27d87b30efd')
@@ -145,7 +144,8 @@
     def test_resize_server_with_non_existent_flavor(self):
         """Resizing a server with non existent flavor should fail"""
         nonexistent_flavor = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.BadRequest, self.client.resize_server,
+        self.assertRaises(lib_exc.BadRequest,
+                          self.servers_client.resize_server,
                           self.server_id, flavor_ref=nonexistent_flavor)
 
     @decorators.idempotent_id('45436a7d-a388-4a35-a9d8-3adc5d0d940b')
@@ -154,7 +154,8 @@
     @decorators.attr(type=['negative'])
     def test_resize_server_with_null_flavor(self):
         """Resizing a server with null flavor should fail"""
-        self.assertRaises(lib_exc.BadRequest, self.client.resize_server,
+        self.assertRaises(lib_exc.BadRequest,
+                          self.servers_client.resize_server,
                           self.server_id, flavor_ref="")
 
     @decorators.attr(type=['negative'])
@@ -162,7 +163,7 @@
     def test_reboot_non_existent_server(self):
         """Rebooting a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.reboot_server,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.reboot_server,
                           nonexistent_server, type='SOFT')
 
     @decorators.idempotent_id('d1417e7f-a509-41b5-a102-d5eed8613369')
@@ -171,19 +172,20 @@
     @decorators.attr(type=['negative'])
     def test_pause_paused_server(self):
         """Pausing a paused server should fail"""
-        self.client.pause_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id, 'PAUSED')
+        self.servers_client.pause_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
+                                       'PAUSED')
         self.assertRaises(lib_exc.Conflict,
-                          self.client.pause_server,
+                          self.servers_client.pause_server,
                           self.server_id)
-        self.client.unpause_server(self.server_id)
+        self.servers_client.unpause_server(self.server_id)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('98fa0458-1485-440f-873b-fe7f0d714930')
     def test_rebuild_deleted_server(self):
         """Rebuilding a deleted server should fail"""
         self.assertRaises(lib_exc.NotFound,
-                          self.client.rebuild_server,
+                          self.servers_client.rebuild_server,
                           self.deleted_server_id, self.image_ref)
 
     @decorators.related_bug('1660878', status_code=409)
@@ -191,7 +193,7 @@
     @decorators.idempotent_id('581a397d-5eab-486f-9cf9-1014bbd4c984')
     def test_reboot_deleted_server(self):
         """Rebooting a deleted server should fail"""
-        self.assertRaises(lib_exc.NotFound, self.client.reboot_server,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.reboot_server,
                           self.deleted_server_id, type='SOFT')
 
     @decorators.attr(type=['negative'])
@@ -200,7 +202,7 @@
         """Rebuilding a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.rebuild_server,
+                          self.servers_client.rebuild_server,
                           nonexistent_server,
                           self.image_ref)
 
@@ -292,7 +294,7 @@
             prefix=CONF.resource_name_prefix,
             name=self.__class__.__name__ + '-server') + '_updated'
 
-        self.assertRaises(lib_exc.NotFound, self.client.update_server,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.update_server,
                           nonexistent_server, name=new_name)
 
     @decorators.attr(type=['negative'])
@@ -300,7 +302,8 @@
     def test_update_server_set_empty_name(self):
         """Updating name of the server to an empty string should fail"""
         new_name = ''
-        self.assertRaises(lib_exc.BadRequest, self.client.update_server,
+        self.assertRaises(lib_exc.BadRequest,
+                          self.servers_client.update_server,
                           self.server_id, name=new_name)
 
     @decorators.attr(type=['negative'])
@@ -313,7 +316,7 @@
         """
         new_name = 'a' * 256
         self.assertRaises(lib_exc.BadRequest,
-                          self.client.update_server,
+                          self.servers_client.update_server,
                           self.server_id,
                           name=new_name)
 
@@ -322,14 +325,15 @@
     def test_delete_non_existent_server(self):
         """Deleting a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.delete_server,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.delete_server,
                           nonexistent_server)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('75f79124-277c-45e6-a373-a1d6803f4cc4')
     def test_delete_server_pass_negative_id(self):
         """Passing an invalid string parameter to delete server should fail"""
-        self.assertRaises(lib_exc.NotFound, self.client.delete_server, -1)
+        self.assertRaises(lib_exc.NotFound,
+                          self.servers_client.delete_server, -1)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('f4d7279b-5fd2-4bf2-9ba4-ae35df0d18c5')
@@ -339,7 +343,7 @@
         Pass a server ID that exceeds length limit to delete server, an error
         is returned.
         """
-        self.assertRaises(lib_exc.NotFound, self.client.delete_server,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.delete_server,
                           sys.maxsize + 1)
 
     @decorators.attr(type=['negative'])
@@ -356,7 +360,8 @@
     def test_get_non_existent_server(self):
         """Getting a non existent server details should fail"""
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.show_server,
+        self.assertRaises(lib_exc.NotFound,
+                          self.reader_servers_client.show_server,
                           nonexistent_server)
 
     @decorators.attr(type=['negative'])
@@ -374,7 +379,7 @@
     def test_pause_non_existent_server(self):
         """Pausing a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.pause_server,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.pause_server,
                           nonexistent_server)
 
     @decorators.idempotent_id('705b8e3a-e8a7-477c-a19b-6868fc24ac75')
@@ -384,7 +389,7 @@
     def test_unpause_non_existent_server(self):
         """Unpausing a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.unpause_server,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.unpause_server,
                           nonexistent_server)
 
     @decorators.idempotent_id('c8e639a7-ece8-42dd-a2e0-49615917ba4f')
@@ -394,7 +399,7 @@
     def test_unpause_server_invalid_state(self):
         """Unpausing an active server should fail"""
         self.assertRaises(lib_exc.Conflict,
-                          self.client.unpause_server,
+                          self.servers_client.unpause_server,
                           self.server_id)
 
     @decorators.idempotent_id('d1f032d5-7b6e-48aa-b252-d5f16dd994ca')
@@ -404,7 +409,7 @@
     def test_suspend_non_existent_server(self):
         """Suspending a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.suspend_server,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.suspend_server,
                           nonexistent_server)
 
     @decorators.idempotent_id('7f323206-05a9-4bf8-996b-dd5b2036501b')
@@ -413,13 +418,13 @@
     @decorators.attr(type=['negative'])
     def test_suspend_server_invalid_state(self):
         """Suspending a suspended server should fail"""
-        self.client.suspend_server(self.server_id)
-        waiters.wait_for_server_status(self.client, self.server_id,
+        self.servers_client.suspend_server(self.server_id)
+        waiters.wait_for_server_status(self.servers_client, self.server_id,
                                        'SUSPENDED')
         self.assertRaises(lib_exc.Conflict,
-                          self.client.suspend_server,
+                          self.servers_client.suspend_server,
                           self.server_id)
-        self.client.resume_server(self.server_id)
+        self.servers_client.resume_server(self.server_id)
 
     @decorators.idempotent_id('221cd282-bddb-4837-a683-89c2487389b6')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
@@ -428,7 +433,7 @@
     def test_resume_non_existent_server(self):
         """Resuming a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.resume_server,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.resume_server,
                           nonexistent_server)
 
     @decorators.idempotent_id('ccb6294d-c4c9-498f-8a43-554c098bfadb')
@@ -438,7 +443,7 @@
     def test_resume_server_invalid_state(self):
         """Resuming an active server should fail"""
         self.assertRaises(lib_exc.Conflict,
-                          self.client.resume_server,
+                          self.servers_client.resume_server,
                           self.server_id)
 
     @decorators.attr(type=['negative'])
@@ -447,7 +452,7 @@
         """Getting the console output for a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.get_console_output,
+                          self.servers_client.get_console_output,
                           nonexistent_server, length=10)
 
     @decorators.attr(type=['negative'])
@@ -456,7 +461,7 @@
         """Force-deleting a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.force_delete_server,
+                          self.servers_client.force_delete_server,
                           nonexistent_server)
 
     @decorators.attr(type=['negative'])
@@ -469,7 +474,7 @@
         """
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
-                          self.client.restore_soft_deleted_server,
+                          self.servers_client.restore_soft_deleted_server,
                           nonexistent_server)
 
     @decorators.idempotent_id('abca56e2-a892-48ea-b5e5-e07e69774816')
@@ -479,7 +484,7 @@
     def test_shelve_non_existent_server(self):
         """Shelving a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.shelve_server,
+        self.assertRaises(lib_exc.NotFound, self.servers_client.shelve_server,
                           nonexistent_server)
 
     @decorators.idempotent_id('443e4f9b-e6bf-4389-b601-3a710f15fddd')
@@ -488,15 +493,17 @@
     @decorators.attr(type=['negative'])
     def test_shelve_shelved_server(self):
         """Shelving a shelved server should fail"""
-        compute.shelve_server(self.client, self.server_id)
+        compute.shelve_server(self.servers_client, self.server_id)
 
         def _unshelve_server():
-            server_info = self.client.show_server(self.server_id)['server']
+            server_info = self.reader_servers_client.show_server(
+                self.server_id)['server']
             if 'SHELVED' in server_info['status']:
-                self.client.unshelve_server(self.server_id)
+                self.servers_client.unshelve_server(self.server_id)
         self.addCleanup(_unshelve_server)
 
-        server = self.client.show_server(self.server_id)['server']
+        server = self.reader_servers_client.show_server(
+            self.server_id)['server']
         image_name = server['name'] + '-shelved'
         kwargs = {'params': {'name': image_name}}
         images = self.images_client.list_images(**kwargs)['images']
@@ -504,10 +511,10 @@
         self.assertEqual(image_name, images[0]['name'])
 
         self.assertRaises(lib_exc.Conflict,
-                          self.client.shelve_server,
+                          self.servers_client.shelve_server,
                           self.server_id)
 
-        self.client.unshelve_server(self.server_id)
+        self.servers_client.unshelve_server(self.server_id)
 
     @decorators.idempotent_id('23d23b37-afaf-40d7-aa5d-5726f82d8821')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
@@ -516,7 +523,8 @@
     def test_unshelve_non_existent_server(self):
         """Unshelving a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.client.unshelve_server,
+        self.assertRaises(lib_exc.NotFound,
+                          self.servers_client.unshelve_server,
                           nonexistent_server)
 
     @decorators.idempotent_id('8f198ded-1cca-4228-9e65-c6b449c54880')
@@ -526,7 +534,7 @@
     def test_unshelve_server_invalid_state(self):
         """Unshelving an active server should fail"""
         self.assertRaises(lib_exc.Conflict,
-                          self.client.unshelve_server,
+                          self.servers_client.unshelve_server,
                           self.server_id)
 
     @decorators.attr(type=['negative'])
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index 80c4d1c..7291a0b 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -26,6 +26,27 @@
 class DomainsTestJSON(base.BaseIdentityV3AdminTest):
     """Test identity domains"""
 
+    credentials = ['primary', 'admin', 'system_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(DomainsTestJSON, cls).setup_clients()
+        if CONF.identity.use_system_token:
+            # Use system reader for listing/showing domains
+            cls.reader_domains_client = (
+                cls.os_system_reader.domains_client)
+            # Use system reader for showing users
+            cls.reader_users_client = (
+                cls.os_system_reader.users_v3_client)
+            # Use system reader for showing groups
+            cls.reader_groups_client = (
+                cls.os_system_reader.groups_client)
+        else:
+            # Use admin client by default
+            cls.reader_domains_client = cls.domains_client
+            cls.reader_users_client = cls.users_client
+            cls.reader_groups_client = cls.groups_client
+
     @classmethod
     def resource_setup(cls):
         super(DomainsTestJSON, cls).resource_setup()
@@ -41,7 +62,7 @@
         """Test listing domains"""
         fetched_ids = list()
         # List and Verify Domains
-        body = self.domains_client.list_domains()['domains']
+        body = self.reader_domains_client.list_domains()['domains']
         for d in body:
             fetched_ids.append(d['id'])
         missing_doms = [d for d in self.setup_domains
@@ -52,7 +73,7 @@
     def test_list_domains_filter_by_name(self):
         """Test listing domains filtering by name"""
         params = {'name': self.setup_domains[0]['name']}
-        fetched_domains = self.domains_client.list_domains(
+        fetched_domains = self.reader_domains_client.list_domains(
             **params)['domains']
         # Verify the filtered list is correct, domain names are unique
         # so exactly one domain should be found with the provided name
@@ -64,7 +85,7 @@
     def test_list_domains_filter_by_enabled(self):
         """Test listing domains filtering by enabled domains"""
         params = {'enabled': True}
-        fetched_domains = self.domains_client.list_domains(
+        fetched_domains = self.reader_domains_client.list_domains(
             **params)['domains']
         # Verify the filtered list is correct
         self.assertIn(self.setup_domains[0], fetched_domains)
@@ -108,14 +129,14 @@
         self.assertEqual(new_desc, updated_domain['description'])
         self.assertEqual(False, updated_domain['enabled'])
         # Show domain
-        fetched_domain = self.domains_client.show_domain(
+        fetched_domain = self.reader_domains_client.show_domain(
             domain['id'])['domain']
         self.assertEqual(new_name, fetched_domain['name'])
         self.assertEqual(new_desc, fetched_domain['description'])
         self.assertEqual(False, fetched_domain['enabled'])
         # Delete domain
         self.domains_client.delete_domain(domain['id'])
-        body = self.domains_client.list_domains()['domains']
+        body = self.reader_domains_client.list_domains()['domains']
         domains_list = [d['id'] for d in body]
         self.assertNotIn(domain['id'], domains_list)
 
@@ -130,11 +151,11 @@
         self.delete_domain(domain['id'])
         # Check the domain, its users and groups are gone
         self.assertRaises(exceptions.NotFound,
-                          self.domains_client.show_domain, domain['id'])
+                          self.reader_domains_client.show_domain, domain['id'])
         self.assertRaises(exceptions.NotFound,
-                          self.users_client.show_user, user['id'])
+                          self.reader_users_client.show_user, user['id'])
         self.assertRaises(exceptions.NotFound,
-                          self.groups_client.show_group, group['id'])
+                          self.reader_groups_client.show_group, group['id'])
 
     @decorators.idempotent_id('036df86e-bb5d-42c0-a7c2-66b9db3a6046')
     def test_create_domain_with_disabled_status(self):
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index f9f3e72..defdcc7 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -30,10 +30,21 @@
     # pre-provisioned credentials provider.
     force_tenant_isolation = False
 
+    credentials = ['primary', 'admin', 'system_reader']
+
     @classmethod
     def setup_clients(cls):
         super(EndPointsTestJSON, cls).setup_clients()
         cls.client = cls.endpoints_client
+        if CONF.identity.use_system_token:
+            # Use system reader for listing/showing endpoints
+            cls.reader_client = cls.os_system_reader.endpoints_v3_client
+            # Use system reader for showing regions
+            cls.reader_regions_client = cls.os_system_reader.regions_client
+        else:
+            # Use admin client by default
+            cls.reader_client = cls.client
+            cls.reader_regions_client = cls.regions_client
 
     @classmethod
     def resource_setup(cls):
@@ -55,7 +66,8 @@
             endpoint = cls.client.create_endpoint(
                 service_id=cls.service_ids[i], interface=interfaces[i],
                 url=url, region=region_name, enabled=True)['endpoint']
-            region = cls.regions_client.show_region(region_name)['region']
+            region = cls.reader_regions_client.show_region(region_name)[
+                'region']
             cls.addClassResourceCleanup(
                 cls.regions_client.delete_region, region['id'])
             cls.addClassResourceCleanup(
@@ -81,7 +93,7 @@
     def test_list_endpoints(self):
         """Test listing keystone endpoints by filters"""
         # Get the list of all the endpoints.
-        fetched_endpoints = self.client.list_endpoints()['endpoints']
+        fetched_endpoints = self.reader_client.list_endpoints()['endpoints']
         fetched_endpoint_ids = [e['id'] for e in fetched_endpoints]
         # Check that all the created endpoints are present in
         # "fetched_endpoints".
@@ -93,9 +105,9 @@
                          ', '.join(str(e) for e in missing_endpoints))
 
         # Check that filtering endpoints by service_id works.
-        fetched_endpoints_for_service = self.client.list_endpoints(
+        fetched_endpoints_for_service = self.reader_client.list_endpoints(
             service_id=self.service_ids[0])['endpoints']
-        fetched_endpoints_for_alt_service = self.client.list_endpoints(
+        fetched_endpoints_for_alt_service = self.reader_client.list_endpoints(
             service_id=self.service_ids[1])['endpoints']
 
         # Assert that both filters returned the correct result.
@@ -106,9 +118,9 @@
                               fetched_endpoints_for_alt_service[0]['id']]))
 
         # Check that filtering endpoints by interface works.
-        fetched_public_endpoints = self.client.list_endpoints(
+        fetched_public_endpoints = self.reader_client.list_endpoints(
             interface='public')['endpoints']
-        fetched_internal_endpoints = self.client.list_endpoints(
+        fetched_internal_endpoints = self.reader_client.list_endpoints(
             interface='internal')['endpoints']
 
         # Check that the expected endpoint_id is present per filter. [0] is
@@ -129,7 +141,7 @@
                                                interface=interface,
                                                url=url, region=region_name,
                                                enabled=True)['endpoint']
-        region = self.regions_client.show_region(region_name)['region']
+        region = self.reader_regions_client.show_region(region_name)['region']
         self.addCleanup(self.regions_client.delete_region, region['id'])
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.client.delete_endpoint, endpoint['id'])
@@ -138,13 +150,13 @@
         self.assertEqual(url, endpoint['url'])
 
         # Checking if created endpoint is present in the list of endpoints
-        fetched_endpoints = self.client.list_endpoints()['endpoints']
+        fetched_endpoints = self.reader_client.list_endpoints()['endpoints']
         fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
         self.assertIn(endpoint['id'], fetched_endpoints_id)
 
         # Show endpoint
         fetched_endpoint = (
-            self.client.show_endpoint(endpoint['id'])['endpoint'])
+            self.reader_client.show_endpoint(endpoint['id'])['endpoint'])
         # Asserting if the attributes of endpoint are the same
         self.assertEqual(self.service_ids[0], fetched_endpoint['service_id'])
         self.assertEqual(interface, fetched_endpoint['interface'])
@@ -156,7 +168,7 @@
         self.client.delete_endpoint(endpoint['id'])
 
         # Checking whether endpoint is deleted successfully
-        fetched_endpoints = self.client.list_endpoints()['endpoints']
+        fetched_endpoints = self.reader_client.list_endpoints()['endpoints']
         fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
         self.assertNotIn(endpoint['id'], fetched_endpoints_id)
 
@@ -187,7 +199,8 @@
                                         interface=interface1,
                                         url=url1, region=region1_name,
                                         enabled=True)['endpoint'])
-        region1 = self.regions_client.show_region(region1_name)['region']
+        region1 = self.reader_regions_client.show_region(region1_name)[
+            'region']
         self.addCleanup(self.regions_client.delete_region, region1['id'])
 
         # Updating endpoint with new values
@@ -199,7 +212,8 @@
                                                interface=interface2,
                                                url=url2, region=region2_name,
                                                enabled=False)['endpoint']
-        region2 = self.regions_client.show_region(region2_name)['region']
+        region2 = self.reader_regions_client.show_region(region2_name)[
+            'region']
         self.addCleanup(self.regions_client.delete_region, region2['id'])
         self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
 
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 96218bb..f704f02 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -30,6 +30,23 @@
     # pre-provisioned credentials provider.
     force_tenant_isolation = False
 
+    credentials = ['primary', 'admin', 'system_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(GroupsV3TestJSON, cls).setup_clients()
+        if CONF.identity.use_system_token:
+            # Use system reader for listing/showing groups
+            cls.reader_groups_client = (
+                cls.os_system_reader.groups_client)
+            # Use system reader for listing user groups
+            cls.reader_users_client = (
+                cls.os_system_reader.users_v3_client)
+        else:
+            # Use admin client by default
+            cls.reader_groups_client = cls.groups_client
+            cls.reader_users_client = cls.users_client
+
     @classmethod
     def resource_setup(cls):
         super(GroupsV3TestJSON, cls).resource_setup()
@@ -60,7 +77,7 @@
         self.assertEqual(updated_group['description'], first_desc_update)
 
         # Verify that the updated values are reflected after performing show.
-        new_group = self.groups_client.show_group(group['id'])['group']
+        new_group = self.reader_groups_client.show_group(group['id'])['group']
         self.assertEqual(group['id'], new_group['id'])
         self.assertEqual(first_name_update, new_group['name'])
         self.assertEqual(first_desc_update, new_group['description'])
@@ -94,7 +111,8 @@
             self.groups_client.add_group_user(group['id'], user['id'])
 
         # list users in group
-        group_users = self.groups_client.list_group_users(group['id'])['users']
+        group_users = self.reader_groups_client.list_group_users(group['id'])[
+            'users']
         self.assertEqual(sorted(users, key=lambda k: k['name']),
                          sorted(group_users, key=lambda k: k['name']))
         # check and delete user in group
@@ -102,7 +120,8 @@
             self.groups_client.check_group_user_existence(
                 group['id'], user['id'])
             self.groups_client.delete_group_user(group['id'], user['id'])
-        group_users = self.groups_client.list_group_users(group['id'])['users']
+        group_users = self.reader_groups_client.list_group_users(group['id'])[
+            'users']
         self.assertEqual(len(group_users), 0)
 
     @decorators.idempotent_id('64573281-d26a-4a52-b899-503cb0f4e4ec')
@@ -121,7 +140,8 @@
             groups.append(group)
             self.groups_client.add_group_user(group['id'], user['id'])
         # list groups which user belongs to
-        user_groups = self.users_client.list_user_groups(user['id'])['groups']
+        user_groups = self.reader_users_client.list_user_groups(user['id'])[
+            'groups']
         # The `membership_expires_at` attribute is present when listing user
         # group memberships, and is not an attribute of the groups themselves.
         # Therefore we remove it from the comparison.
@@ -146,10 +166,10 @@
         # of listing all users and listing all groups are not supported,
         # they need a domain filter to be specified
         if CONF.identity_feature_enabled.domain_specific_drivers:
-            body = self.groups_client.list_groups(
+            body = self.reader_groups_client.list_groups(
                 domain_id=self.domain['id'])['groups']
         else:
-            body = self.groups_client.list_groups()['groups']
+            body = self.reader_groups_client.list_groups()['groups']
         for g in body:
             fetched_ids.append(g['id'])
         missing_groups = [g for g in group_ids if g not in fetched_ids]
diff --git a/tempest/api/identity/admin/v3/test_list_projects.py b/tempest/api/identity/admin/v3/test_list_projects.py
index 2135fcc..c758dfa 100644
--- a/tempest/api/identity/admin/v3/test_list_projects.py
+++ b/tempest/api/identity/admin/v3/test_list_projects.py
@@ -26,13 +26,26 @@
 
 class BaseListProjectsTestJSON(base.BaseIdentityV3AdminTest):
 
+    credentials = ['primary', 'admin', 'system_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseListProjectsTestJSON, cls).setup_clients()
+        if CONF.identity.use_system_token:
+            # Use system reader for listing projects
+            cls.reader_projects_client = (
+                cls.os_system_reader.projects_client)
+        else:
+            # Use admin client by default
+            cls.reader_projects_client = cls.projects_client
+
     def _list_projects_with_params(self, included, excluded, params, key):
         # Validate that projects in ``included`` belongs to the projects
         # returned that match ``params`` but not projects in ``excluded``
-        all_projects = self.projects_client.list_projects()['projects']
+        all_projects = self.reader_projects_client.list_projects()['projects']
         LOG.debug("Complete list of projects available in keystone: %s",
                   all_projects)
-        body = self.projects_client.list_projects(params)['projects']
+        body = self.reader_projects_client.list_projects(params)['projects']
         for p in included:
             self.assertIn(p[key], map(lambda x: x[key], body))
         for p in excluded:
@@ -75,7 +88,7 @@
     def test_list_projects_with_parent(self):
         """Test listing projects with parent"""
         params = {'parent_id': self.p3['parent_id']}
-        fetched_projects = self.projects_client.list_projects(
+        fetched_projects = self.reader_projects_client.list_projects(
             params)['projects']
         self.assertNotEmpty(fetched_projects)
         for project in fetched_projects:
@@ -111,10 +124,10 @@
     @decorators.idempotent_id('1d830662-22ad-427c-8c3e-4ec854b0af44')
     def test_list_projects(self):
         """Test listing projects"""
-        list_projects = self.projects_client.list_projects()['projects']
+        list_projects = self.reader_projects_client.list_projects()['projects']
 
         for p in [self.p1, self.p2]:
-            show_project = self.projects_client.show_project(p['id'])[
+            show_project = self.reader_projects_client.show_project(p['id'])[
                 'project']
             self.assertIn(show_project, list_projects)
 
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
index 3884989..e8d0ff5 100644
--- a/tempest/api/identity/admin/v3/test_list_users.py
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -24,12 +24,25 @@
 class UsersV3TestJSON(base.BaseIdentityV3AdminTest):
     """Test listing keystone users"""
 
+    credentials = ['primary', 'admin', 'system_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(UsersV3TestJSON, cls).setup_clients()
+        if CONF.identity.use_system_token:
+            # Use system reader for listing users
+            cls.reader_users_client = (
+                cls.os_system_reader.users_v3_client)
+        else:
+            # Use admin client by default
+            cls.reader_users_client = cls.users_client
+
     def _list_users_with_params(self, params, key, expected, not_expected):
         # Helper method to list users filtered with params and
         # assert the response based on expected and not_expected
         # expected: user expected in the list response
         # not_expected: user, which should not be present in list response
-        body = self.users_client.list_users(**params)['users']
+        body = self.reader_users_client.list_users(**params)['users']
         self.assertIn(expected[key], map(lambda x: x[key], body))
         self.assertNotIn(not_expected[key],
                          map(lambda x: x[key], body))
@@ -105,13 +118,13 @@
         # of listing all users and listing all groups are not supported,
         # they need a domain filter to be specified
         if CONF.identity_feature_enabled.domain_specific_drivers:
-            body_enabled_user = self.users_client.list_users(
+            body_enabled_user = self.reader_users_client.list_users(
                 domain_id=self.domain_enabled_user['domain_id'])['users']
-            body_non_enabled_user = self.users_client.list_users(
+            body_non_enabled_user = self.reader_users_client.list_users(
                 domain_id=self.non_domain_enabled_user['domain_id'])['users']
             body = (body_enabled_user + body_non_enabled_user)
         else:
-            body = self.users_client.list_users()['users']
+            body = self.reader_users_client.list_users()['users']
 
         fetched_ids = [u['id'] for u in body]
         missing_users = [u['id'] for u in self.users
@@ -123,7 +136,7 @@
     @decorators.idempotent_id('b4baa3ae-ac00-4b4e-9e27-80deaad7771f')
     def test_get_user(self):
         """Get a user detail"""
-        user = self.users_client.show_user(self.users[0]['id'])['user']
+        user = self.reader_users_client.show_user(self.users[0]['id'])['user']
         self.assertEqual(self.users[0]['id'], user['id'])
         self.assertEqual(self.users[0]['name'], user['name'])
         self.assertEqual(self.alt_email, user['email'])
diff --git a/tempest/api/identity/admin/v3/test_policies.py b/tempest/api/identity/admin/v3/test_policies.py
index 2d3775a..6bce533 100644
--- a/tempest/api/identity/admin/v3/test_policies.py
+++ b/tempest/api/identity/admin/v3/test_policies.py
@@ -24,6 +24,19 @@
 class PoliciesTestJSON(base.BaseIdentityV3AdminTest):
     """Test keystone policies"""
 
+    credentials = ['primary', 'admin', 'system_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(PoliciesTestJSON, cls).setup_clients()
+        if CONF.identity.use_system_token:
+            # Use system reader for listing/showing policies
+            cls.reader_policies_client = (
+                cls.os_system_reader.policies_client)
+        else:
+            # Use admin client by default
+            cls.reader_policies_client = cls.policies_client
+
     def _delete_policy(self, policy_id):
         self.policies_client.delete_policy(policy_id)
 
@@ -43,7 +56,7 @@
             self.addCleanup(self._delete_policy, policy['id'])
             policy_ids.append(policy['id'])
         # List and Verify Policies
-        body = self.policies_client.list_policies()['policies']
+        body = self.reader_policies_client.list_policies()['policies']
         for p in body:
             fetched_ids.append(p['id'])
         missing_pols = [p for p in policy_ids if p not in fetched_ids]
@@ -70,7 +83,7 @@
             policy['id'], type=update_type)['policy']
         self.assertIn('type', data)
         # Assertion for updated value with fetched value
-        fetched_policy = self.policies_client.show_policy(
+        fetched_policy = self.reader_policies_client.show_policy(
             policy['id'])['policy']
         self.assertIn('id', fetched_policy)
         self.assertIn('blob', fetched_policy)
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index 3b0052c..c191955 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -30,6 +30,27 @@
     # pre-provisioned credentials provider.
     force_tenant_isolation = False
 
+    credentials = ['primary', 'admin', 'system_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(ProjectsTestJSON, cls).setup_clients()
+        if CONF.identity.use_system_token:
+            # Use system reader for listing/showing projects
+            cls.reader_projects_client = (
+                cls.os_system_reader.projects_client)
+            # Use system reader for listing/showing domains
+            cls.reader_domains_client = (
+                cls.os_system_reader.domains_client)
+            # Use system reader for showing users
+            cls.reader_users_client = (
+                cls.os_system_reader.users_v3_client)
+        else:
+            # Use admin client by default
+            cls.reader_projects_client = cls.projects_client
+            cls.reader_domains_client = cls.domains_client
+            cls.reader_users_client = cls.users_client
+
     @decorators.idempotent_id('0ecf465c-0dc4-4532-ab53-91ffeb74d12d')
     def test_project_create_with_description(self):
         """Test creating project with a description"""
@@ -40,7 +61,7 @@
         desc1 = project['description']
         self.assertEqual(desc1, project_desc, 'Description should have '
                          'been sent in response for create')
-        body = self.projects_client.show_project(project_id)['project']
+        body = self.reader_projects_client.show_project(project_id)['project']
         desc2 = body['description']
         self.assertEqual(desc2, project_desc, 'Description does not appear '
                          'to be set')
@@ -56,7 +77,7 @@
         project_id = project['id']
         self.assertEqual(project_name, project['name'])
         self.assertEqual(domain['id'], project['domain_id'])
-        body = self.projects_client.show_project(project_id)['project']
+        body = self.reader_projects_client.show_project(project_id)['project']
         self.assertEqual(project_name, body['name'])
         self.assertEqual(domain['id'], body['domain_id'])
 
@@ -97,15 +118,15 @@
 
         # Check if the is_domain project is correctly returned by both
         # project and domain APIs
-        projects_list = self.projects_client.list_projects(
+        projects_list = self.reader_projects_client.list_projects(
             params={'is_domain': True})['projects']
         project_ids = [p['id'] for p in projects_list]
         self.assertIn(project['id'], project_ids)
 
         # The domains API return different attributes for the entity, so we
         # compare the entities IDs
-        domains_ids = [d['id'] for d in self.domains_client.list_domains()[
-            'domains']]
+        domains_list = self.reader_domains_client.list_domains()['domains']
+        domains_ids = [d['id'] for d in domains_list]
         self.assertIn(project['id'], domains_ids)
 
     @decorators.idempotent_id('1f66dc76-50cc-4741-a200-af984509e480')
@@ -115,7 +136,7 @@
         project_id = project['id']
         self.assertTrue(project['enabled'],
                         'Enable should be True in response')
-        body = self.projects_client.show_project(project_id)['project']
+        body = self.reader_projects_client.show_project(project_id)['project']
         self.assertTrue(body['enabled'], 'Enable should be True in lookup')
 
     @decorators.idempotent_id('78f96a9c-e0e0-4ee6-a3ba-fbf6dfd03207')
@@ -124,7 +145,8 @@
         project = self.setup_test_project(enabled=False)
         self.assertFalse(project['enabled'],
                          'Enable should be False in response')
-        body = self.projects_client.show_project(project['id'])['project']
+        body = self.reader_projects_client.show_project(project['id'])[
+            'project']
         self.assertFalse(body['enabled'],
                          'Enable should be False in lookup')
 
@@ -144,7 +166,8 @@
         resp2_name = body['name']
         self.assertNotEqual(resp1_name, resp2_name)
 
-        body = self.projects_client.show_project(project['id'])['project']
+        body = self.reader_projects_client.show_project(project['id'])[
+            'project']
         resp3_name = body['name']
 
         self.assertNotEqual(resp1_name, resp3_name)
@@ -166,7 +189,8 @@
         resp2_desc = body['description']
         self.assertNotEqual(resp1_desc, resp2_desc)
 
-        body = self.projects_client.show_project(project['id'])['project']
+        body = self.reader_projects_client.show_project(project['id'])[
+            'project']
         resp3_desc = body['description']
 
         self.assertNotEqual(resp1_desc, resp3_desc)
@@ -187,7 +211,8 @@
         resp2_en = body['enabled']
         self.assertNotEqual(resp1_en, resp2_en)
 
-        body = self.projects_client.show_project(project['id'])['project']
+        body = self.reader_projects_client.show_project(project['id'])[
+            'project']
         resp3_en = body['enabled']
 
         self.assertNotEqual(resp1_en, resp3_en)
@@ -217,7 +242,7 @@
         self.addCleanup(self.users_client.delete_user, user['id'])
 
         # Get User To validate the user details
-        new_user_get = self.users_client.show_user(user['id'])['user']
+        new_user_get = self.reader_users_client.show_user(user['id'])['user']
         # Assert response body of GET
         self.assertEqual(u_name, new_user_get['name'])
         self.assertEqual(u_desc, new_user_get['description'])
@@ -238,9 +263,9 @@
         project = self.setup_test_project(tags=tags)
 
         # Show and list for the project
-        project_get = self.projects_client.show_project(
+        project_get = self.reader_projects_client.show_project(
             project['id'])['project']
-        _projects = self.projects_client.list_projects()['projects']
+        _projects = self.reader_projects_client.list_projects()['projects']
         project_list = next(x for x in _projects if x['id'] == project['id'])
 
         # Assert the expected fields exist. More fields than expected may
diff --git a/tempest/api/identity/admin/v3/test_regions.py b/tempest/api/identity/admin/v3/test_regions.py
index 870a406..f021cc2 100644
--- a/tempest/api/identity/admin/v3/test_regions.py
+++ b/tempest/api/identity/admin/v3/test_regions.py
@@ -30,10 +30,18 @@
     # pre-provisioned credentials provider.
     force_tenant_isolation = False
 
+    credentials = ['primary', 'admin', 'system_reader']
+
     @classmethod
     def setup_clients(cls):
         super(RegionsTestJSON, cls).setup_clients()
         cls.client = cls.regions_client
+        if CONF.identity.use_system_token:
+            # Use system reader for listing/showing regions
+            cls.reader_client = cls.os_system_reader.regions_client
+        else:
+            # Use admin client by default
+            cls.reader_client = cls.client
 
     @classmethod
     def resource_setup(cls):
@@ -77,13 +85,13 @@
         self.assertEqual(self.setup_regions[1]['id'],
                          region['parent_region_id'])
         # Get the details of region
-        region = self.client.show_region(region['id'])['region']
+        region = self.reader_client.show_region(region['id'])['region']
         self.assertEqual(r_alt_description, region['description'])
         self.assertEqual(self.setup_regions[1]['id'],
                          region['parent_region_id'])
         # Delete the region
         self.client.delete_region(region['id'])
-        body = self.client.list_regions()['regions']
+        body = self.reader_client.list_regions()['regions']
         regions_list = [r['id'] for r in body]
         self.assertNotIn(region['id'], regions_list)
 
@@ -104,7 +112,7 @@
     @decorators.idempotent_id('d180bf99-544a-445c-ad0d-0c0d27663796')
     def test_list_regions(self):
         """Test getting a list of regions"""
-        fetched_regions = self.client.list_regions()['regions']
+        fetched_regions = self.reader_client.list_regions()['regions']
         missing_regions =\
             [e for e in self.setup_regions if e not in fetched_regions]
         # Asserting List Regions response
@@ -124,7 +132,8 @@
         self.addCleanup(self.client.delete_region, region['id'])
         # Get the list of regions filtering with the parent_region_id
         params = {'parent_region_id': self.setup_regions[0]['id']}
-        fetched_regions = self.client.list_regions(params=params)['regions']
+        fetched_regions = self.reader_client.list_regions(params=params)[
+            'regions']
         # Asserting list regions response
         self.assertIn(region, fetched_regions)
         for r in fetched_regions:
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index ab96027..d1c90dc 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -32,6 +32,19 @@
     # pre-provisioned credentials provider.
     force_tenant_isolation = False
 
+    credentials = ['primary', 'admin', 'system_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(RolesV3TestJSON, cls).setup_clients()
+        if CONF.identity.use_system_token:
+            # Use system reader for listing/showing roles
+            cls.reader_roles_client = (
+                cls.os_system_reader.roles_v3_client)
+        else:
+            # Use admin client by default
+            cls.reader_roles_client = cls.roles_client
+
     @classmethod
     def resource_setup(cls):
         super(RolesV3TestJSON, cls).resource_setup()
@@ -97,11 +110,11 @@
         self.assertIn('links', updated_role)
         self.assertNotEqual(r_name, updated_role['name'])
 
-        new_role = self.roles_client.show_role(role['id'])['role']
+        new_role = self.reader_roles_client.show_role(role['id'])['role']
         self.assertEqual(new_name, new_role['name'])
         self.assertEqual(updated_role['id'], new_role['id'])
 
-        roles = self.roles_client.list_roles()['roles']
+        roles = self.reader_roles_client.list_roles()['roles']
         self.assertIn(role['id'], [r['id'] for r in roles])
 
     @decorators.idempotent_id('c6b80012-fe4a-498b-9ce8-eb391c05169f')
@@ -114,7 +127,7 @@
                                                       self.user_body['id'],
                                                       self.role['id'])
 
-        roles = self.roles_client.list_user_roles_on_project(
+        roles = self.reader_roles_client.list_user_roles_on_project(
             self.project['id'], self.user_body['id'])['roles']
 
         self.assertEqual(1, len(roles))
@@ -135,7 +148,7 @@
         self.roles_client.create_user_role_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
 
-        roles = self.roles_client.list_user_roles_on_domain(
+        roles = self.reader_roles_client.list_user_roles_on_domain(
             self.domain['id'], self.user_body['id'])['roles']
 
         self.assertEqual(1, len(roles))
@@ -155,7 +168,7 @@
         self.roles_client.create_user_role_on_system(
             self.user_body['id'], self.role['id'])
 
-        roles = self.roles_client.list_user_roles_on_system(
+        roles = self.reader_roles_client.list_user_roles_on_system(
             self.user_body['id'])['roles']
 
         self.assertEqual(1, len(roles))
@@ -177,7 +190,7 @@
         self.roles_client.create_group_role_on_project(
             self.project['id'], self.group_body['id'], self.role['id'])
         # List group roles on project
-        roles = self.roles_client.list_group_roles_on_project(
+        roles = self.reader_roles_client.list_group_roles_on_project(
             self.project['id'], self.group_body['id'])['roles']
 
         self.assertEqual(1, len(roles))
@@ -210,7 +223,7 @@
         self.roles_client.create_group_role_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
 
-        roles = self.roles_client.list_group_roles_on_domain(
+        roles = self.reader_roles_client.list_group_roles_on_domain(
             self.domain['id'], self.group_body['id'])['roles']
 
         self.assertEqual(1, len(roles))
@@ -227,7 +240,7 @@
         self.roles_client.create_group_role_on_system(
             self.group_body['id'], self.role['id'])
 
-        roles = self.roles_client.list_group_roles_on_system(
+        roles = self.reader_roles_client.list_group_roles_on_system(
             self.group_body['id'])['roles']
 
         self.assertEqual(1, len(roles))
@@ -243,7 +256,7 @@
     def test_list_roles(self):
         """Test listing roles"""
         # Return a list of all roles
-        body = self.roles_client.list_roles()['roles']
+        body = self.reader_roles_client.list_roles()['roles']
         found = [role for role in body if role in self.roles]
         self.assertEqual(len(found), len(self.roles))
 
@@ -278,7 +291,7 @@
             prior_role_id, implies_role_id)
 
         # Show the inference rule and check its elements
-        resp_body = self.roles_client.show_role_inference_rule(
+        resp_body = self.reader_roles_client.show_role_inference_rule(
             prior_role_id, implies_role_id)
         self.assertIn('role_inference', resp_body)
         role_inference = resp_body['role_inference']
@@ -293,7 +306,7 @@
         # Check if the inference rule no longer exists
         self.assertRaises(
             lib_exc.NotFound,
-            self.roles_client.show_role_inference_rule,
+            self.reader_roles_client.show_role_inference_rule,
             prior_role_id,
             implies_role_id)
 
@@ -313,14 +326,14 @@
             self.roles[2]['id'], self.role['id'])
 
         # Listing inferences rules from "roles[2]" should only return "role"
-        rules = self.roles_client.list_role_inferences_rules(
+        rules = self.reader_roles_client.list_role_inferences_rules(
             self.roles[2]['id'])['role_inference']
         self.assertEqual(1, len(rules['implies']))
         self.assertEqual(self.role['id'], rules['implies'][0]['id'])
 
         # Listing inferences rules from "roles[0]" should return "roles[1]" and
         # "roles[2]" (only direct rules are listed)
-        rules = self.roles_client.list_role_inferences_rules(
+        rules = self.reader_roles_client.list_role_inferences_rules(
             self.roles[0]['id'])['role_inference']
         implies_ids = [role['id'] for role in rules['implies']]
         self.assertEqual(2, len(implies_ids))
@@ -384,13 +397,13 @@
             self.roles_client.delete_role,
             domain_role['id'])
 
-        domain_roles = self.roles_client.list_roles(
+        domain_roles = self.reader_roles_client.list_roles(
             domain_id=self.domain['id'])['roles']
         self.assertEqual(1, len(domain_roles))
         self.assertIn(domain_role, domain_roles)
 
         self.roles_client.delete_role(domain_role['id'])
-        domain_roles = self.roles_client.list_roles(
+        domain_roles = self.reader_roles_client.list_roles(
             domain_id=self.domain['id'])['roles']
         self.assertEmpty(domain_roles)
 
@@ -465,7 +478,7 @@
         self._create_implied_role(
             self.roles[2]['id'], self.role['id'])
 
-        rules = self.roles_client.list_all_role_inference_rules()[
+        rules = self.reader_roles_client.list_all_role_inference_rules()[
             'role_inferences']
 
         # NOTE(jaosorior): With the work related to the define-default-roles
diff --git a/tempest/api/identity/admin/v3/test_services.py b/tempest/api/identity/admin/v3/test_services.py
index b67e175..3379c3e 100644
--- a/tempest/api/identity/admin/v3/test_services.py
+++ b/tempest/api/identity/admin/v3/test_services.py
@@ -25,11 +25,25 @@
 class ServicesTestJSON(base.BaseIdentityV3AdminTest):
     """Test keystone services"""
 
+    credentials = ['primary', 'admin', 'system_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(ServicesTestJSON, cls).setup_clients()
+        if CONF.identity.use_system_token:
+            # Use system reader for listing/showing services
+            cls.reader_services_client = (
+                cls.os_system_reader.identity_services_v3_client)
+        else:
+            # Use admin client by default
+            cls.reader_services_client = cls.services_client
+
     def _del_service(self, service_id):
         # Used for deleting the services created in this class
         self.services_client.delete_service(service_id)
         # Checking whether service is deleted successfully
-        self.assertRaises(lib_exc.NotFound, self.services_client.show_service,
+        self.assertRaises(lib_exc.NotFound,
+                          self.reader_services_client.show_service,
                           service_id)
 
     @decorators.attr(type='smoke')
@@ -61,7 +75,8 @@
         self.assertNotEqual(resp1_desc, resp2_desc)
 
         # Get service
-        fetched_service = self.services_client.show_service(s_id)['service']
+        fetched_service = self.reader_services_client.show_service(s_id)[
+            'service']
         resp3_desc = fetched_service['description']
 
         self.assertEqual(resp2_desc, resp3_desc)
@@ -100,14 +115,14 @@
             service_types.append(serv_type)
 
         # List and Verify Services
-        services = self.services_client.list_services()['services']
+        services = self.reader_services_client.list_services()['services']
         fetched_ids = [service['id'] for service in services]
         found = [s for s in fetched_ids if s in service_ids]
         self.assertEqual(len(found), len(service_ids))
 
         # Check that filtering by service type works.
         for serv_type in service_types:
-            fetched_services = self.services_client.list_services(
+            fetched_services = self.reader_services_client.list_services(
                 type=serv_type)['services']
             self.assertEqual(1, len(fetched_services))
             self.assertEqual(serv_type, fetched_services[0]['type'])
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 5bd6756..d843abf 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -29,6 +29,19 @@
 class TrustsV3TestJSON(base.BaseIdentityV3AdminTest):
     """Test keystone trusts"""
 
+    credentials = ['primary', 'admin', 'system_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(TrustsV3TestJSON, cls).setup_clients()
+        if CONF.identity.use_system_token:
+            # Use system reader for listing trusts
+            cls.reader_trusts_client = (
+                cls.os_system_reader.trusts_client)
+        else:
+            # Use admin client by default
+            cls.reader_trusts_client = cls.trusts_client
+
     @classmethod
     def skip_checks(cls):
         super(TrustsV3TestJSON, cls).skip_checks()
@@ -293,7 +306,7 @@
         original_scope = self.os_admin.auth_provider.scope
         set_scope(self.os_admin.auth_provider, 'project')
         self.addCleanup(set_scope, self.os_admin.auth_provider, original_scope)
-        trusts_get = self.trusts_client.list_trusts()['trusts']
+        trusts_get = self.reader_trusts_client.list_trusts()['trusts']
         trusts = [t for t in trusts_get
                   if t['id'] == self.trust_id]
         self.assertEqual(1, len(trusts))
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 9bcbba5..1272adb 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -29,6 +29,27 @@
 class UsersV3TestJSON(base.BaseIdentityV3AdminTest):
     """Test keystone users"""
 
+    credentials = ['primary', 'admin', 'system_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(UsersV3TestJSON, cls).setup_clients()
+        if CONF.identity.use_system_token:
+            # Use system reader for listing/showing users
+            cls.reader_users_client = (
+                cls.os_system_reader.users_v3_client)
+            # Use system reader for showing roles
+            cls.reader_roles_client = (
+                cls.os_system_reader.roles_v3_client)
+            # Use system reader for showing projects
+            cls.reader_projects_client = (
+                cls.os_system_reader.projects_client)
+        else:
+            # Use admin client by default
+            cls.reader_users_client = cls.users_client
+            cls.reader_roles_client = cls.roles_client
+            cls.reader_projects_client = cls.projects_client
+
     @classmethod
     def skip_checks(cls):
         super(UsersV3TestJSON, cls).skip_checks()
@@ -67,7 +88,7 @@
             self.assertEqual(update_kwargs[field], updated_user[field])
 
         # GET by id after updating
-        new_user_get = self.users_client.show_user(user['id'])['user']
+        new_user_get = self.reader_users_client.show_user(user['id'])['user']
         # Assert response body of GET after updation
         for field in update_kwargs:
             self.assertEqual(update_kwargs[field], new_user_get[field])
@@ -120,19 +141,20 @@
         # Creating Role
         role_body = self.setup_test_role()
 
-        user = self.users_client.show_user(user_body['id'])['user']
-        role = self.roles_client.show_role(role_body['id'])['role']
+        user = self.reader_users_client.show_user(user_body['id'])['user']
+        role = self.reader_roles_client.show_role(role_body['id'])['role']
         for _ in range(2):
             # Creating project so as to assign role
             project_body = self.setup_test_project()
-            project = self.projects_client.show_project(
+            project = self.reader_projects_client.show_project(
                 project_body['id'])['project']
             # Assigning roles to user on project
             self.roles_client.create_user_role_on_project(project['id'],
                                                           user['id'],
                                                           role['id'])
             assigned_project_ids.append(project['id'])
-        body = self.users_client.list_user_projects(user['id'])['projects']
+        body = self.reader_users_client.list_user_projects(user['id'])[
+            'projects']
         for i in body:
             fetched_project_ids.append(i['id'])
         # verifying the project ids in list
@@ -148,7 +170,7 @@
     def test_get_user(self):
         """Test getting a user detail"""
         user = self.setup_test_user()
-        fetched_user = self.users_client.show_user(user['id'])['user']
+        fetched_user = self.reader_users_client.show_user(user['id'])['user']
         self.assertEqual(user['id'], fetched_user['id'])
 
     @testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
diff --git a/tempest/api/network/test_agent_management_negative.py b/tempest/api/network/test_agent_management_negative.py
index d1c02ce..f4107e2 100644
--- a/tempest/api/network/test_agent_management_negative.py
+++ b/tempest/api/network/test_agent_management_negative.py
@@ -14,15 +14,28 @@
 #    under the License.
 
 from tempest.api.network import base
+from tempest import config
 from tempest.lib import decorators
 
+CONF = config.CONF
+
 
 class AgentManagementNegativeTest(base.BaseNetworkTest):
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(AgentManagementNegativeTest, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.network_agents_client
+        else:
+            cls.reader_client = cls.agents_client
+
     @decorators.idempotent_id('e335be47-b9a1-46fd-be30-0874c0b751e6')
     @decorators.attr(type=['negative'])
     def test_list_agents_non_admin(self):
         """Validate that non-admin user cannot list agents."""
         # Listing agents requires admin_only permissions.
-        body = self.agents_client.list_agents()
+        body = self.reader_client.list_agents()
         self.assertEmpty(body["agents"])
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index 58160e0..4570b18 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -39,6 +39,7 @@
 
         api_extensions
     """
+    credentials = ['primary', 'project_reader']
 
     @classmethod
     def skip_checks(cls):
@@ -48,6 +49,14 @@
             raise cls.skipException(msg)
 
     @classmethod
+    def setup_clients(cls):
+        super(AllowedAddressPairTestJSON, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.ports_client
+        else:
+            cls.reader_client = cls.ports_client
+
+    @classmethod
     def resource_setup(cls):
         super(AllowedAddressPairTestJSON, cls).resource_setup()
         cls.network = cls.create_network()
@@ -73,7 +82,7 @@
                         self.ports_client.delete_port, port_id)
 
         # Confirm port was created with allowed address pair attribute
-        body = self.ports_client.list_ports()
+        body = self.reader_client.list_ports()
         ports = body['ports']
         port = [p for p in ports if p['id'] == port_id]
         msg = 'Created port not found in list of ports returned by Neutron'
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index fee6af5..eaead8a 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -41,6 +41,8 @@
         addressing in subnets with router
     """
 
+    credentials = ['primary', 'project_reader']
+
     @classmethod
     def skip_checks(cls):
         super(NetworksTestDHCPv6, cls).skip_checks()
@@ -53,6 +55,18 @@
             raise cls.skipException(msg)
 
     @classmethod
+    def setup_clients(cls):
+        super(NetworksTestDHCPv6, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_ports_client = cls.os_project_reader.ports_client
+            cls.reader_subnets_client = cls.os_project_reader.subnets_client
+            cls.reader_routers_client = cls.os_project_reader.routers_client
+        else:
+            cls.reader_ports_client = cls.ports_client
+            cls.reader_subnets_client = cls.subnets_client
+            cls.reader_routers_client = cls.routers_client
+
+    @classmethod
     def resource_setup(cls):
         super(NetworksTestDHCPv6, cls).resource_setup()
         cls.network = cls.create_network()
@@ -67,7 +81,7 @@
         del things_list[index]
 
     def _clean_network(self):
-        body = self.ports_client.list_ports()
+        body = self.reader_ports_client.list_ports()
         ports = body['ports']
         for port in ports:
             if (net_info.is_router_interface_port(port) and
@@ -78,13 +92,13 @@
                 if port['id'] in [p['id'] for p in self.ports]:
                     self.ports_client.delete_port(port['id'])
                     self._remove_from_list_by_index(self.ports, port)
-        body = self.subnets_client.list_subnets()
+        body = self.reader_subnets_client.list_subnets()
         subnets = body['subnets']
         for subnet in subnets:
             if subnet['id'] in [s['id'] for s in self.subnets]:
                 self.subnets_client.delete_subnet(subnet['id'])
                 self._remove_from_list_by_index(self.subnets, subnet)
-        body = self.routers_client.list_routers()
+        body = self.reader_routers_client.list_routers()
         routers = body['routers']
         for router in routers:
             if router['id'] in [r['id'] for r in self.routers]:
@@ -221,7 +235,7 @@
                                                          subnet_slaac]]
                 self.ports_client.delete_port(port['id'])
                 self.ports.pop()
-                body = self.ports_client.list_ports()
+                body = self.reader_ports_client.list_ports()
                 ports_id_list = [i['id'] for i in body['ports']]
                 self.assertNotIn(port['id'], ports_id_list)
                 self._clean_network()
@@ -398,7 +412,7 @@
         self.routers.append(router)
         port = self.create_router_interface(router['id'],
                                             subnet['id'])
-        body = self.ports_client.show_port(port['port_id'])
+        body = self.reader_ports_client.show_port(port['port_id'])
         return subnet, body['port']
 
     @decorators.idempotent_id('e98f65db-68f4-4330-9fea-abd8c5192d4d')
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index e116d7c..98b2bb1 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -16,8 +16,11 @@
 
 from tempest.api.network import base
 from tempest.common import utils
+from tempest import config
 from tempest.lib import decorators
 
+CONF = config.CONF
+
 
 class ExtensionsTestJSON(base.BaseNetworkTest):
     """Tests the following operations in the Neutron API:
@@ -29,6 +32,16 @@
     etc/tempest.conf.
     """
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(ExtensionsTestJSON, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.network_extensions_client
+        else:
+            cls.reader_client = cls.network_extensions_client
+
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('ef28c7e6-e646-4979-9d67-deb207bc5564')
     def test_list_show_extensions(self):
@@ -42,14 +55,14 @@
         expected_alias = [ext for ext in expected_alias if
                           utils.is_extension_enabled(ext, 'network')]
         actual_alias = list()
-        extensions = self.network_extensions_client.list_extensions()
+        extensions = self.reader_client.list_extensions()
         list_extensions = extensions['extensions']
         # Show and verify the details of the available extensions
         for ext in list_extensions:
             ext_name = ext['name']
             ext_alias = ext['alias']
             actual_alias.append(ext['alias'])
-            ext_details = self.network_extensions_client.show_extension(
+            ext_details = self.reader_client.show_extension(
                 ext_alias)
             ext_details = ext_details['extension']
 
diff --git a/tempest/api/network/test_extra_dhcp_options.py b/tempest/api/network/test_extra_dhcp_options.py
index 36578b1..5ff43a7 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -36,6 +36,8 @@
     section of etc/tempest.conf
     """
 
+    credentials = ['primary', 'project_reader']
+
     @classmethod
     def skip_checks(cls):
         super(ExtraDHCPOptionsTestJSON, cls).skip_checks()
@@ -44,6 +46,14 @@
             raise cls.skipException(msg)
 
     @classmethod
+    def setup_clients(cls):
+        super(ExtraDHCPOptionsTestJSON, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_ports_client = cls.os_project_reader.ports_client
+        else:
+            cls.reader_ports_client = cls.ports_client
+
+    @classmethod
     def resource_setup(cls):
         super(ExtraDHCPOptionsTestJSON, cls).resource_setup()
         cls.network = cls.create_network()
@@ -72,7 +82,7 @@
                         self.ports_client.delete_port, port_id)
 
         # Confirm port created has Extra DHCP Options
-        body = self.ports_client.list_ports()
+        body = self.reader_ports_client.list_ports()
         ports = body['ports']
         port = [p for p in ports if p['id'] == port_id]
         self.assertTrue(port)
@@ -88,7 +98,7 @@
             name=name,
             extra_dhcp_opts=self.extra_dhcp_opts)
         # Confirm extra dhcp options were added to the port
-        body = self.ports_client.show_port(self.port['id'])
+        body = self.reader_ports_client.show_port(self.port['id'])
         self._confirm_extra_dhcp_options(body['port'], self.extra_dhcp_opts)
 
     def _confirm_extra_dhcp_options(self, port, extra_dhcp_opts):
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 07f0903..799bce3 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -42,6 +42,8 @@
         public_network_id which is the id for the external network present
     """
 
+    credentials = ['primary', 'project_reader']
+
     @classmethod
     def skip_checks(cls):
         super(FloatingIPTestJSON, cls).skip_checks()
@@ -55,6 +57,14 @@
             raise cls.skipException("Floating ips are not available")
 
     @classmethod
+    def setup_clients(cls):
+        super(FloatingIPTestJSON, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.floating_ips_client
+        else:
+            cls.reader_client = cls.floating_ips_client
+
+    @classmethod
     def resource_setup(cls):
         super(FloatingIPTestJSON, cls).resource_setup()
         cls.ext_net_id = CONF.network.public_network_id
@@ -92,7 +102,7 @@
         self.assertIn(created_floating_ip['fixed_ip_address'],
                       [ip['ip_address'] for ip in self.ports[0]['fixed_ips']])
         # Verifies the details of a floating_ip
-        floating_ip = self.floating_ips_client.show_floatingip(
+        floating_ip = self.reader_client.show_floatingip(
             created_floating_ip['id'])
         shown_floating_ip = floating_ip['floatingip']
         self.assertEqual(shown_floating_ip['id'], created_floating_ip['id'])
@@ -105,7 +115,7 @@
         self.assertEqual(shown_floating_ip['port_id'], self.ports[0]['id'])
 
         # Verify the floating ip exists in the list of all floating_ips
-        floating_ips = self.floating_ips_client.list_floatingips()
+        floating_ips = self.reader_client.list_floatingips()
         floatingip_id_list = list()
         for f in floating_ips['floatingips']:
             floatingip_id_list.append(f['id'])
@@ -162,7 +172,7 @@
         # Delete port
         self.ports_client.delete_port(created_port['id'])
         # Verifies the details of the floating_ip
-        floating_ip = self.floating_ips_client.show_floatingip(
+        floating_ip = self.reader_client.show_floatingip(
             created_floating_ip['id'])
         shown_floating_ip = floating_ip['floatingip']
         # Confirm the fields are back to None
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index b1fba2d..ff02e80 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -155,6 +155,24 @@
         project_network_v6_mask_bits is the equivalent for ipv6 subnets
     """
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(NetworksTest, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_networks_client = cls.os_project_reader.networks_client
+            cls.reader_ports_client = cls.os_project_reader.ports_client
+            cls.reader_subnets_client = cls.os_project_reader.subnets_client
+            cls.reader_network_extensions_client = (
+                cls.os_project_reader.network_extensions_client)
+        else:
+            cls.reader_networks_client = cls.networks_client
+            cls.reader_ports_client = cls.ports_client
+            cls.reader_subnets_client = cls.subnets_client
+            cls.reader_network_extensions_client = (
+                cls.network_extensions_client)
+
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
     def test_create_update_delete_network_subnet(self):
@@ -185,7 +203,7 @@
     @decorators.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
     def test_show_network(self):
         """Verify the details of a network"""
-        body = self.networks_client.show_network(self.network['id'])
+        body = self.reader_networks_client.show_network(self.network['id'])
         network = body['network']
         for key in ['id', 'name']:
             self.assertEqual(network[key], self.network[key])
@@ -196,8 +214,8 @@
         fields = ['id', 'name']
         if utils.is_extension_enabled('net-mtu', 'network'):
             fields.append('mtu')
-        body = self.networks_client.show_network(self.network['id'],
-                                                 fields=fields)
+        body = self.reader_networks_client.show_network(self.network['id'],
+                                                        fields=fields)
         network = body['network']
         self.assertEqual(sorted(network.keys()), sorted(fields))
         for field_name in fields:
@@ -209,7 +227,7 @@
     @decorators.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
     def test_list_networks(self):
         """Verify the network exists in the list of all networks"""
-        body = self.networks_client.list_networks()
+        body = self.reader_networks_client.list_networks()
         networks = [network['id'] for network in body['networks']
                     if network['id'] == self.network['id']]
         self.assertNotEmpty(networks, "Created network not found in the list")
@@ -220,7 +238,7 @@
         fields = ['id', 'name']
         if utils.is_extension_enabled('net-mtu', 'network'):
             fields.append('mtu')
-        body = self.networks_client.list_networks(fields=fields)
+        body = self.reader_networks_client.list_networks(fields=fields)
         networks = body['networks']
         self.assertNotEmpty(networks, "Network list returned is empty")
         for network in networks:
@@ -230,7 +248,7 @@
     @decorators.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
     def test_show_subnet(self):
         """Verify the details of a subnet"""
-        body = self.subnets_client.show_subnet(self.subnet['id'])
+        body = self.reader_subnets_client.show_subnet(self.subnet['id'])
         subnet = body['subnet']
         self.assertNotEmpty(subnet, "Subnet returned has no fields")
         for key in ['id', 'cidr']:
@@ -241,8 +259,8 @@
     def test_show_subnet_fields(self):
         """Verify specific fields of a subnet"""
         fields = ['id', 'network_id']
-        body = self.subnets_client.show_subnet(self.subnet['id'],
-                                               fields=fields)
+        body = self.reader_subnets_client.show_subnet(self.subnet['id'],
+                                                      fields=fields)
         subnet = body['subnet']
         self.assertEqual(sorted(subnet.keys()), sorted(fields))
         for field_name in fields:
@@ -252,7 +270,7 @@
     @decorators.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
     def test_list_subnets(self):
         """Verify the subnet exists in the list of all subnets"""
-        body = self.subnets_client.list_subnets()
+        body = self.reader_subnets_client.list_subnets()
         subnets = [subnet['id'] for subnet in body['subnets']
                    if subnet['id'] == self.subnet['id']]
         self.assertNotEmpty(subnets, "Created subnet not found in the list")
@@ -261,7 +279,7 @@
     def test_list_subnets_fields(self):
         """Verify specific fields of subnets"""
         fields = ['id', 'network_id']
-        body = self.subnets_client.list_subnets(fields=fields)
+        body = self.reader_subnets_client.list_subnets(fields=fields)
         subnets = body['subnets']
         self.assertNotEmpty(subnets, "Subnet list returned is empty")
         for subnet in subnets:
@@ -284,7 +302,8 @@
         self.networks_client.delete_network(net_id)
 
         # Verify that the subnet got automatically deleted.
-        self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
+        self.assertRaises(lib_exc.NotFound,
+                          self.reader_subnets_client.show_subnet,
                           subnet_id)
 
     @decorators.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
@@ -373,7 +392,8 @@
         public_network_id = CONF.network.public_network_id
 
         # find external network matching public_network_id
-        body = self.networks_client.list_networks(**{'router:external': True})
+        body = self.reader_networks_client.list_networks(
+            **{'router:external': True})
         external_network = next((network for network in body['networks']
                                  if network['id'] == public_network_id), None)
         self.assertIsNotNone(external_network, "Public network %s not found "
@@ -388,10 +408,12 @@
         # only check the public network ID because the other networks may
         # belong to other tests and their state may have changed during this
         # test
-        body = self.subnets_client.list_subnets(network_id=public_network_id)
+        body = self.reader_subnets_client.list_subnets(
+            network_id=public_network_id)
         extensions = [
             ext['alias'] for ext in
-            self.network_extensions_client.list_extensions()['extensions']]
+            self.reader_network_extensions_client.list_extensions()[
+                'extensions']]
         is_sen_ext = 'subnet-external-network' in extensions
 
         # check subnet visibility of external_network
@@ -412,12 +434,14 @@
         body = self.create_network(description='d1')
         self.assertEqual('d1', body['description'])
         net_id = body['id']
-        body = self.networks_client.list_networks(id=net_id)['networks'][0]
+        body = self.reader_networks_client.list_networks(
+            id=net_id)['networks'][0]
         self.assertEqual('d1', body['description'])
         body = self.networks_client.update_network(body['id'],
                                                    description='d2')
         self.assertEqual('d2', body['network']['description'])
-        body = self.networks_client.list_networks(id=net_id)['networks'][0]
+        body = self.reader_networks_client.list_networks(
+            id=net_id)['networks'][0]
         self.assertEqual('d2', body['description'])
 
 
@@ -439,11 +463,25 @@
         the block defined by project-network_cidr
     """
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(BulkNetworkOpsTest, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_networks_client = cls.os_project_reader.networks_client
+            cls.reader_ports_client = cls.os_project_reader.ports_client
+            cls.reader_subnets_client = cls.os_project_reader.subnets_client
+        else:
+            cls.reader_networks_client = cls.networks_client
+            cls.reader_ports_client = cls.ports_client
+            cls.reader_subnets_client = cls.subnets_client
+
     def _delete_networks(self, created_networks):
         for n in created_networks:
             self.networks_client.delete_network(n['id'])
         # Asserting that the networks are not found in the list after deletion
-        body = self.networks_client.list_networks()
+        body = self.reader_networks_client.list_networks()
         networks_list = [network['id'] for network in body['networks']]
         for n in created_networks:
             self.assertNotIn(n['id'], networks_list)
@@ -452,7 +490,7 @@
         for n in created_subnets:
             self.subnets_client.delete_subnet(n['id'])
         # Asserting that the subnets are not found in the list after deletion
-        body = self.subnets_client.list_subnets()
+        body = self.reader_subnets_client.list_subnets()
         subnets_list = [subnet['id'] for subnet in body['subnets']]
         for n in created_subnets:
             self.assertNotIn(n['id'], subnets_list)
@@ -461,7 +499,7 @@
         for n in created_ports:
             self.ports_client.delete_port(n['id'])
         # Asserting that the ports are not found in the list after deletion
-        body = self.ports_client.list_ports()
+        body = self.reader_ports_client.list_ports()
         ports_list = [port['id'] for port in body['ports']]
         for n in created_ports:
             self.assertNotIn(n['id'], ports_list)
@@ -480,7 +518,7 @@
         created_networks = body['networks']
         self.addCleanup(self._delete_networks, created_networks)
         # Asserting that the networks are found in the list after creation
-        body = self.networks_client.list_networks()
+        body = self.reader_networks_client.list_networks()
         networks_list = [network['id'] for network in body['networks']]
         for n in created_networks:
             self.assertIsNotNone(n['id'])
@@ -512,7 +550,7 @@
         created_subnets = body['subnets']
         self.addCleanup(self._delete_subnets, created_subnets)
         # Asserting that the subnets are found in the list after creation
-        body = self.subnets_client.list_subnets()
+        body = self.reader_subnets_client.list_subnets()
         subnets_list = [subnet['id'] for subnet in body['subnets']]
         for n in created_subnets:
             self.assertIsNotNone(n['id'])
@@ -541,7 +579,7 @@
         created_ports = body['ports']
         self.addCleanup(self._delete_ports, created_ports)
         # Asserting that the ports are found in the list after creation
-        body = self.ports_client.list_ports()
+        body = self.reader_ports_client.list_ports()
         ports_list = [port['id'] for port in body['ports']]
         for n in created_ports:
             self.assertIsNotNone(n['id'])
@@ -555,6 +593,16 @@
 class NetworksIpV6Test(NetworksTest):
     _ip_version = 6
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(NetworksIpV6Test, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_subnets_client = cls.os_project_reader.subnets_client
+        else:
+            cls.reader_subnets_client = cls.subnets_client
+
     @decorators.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
     def test_create_delete_subnet_with_gw(self):
         """Verify creating and deleting subnet with gateway"""
@@ -600,7 +648,7 @@
         # Verifies Subnet GW is None in IPv4
         self.assertIsNone(subnet2['gateway_ip'])
         # Verifies all 2 subnets in the same network
-        body = self.subnets_client.list_subnets()
+        body = self.reader_subnets_client.list_subnets()
         subnets = [sub['id'] for sub in body['subnets']
                    if sub['network_id'] == network['id']]
         test_subnet_ids = [sub['id'] for sub in (subnet1, subnet2)]
@@ -613,6 +661,16 @@
 
     _ip_version = 6
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(NetworksIpV6TestAttrs, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_subnets_client = cls.os_project_reader.subnets_client
+        else:
+            cls.reader_subnets_client = cls.subnets_client
+
     @classmethod
     def skip_checks(cls):
         super(NetworksIpV6TestAttrs, cls).skip_checks()
@@ -651,7 +709,7 @@
         port = self.create_port(slaac_network)
         self.assertIsNotNone(port['fixed_ips'][0]['ip_address'])
         self.subnets_client.delete_subnet(subnet_slaac['id'])
-        subnets = self.subnets_client.list_subnets()
+        subnets = self.reader_subnets_client.list_subnets()
         subnet_ids = [subnet['id'] for subnet in subnets['subnets']]
         self.assertNotIn(subnet_slaac['id'], subnet_ids,
                          "Subnet wasn't deleted")
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index 6c91df0..72655a3 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -26,12 +26,27 @@
 class NetworksNegativeTestJSON(base.BaseNetworkTest):
     """Negative tests of network"""
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(NetworksNegativeTestJSON, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_ports_client = cls.os_project_reader.ports_client
+            cls.reader_subnets_client = cls.os_project_reader.subnets_client
+            cls.reader_networks_client = cls.os_project_reader.networks_client
+        else:
+            cls.reader_ports_client = cls.ports_client
+            cls.reader_subnets_client = cls.subnets_client
+            cls.reader_networks_client = cls.networks_client
+
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('9293e937-824d-42d2-8d5b-e985ea67002a')
     def test_show_non_existent_network(self):
         """Test showing non existent network"""
         non_exist_id = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.networks_client.show_network,
+        self.assertRaises(lib_exc.NotFound,
+                          self.reader_networks_client.show_network,
                           non_exist_id)
 
     @decorators.attr(type=['negative'])
@@ -39,7 +54,8 @@
     def test_show_non_existent_subnet(self):
         """Test showing non existent subnet"""
         non_exist_id = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
+        self.assertRaises(lib_exc.NotFound,
+                          self.reader_subnets_client.show_subnet,
                           non_exist_id)
 
     @decorators.attr(type=['negative'])
@@ -47,7 +63,8 @@
     def test_show_non_existent_port(self):
         """Test showing non existent port"""
         non_exist_id = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.NotFound, self.ports_client.show_port,
+        self.assertRaises(lib_exc.NotFound,
+                          self.reader_ports_client.show_port,
                           non_exist_id)
 
     @decorators.attr(type=['negative'])
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 02faa59..82de7e3 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -40,6 +40,16 @@
         port update
     """
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(PortsTestJSON, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.ports_client
+        else:
+            cls.reader_client = cls.ports_client
+
     @classmethod
     def resource_setup(cls):
         super(PortsTestJSON, cls).resource_setup()
@@ -48,7 +58,7 @@
 
     def _delete_port(self, port_id):
         self.ports_client.delete_port(port_id)
-        body = self.ports_client.list_ports()
+        body = self.reader_client.list_ports()
         ports_list = body['ports']
         self.assertFalse(port_id in [n['id'] for n in ports_list])
 
@@ -153,7 +163,7 @@
     @decorators.idempotent_id('c9a685bd-e83f-499c-939f-9f7863ca259f')
     def test_show_port(self):
         """Verify the details of port"""
-        body = self.ports_client.show_port(self.port['id'])
+        body = self.reader_client.show_port(self.port['id'])
         port = body['port']
         self.assertIn('id', port)
         # NOTE(rfolco): created_at and updated_at may get inconsistent values
@@ -170,8 +180,8 @@
     def test_show_port_fields(self):
         """Verify specific fields of a port"""
         fields = ['id', 'mac_address']
-        body = self.ports_client.show_port(self.port['id'],
-                                           fields=fields)
+        body = self.reader_client.show_port(self.port['id'],
+                                            fields=fields)
         port = body['port']
         self.assertEqual(sorted(port.keys()), sorted(fields))
         for field_name in fields:
@@ -181,7 +191,7 @@
     @decorators.idempotent_id('cf95b358-3e92-4a29-a148-52445e1ac50e')
     def test_list_ports(self):
         """Verify the port exists in the list of all ports"""
-        body = self.ports_client.list_ports()
+        body = self.reader_client.list_ports()
         ports = [port['id'] for port in body['ports']
                  if port['id'] == self.port['id']]
         self.assertNotEmpty(ports, "Created port not found in the list")
@@ -212,7 +222,7 @@
         # List ports filtered by fixed_ips
         port_1_fixed_ip = port_1['port']['fixed_ips'][0]['ip_address']
         fixed_ips = 'ip_address=' + port_1_fixed_ip
-        port_list = self.ports_client.list_ports(fixed_ips=fixed_ips)
+        port_list = self.reader_client.list_ports(fixed_ips=fixed_ips)
         # Check that we got the desired port
         ports = port_list['ports']
         project_ids = set([port['project_id'] for port in ports])
@@ -281,7 +291,7 @@
             ips_filter = 'ip_address_substr=' + ip_address_1[:-1]
         else:
             ips_filter = 'ip_address_substr=' + ip_address_1
-        ports = self.ports_client.list_ports(fixed_ips=ips_filter)['ports']
+        ports = self.reader_client.list_ports(fixed_ips=ips_filter)['ports']
         # Check that we got the desired port
         port_ids = [port['id'] for port in ports]
         fixed_ips = [port['fixed_ips'] for port in ports]
@@ -302,7 +312,7 @@
         while substr not in ip_address_2:
             substr = substr[:-1]
         ips_filter = 'ip_address_substr=' + substr
-        ports = self.ports_client.list_ports(fixed_ips=ips_filter)['ports']
+        ports = self.reader_client.list_ports(fixed_ips=ips_filter)['ports']
         # Check that we got both port
         port_ids = [port['id'] for port in ports]
         fixed_ips = [port['fixed_ips'] for port in ports]
@@ -339,7 +349,7 @@
                         self.routers_client.remove_router_interface,
                         router['id'], port_id=port['port']['id'])
         # List ports filtered by router_id
-        port_list = self.ports_client.list_ports(device_id=router['id'])
+        port_list = self.reader_client.list_ports(device_id=router['id'])
         ports = port_list['ports']
         self.assertEqual(len(ports), 1)
         self.assertEqual(ports[0]['id'], port['port']['id'])
@@ -349,7 +359,7 @@
     def test_list_ports_fields(self):
         """Verify specific fields of ports"""
         fields = ['id', 'mac_address']
-        body = self.ports_client.list_ports(fields=fields)
+        body = self.reader_client.list_ports(fields=fields)
         ports = body['ports']
         self.assertNotEmpty(ports, "Port list returned is empty")
         # Asserting the fields returned are correct
@@ -501,7 +511,7 @@
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.ports_client.delete_port, body['port']['id'])
         port = body['port']
-        body = self.ports_client.show_port(port['id'])
+        body = self.reader_client.show_port(port['id'])
         show_port = body['port']
         self.assertEqual(free_mac_address,
                          show_port['mac_address'])
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index fedf2f4..9e5a604 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -37,6 +37,18 @@
         self.assertEqual(subnet_id, interface['subnet_id'])
         return interface
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(RoutersTest, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_routers_client = cls.os_project_reader.routers_client
+            cls.reader_ports_client = cls.os_project_reader.ports_client
+        else:
+            cls.reader_routers_client = cls.routers_client
+            cls.reader_ports_client = cls.ports_client
+
     @classmethod
     def skip_checks(cls):
         super(RoutersTest, cls).skip_checks()
@@ -65,7 +77,7 @@
             router['external_gateway_info']['network_id'],
             CONF.network.public_network_id)
         # Show details of the created router
-        router_show = self.routers_client.show_router(
+        router_show = self.reader_routers_client.show_router(
             router['id'])['router']
         self.assertEqual(router_show['name'], router['name'])
         self.assertEqual(
@@ -79,7 +91,7 @@
         router_update = self.routers_client.update_router(
             router['id'], name=updated_name)['router']
         self.assertEqual(router_update['name'], updated_name)
-        router_show = self.routers_client.show_router(
+        router_show = self.reader_routers_client.show_router(
             router['id'])['router']
         self.assertEqual(router_show['name'], updated_name)
 
@@ -107,7 +119,7 @@
         self.assertIn('subnet_id', interface.keys())
         self.assertIn('port_id', interface.keys())
         # Verify router id is equal to device id in port details
-        show_port_body = self.ports_client.show_port(
+        show_port_body = self.reader_ports_client.show_port(
             interface['port_id'])
         self.assertEqual(show_port_body['port']['device_id'],
                          router['id'])
@@ -140,7 +152,7 @@
         self.assertIn('subnet_id', interface.keys())
         self.assertIn('port_id', interface.keys())
         # Verify router id is equal to device id in port details
-        show_port_body = self.ports_client.show_port(
+        show_port_body = self.reader_ports_client.show_port(
             interface['port_id'])
         self.assertEqual(show_port_body['port']['device_id'],
                          router['id'])
@@ -194,7 +206,7 @@
         test_routes.sort(key=lambda x: x['destination'])
         extra_route = self.routers_client.update_router(
             router['id'], routes=test_routes)
-        show_body = self.routers_client.show_router(router['id'])
+        show_body = self.reader_routers_client.show_router(router['id'])
         # Assert the number of routes
         self.assertEqual(routes_num, len(extra_route['router']['routes']))
         self.assertEqual(routes_num, len(show_body['router']['routes']))
@@ -215,7 +227,7 @@
             self.assertEqual(test_routes[i]['nexthop'], routes[i]['nexthop'])
 
         self._delete_extra_routes(router['id'])
-        show_body_after_deletion = self.routers_client.show_router(
+        show_body_after_deletion = self.reader_routers_client.show_router(
             router['id'])
         self.assertEmpty(show_body_after_deletion['router']['routes'])
 
@@ -232,7 +244,7 @@
         update_body = self.routers_client.update_router(router['id'],
                                                         admin_state_up=True)
         self.assertTrue(update_body['router']['admin_state_up'])
-        show_body = self.routers_client.show_router(router['id'])
+        show_body = self.reader_routers_client.show_router(router['id'])
         self.assertTrue(show_body['router']['admin_state_up'])
 
     @decorators.attr(type='smoke')
@@ -288,7 +300,7 @@
                                                               subnet['id'])
         self.assertIn('port_id', interface)
         self.assertIn('subnet_id', interface)
-        port = self.ports_client.show_port(interface['port_id'])
+        port = self.reader_ports_client.show_port(interface['port_id'])
         self.assertEqual(port['port']['id'], interface['port_id'])
         router_port = self.ports_client.update_port(port['port']['id'],
                                                     fixed_ips=fixed_ip)
@@ -296,7 +308,7 @@
                          router_port['port']['fixed_ips'][0]['subnet_id'])
 
     def _verify_router_interface(self, router_id, subnet_id, port_id):
-        show_port_body = self.ports_client.show_port(port_id)
+        show_port_body = self.reader_ports_client.show_port(port_id)
         interface_port = show_port_body['port']
         self.assertEqual(router_id, interface_port['device_id'])
         self.assertEqual(subnet_id,
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index 299e0e9..5b06016 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -26,6 +26,16 @@
 class RoutersNegativeTest(base.BaseNetworkTest):
     """Negative tests of routers"""
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(RoutersNegativeTest, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.routers_client
+        else:
+            cls.reader_client = cls.routers_client
+
     @classmethod
     def skip_checks(cls):
         super(RoutersNegativeTest, cls).skip_checks()
@@ -105,7 +115,7 @@
         """Test showing non existent router"""
         router = data_utils.rand_name(
             name='non_exist_router', prefix=CONF.resource_name_prefix)
-        self.assertRaises(lib_exc.NotFound, self.routers_client.show_router,
+        self.assertRaises(lib_exc.NotFound, self.reader_client.show_router,
                           router)
 
     @decorators.attr(type=['negative'])
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index c7f6b8f..b60abac 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -26,6 +26,21 @@
 class SecGroupTest(base.BaseSecGroupTest):
     """Test security groups"""
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(SecGroupTest, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_security_groups_client = (
+                cls.os_project_reader.security_groups_client)
+            cls.reader_security_group_rules_client = (
+                cls.os_project_reader.security_group_rules_client)
+        else:
+            cls.reader_security_groups_client = cls.security_groups_client
+            cls.reader_security_group_rules_client = (
+                cls.security_group_rules_client)
+
     @classmethod
     def skip_checks(cls):
         super(SecGroupTest, cls).skip_checks()
@@ -72,7 +87,7 @@
     @decorators.idempotent_id('e30abd17-fef9-4739-8617-dc26da88e686')
     def test_list_security_groups(self):
         """Verify that default security group exist"""
-        body = self.security_groups_client.list_security_groups()
+        body = self.reader_security_groups_client.list_security_groups()
         security_groups = body['security_groups']
         found = None
         for n in security_groups:
@@ -88,7 +103,7 @@
         group_create_body, _ = self._create_security_group()
 
         # List security groups and verify if created group is there in response
-        list_body = self.security_groups_client.list_security_groups()
+        list_body = self.reader_security_groups_client.list_security_groups()
         secgroup_list = list()
         for secgroup in list_body['security_groups']:
             secgroup_list.append(secgroup['id'])
@@ -106,7 +121,7 @@
         self.assertEqual(update_body['security_group']['description'],
                          new_description)
         # Show details of the updated security group
-        show_body = self.security_groups_client.show_security_group(
+        show_body = self.reader_security_groups_client.show_security_group(
             group_create_body['security_group']['id'])
         self.assertEqual(show_body['security_group']['name'], new_name)
         self.assertEqual(show_body['security_group']['description'],
@@ -136,7 +151,8 @@
 
         # List rules and verify created rule is not in response
         rule_list_body = (
-            self.security_group_rules_client.list_security_group_rules())
+            self.reader_security_group_rules_client
+            .list_security_group_rules())
         rule_list = [rule['id']
                      for rule in rule_list_body['security_group_rules']]
         self.assertNotIn(rule_id, rule_list)
@@ -170,7 +186,8 @@
 
             # List rules and verify created rule is in response
             rule_list_body = (
-                self.security_group_rules_client.list_security_group_rules())
+                self.reader_security_group_rules_client
+                .list_security_group_rules())
             rule_list = [rule['id']
                          for rule in rule_list_body['security_group_rules']]
             self.assertIn(rule_create_body['security_group_rule']['id'],
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index beaeb20..7f68f52 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -26,6 +26,21 @@
 class NegativeSecGroupTest(base.BaseSecGroupTest):
     """Negative tests of security groups"""
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(NegativeSecGroupTest, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_security_groups_client = (
+                cls.os_project_reader.security_groups_client)
+            cls.reader_security_group_rules_client = (
+                cls.os_project_reader.security_group_rules_client)
+        else:
+            cls.reader_security_groups_client = cls.security_groups_client
+            cls.reader_security_group_rules_client = (
+                cls.security_group_rules_client)
+
     @classmethod
     def skip_checks(cls):
         super(NegativeSecGroupTest, cls).skip_checks()
@@ -39,7 +54,8 @@
         """Test showing non existent security group"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(
-            lib_exc.NotFound, self.security_groups_client.show_security_group,
+            lib_exc.NotFound,
+            self.reader_security_groups_client.show_security_group,
             non_exist_id)
 
     @decorators.attr(type=['negative'])
@@ -49,7 +65,7 @@
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(
             lib_exc.NotFound,
-            self.security_group_rules_client.show_security_group_rule,
+            self.reader_security_group_rules_client.show_security_group_rule,
             non_exist_id)
 
     @decorators.attr(type=['negative'])
diff --git a/tempest/api/network/test_service_providers.py b/tempest/api/network/test_service_providers.py
index e203a2c..6771392 100644
--- a/tempest/api/network/test_service_providers.py
+++ b/tempest/api/network/test_service_providers.py
@@ -12,12 +12,25 @@
 
 from tempest.api.network import base
 from tempest.common import utils
+from tempest import config
 from tempest.lib import decorators
 
+CONF = config.CONF
+
 
 class ServiceProvidersTest(base.BaseNetworkTest):
     """Test network service providers"""
 
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(ServiceProvidersTest, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.service_providers_client
+        else:
+            cls.reader_client = cls.service_providers_client
+
     @classmethod
     def skip_checks(cls):
         super(ServiceProvidersTest, cls).skip_checks()
@@ -28,6 +41,6 @@
     @decorators.idempotent_id('2cbbeea9-f010-40f6-8df5-4eaa0c918ea6')
     def test_service_providers_list(self):
         """Test listing network service providers"""
-        body = self.service_providers_client.list_service_providers()
+        body = self.reader_client.list_service_providers()
         self.assertIn('service_providers', body)
         self.assertIsInstance(body['service_providers'], list)
diff --git a/tempest/api/network/test_subnetpools_extensions.py b/tempest/api/network/test_subnetpools_extensions.py
index 689844b..bd20358 100644
--- a/tempest/api/network/test_subnetpools_extensions.py
+++ b/tempest/api/network/test_subnetpools_extensions.py
@@ -39,6 +39,8 @@
 
     """
 
+    credentials = ['primary', 'project_reader']
+
     @classmethod
     def skip_checks(cls):
         super(SubnetPoolsTestJSON, cls).skip_checks()
@@ -46,6 +48,14 @@
             msg = "subnet_allocation extension not enabled."
             raise cls.skipException(msg)
 
+    @classmethod
+    def setup_clients(cls):
+        super(SubnetPoolsTestJSON, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.subnetpools_client
+        else:
+            cls.reader_client = cls.subnetpools_client
+
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e9811')
     def test_create_list_show_update_delete_subnetpools(self):
@@ -62,7 +72,7 @@
                         subnetpool_id)
         self.assertEqual(subnetpool_name, body["subnetpool"]["name"])
         # get detail about subnet pool
-        body = self.subnetpools_client.show_subnetpool(subnetpool_id)
+        body = self.reader_client.show_subnetpool(subnetpool_id)
         self.assertEqual(subnetpool_name, body["subnetpool"]["name"])
         # update the subnet pool
         subnetpool_name = data_utils.rand_name(
@@ -73,5 +83,5 @@
         # delete subnet pool
         body = self.subnetpools_client.delete_subnetpool(subnetpool_id)
         self.assertRaises(lib_exc.NotFound,
-                          self.subnetpools_client.show_subnetpool,
+                          self.reader_client.show_subnetpool,
                           subnetpool_id)
diff --git a/tempest/api/network/test_tags.py b/tempest/api/network/test_tags.py
index a0c6342..527b745 100644
--- a/tempest/api/network/test_tags.py
+++ b/tempest/api/network/test_tags.py
@@ -37,6 +37,8 @@
     tags on their networks. The extension supports networks only.
     """
 
+    credentials = ['primary', 'project_reader']
+
     @classmethod
     def skip_checks(cls):
         super(TagsTest, cls).skip_checks()
@@ -45,6 +47,14 @@
             raise cls.skipException(msg)
 
     @classmethod
+    def setup_clients(cls):
+        super(TagsTest, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.tags_client
+        else:
+            cls.reader_client = cls.tags_client
+
+    @classmethod
     def resource_setup(cls):
         super(TagsTest, cls).resource_setup()
         cls.network = cls.create_network()
@@ -61,7 +71,7 @@
                                              tag_name)
 
         # Validate that listing tags on a network resource works.
-        retrieved_tags = self.tags_client.list_tags(
+        retrieved_tags = self.reader_client.list_tags(
             'networks', self.network['id'])['tags']
         self.assertEqual([tag_name], retrieved_tags)
 
@@ -115,6 +125,8 @@
     # the singular case for the corresponding class resource object.
     SUPPORTED_RESOURCES = ['subnets', 'ports', 'routers', 'subnetpools']
 
+    credentials = ['primary', 'project_reader']
+
     @classmethod
     def skip_checks(cls):
         super(TagsExtTest, cls).skip_checks()
@@ -127,6 +139,14 @@
             raise cls.skipException(msg)
 
     @classmethod
+    def setup_clients(cls):
+        super(TagsExtTest, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.tags_client
+        else:
+            cls.reader_client = cls.tags_client
+
+    @classmethod
     def resource_setup(cls):
         super(TagsExtTest, cls).resource_setup()
         cls.network = cls.create_network()
@@ -169,7 +189,7 @@
         for i, resource in enumerate(self.SUPPORTED_RESOURCES):
             # Ensure that a tag was created for each resource.
             resource_object = getattr(self, resource[:-1])
-            retrieved_tags = self.tags_client.list_tags(
+            retrieved_tags = self.reader_client.list_tags(
                 resource, resource_object['id'])['tags']
             self.assertEqual(1, len(retrieved_tags))
             self.assertEqual(tag_names[i], retrieved_tags[0])
@@ -181,7 +201,7 @@
             # Delete the tag and ensure it was deleted.
             self.tags_client.delete_tag(
                 resource, resource_object['id'], tag_names[i])
-            retrieved_tags = self.tags_client.list_tags(
+            retrieved_tags = self.reader_client.list_tags(
                 resource, resource_object['id'])['tags']
             self.assertEmpty(retrieved_tags)
 
diff --git a/tempest/api/network/test_versions.py b/tempest/api/network/test_versions.py
index 020cb5c..84add7a 100644
--- a/tempest/api/network/test_versions.py
+++ b/tempest/api/network/test_versions.py
@@ -13,10 +13,24 @@
 # under the License.
 
 from tempest.api.network import base
+from tempest import config
 from tempest.lib import decorators
 
+CONF = config.CONF
+
 
 class NetworksApiDiscovery(base.BaseNetworkTest):
+
+    credentials = ['primary', 'project_reader']
+
+    @classmethod
+    def setup_clients(cls):
+        super(NetworksApiDiscovery, cls).setup_clients()
+        if CONF.enforce_scope.neutron:
+            cls.reader_client = cls.os_project_reader.network_versions_client
+        else:
+            cls.reader_client = cls.network_versions_client
+
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('cac8a836-c2e0-4304-b556-cd299c7281d1')
     def test_api_version_resources(self):
@@ -28,7 +42,7 @@
         schema.
         """
 
-        result = self.network_versions_client.list_versions()
+        result = self.reader_client.list_versions()
         expected_versions = ('v2.0',)
         expected_resources = ('id', 'links', 'status')
         received_list = result.values()
@@ -45,7 +59,7 @@
         """Test that GET /v2.0/ returns expected resources."""
         current_version = 'v2.0'
         expected_resources = ('subnet', 'network', 'port')
-        result = self.network_versions_client.show_version(current_version)
+        result = self.reader_client.show_version(current_version)
         actual_resources = [r['name'] for r in result['resources']]
         for resource in expected_resources:
             self.assertIn(resource, actual_resources)
diff --git a/tempest/config.py b/tempest/config.py
index b81e13f..f0ed2ab 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1060,9 +1060,11 @@
                 help='Disk format to use when copying a volume to image'),
     cfg.IntOpt('volume_size',
                default=1,
+               min=1,
                help='Default size in GB for volumes created by volumes tests'),
     cfg.IntOpt('volume_size_extend',
                default=1,
+               min=1,
                help="Size in GB a volume is extended by - if a test "
                     "extends a volume, the size of the new volume will be "
                     "volume_size + volume_size_extend."),