Extend tests for new Domain Manager Persona

Adjusts existing tests and adds new tests to incorporate the new Domain
Manager Persona introduced in Keystone. Also adds tests for a Project Manager
Persona to serve as negative tests.

Depends-On: https://review.opendev.org/c/openstack/keystone/+/924132
Depends-On: https://review.opendev.org/c/openstack/tempest/+/924133
Change-Id: I5f0cf4d00ebda6715c610f1dc9b7d4bb15ccaba9
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_access_rule.py b/keystone_tempest_plugin/tests/rbac/v3/test_access_rule.py
index 25767fc..1bb5fc4 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_access_rule.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_access_rule.py
@@ -358,7 +358,12 @@
             access_rule_id=data_utils.rand_uuid_hex())
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -477,7 +482,12 @@
             access_rule_id=data_utils.rand_uuid_hex())
 
 
-class ProjectMemberTests(ProjectAdminTests):
+class ProjectManagerTests(ProjectAdminTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_application_credential.py b/keystone_tempest_plugin/tests/rbac/v3/test_application_credential.py
index 123e64b..dd20e31 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_application_credential.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_application_credential.py
@@ -401,7 +401,12 @@
             application_credential_id=data_utils.rand_uuid_hex())
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -416,10 +421,10 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(IdentityV3RbacApplicationCredentialTest,
-                         base.BaseIdentityTest):
+class ProjectManagerTests(IdentityV3RbacApplicationCredentialTest,
+                          base.BaseIdentityTest):
 
-    credentials = ['project_member', 'system_admin']
+    credentials = ['project_manager', 'system_admin']
 
     @classmethod
     def setup_clients(cls):
@@ -560,6 +565,11 @@
             application_credential_id=data_utils.rand_uuid_hex())
 
 
+class ProjectMemberTests(ProjectManagerTests):
+
+    credentials = ['project_member', 'system_admin']
+
+
 class ProjectReaderTests(ProjectMemberTests):
 
     credentials = ['project_reader', 'system_admin']
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_consumer.py b/keystone_tempest_plugin/tests/rbac/v3/test_consumer.py
index a04fcd9..8193da8 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_consumer.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_consumer.py
@@ -171,7 +171,12 @@
                         expected_status=exceptions.Forbidden)
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -186,7 +191,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_credential.py b/keystone_tempest_plugin/tests/rbac/v3/test_credential.py
index 0c70589..c3f8631 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_credential.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_credential.py
@@ -344,9 +344,9 @@
     credentials = ['domain_admin', 'system_admin']
 
 
-class DomainMemberTests(SystemReaderTests):
+class DomainManagerTests(SystemReaderTests):
 
-    credentials = ['domain_member', 'system_admin']
+    credentials = ['domain_manager', 'system_admin']
 
     def test_identity_get_credential(self):
         # user can get their own credential
@@ -391,6 +391,11 @@
             self.assertNotIn(cred['id'], [c['id'] for c in resp])
 
 
+class DomainMemberTests(DomainManagerTests):
+
+    credentials = ['domain_member', 'system_admin']
+
+
 class DomainReaderTests(DomainMemberTests):
 
     credentials = ['domain_reader', 'system_admin']
@@ -401,7 +406,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_domain.py b/keystone_tempest_plugin/tests/rbac/v3/test_domain.py
index b09b4bd..637f7ad 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_domain.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_domain.py
@@ -31,6 +31,7 @@
         cls.client = cls.persona.domains_client
         admin_client = cls.os_system_admin
         cls.admin_domains_client = admin_client.domains_client
+        cls.own_domain = cls.persona.credentials.domain_id
 
     @abc.abstractmethod
     def test_identity_create_domain(self):
@@ -189,7 +190,9 @@
         self.assertNotIn(other_domain_id, [d['id'] for d in resp['domains']])
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
 
     def test_identity_get_domain(self):
         domain_id = self.admin_domains_client.create_domain(
@@ -197,12 +200,18 @@
         self.addCleanup(self.admin_domains_client.delete_domain, domain_id)
         self.addCleanup(self.admin_domains_client.update_domain,
                         domain_id=domain_id, enabled=False)
+        # user can get own domain
+        self.do_request('show_domain', domain_id=self.own_domain)
+        # user gets a 403 for foreign domain
         self.do_request('show_domain', expected_status=exceptions.Forbidden,
                         domain_id=domain_id)
         # user gets a 403 for nonexistent domain
         self.do_request('show_domain', expected_status=exceptions.Forbidden,
                         domain_id=data_utils.rand_uuid_hex())
 
+
+class DomainMemberTests(DomainManagerTests):
+
     credentials = ['domain_member', 'system_admin']
 
 
@@ -216,9 +225,9 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
 
-    credentials = ['project_member', 'system_admin']
+    credentials = ['project_manager', 'system_admin']
 
     def test_identity_list_domains(self):
         domain_id = self.admin_domains_client.create_domain(
@@ -230,6 +239,11 @@
                         expected_status=exceptions.Forbidden)
 
 
+class ProjectMemberTests(ProjectManagerTests):
+
+    credentials = ['project_member', 'system_admin']
+
+
 class ProjectReaderTests(ProjectMemberTests):
 
     credentials = ['project_reader', 'system_admin']
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_domain_config.py b/keystone_tempest_plugin/tests/rbac/v3/test_domain_config.py
index ba2b612..ce900d3 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_domain_config.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_domain_config.py
@@ -356,7 +356,12 @@
             expected_status=exceptions.Forbidden, group='ldap', option='url')
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -371,7 +376,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_ec2_credential.py b/keystone_tempest_plugin/tests/rbac/v3/test_ec2_credential.py
index b9affc8..fa1ae32 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_ec2_credential.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_ec2_credential.py
@@ -464,7 +464,12 @@
             access=data_utils.rand_uuid_hex())
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -479,9 +484,9 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(SystemReaderTests):
+class ProjectManagerTests(SystemReaderTests):
 
-    credentials = ['project_member', 'system_admin']
+    credentials = ['project_manager', 'system_admin']
 
     def test_identity_ec2_get_credential(self):
         # user can get their own credential
@@ -539,6 +544,11 @@
                         user_id=self.test_user_2)
 
 
+class ProjectMemberTests(ProjectManagerTests):
+
+    credentials = ['project_member', 'system_admin']
+
+
 class ProjectReaderTests(ProjectMemberTests):
 
     credentials = ['project_reader', 'system_admin']
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_endpoint.py b/keystone_tempest_plugin/tests/rbac/v3/test_endpoint.py
index 8dde1ea..8894da1 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_endpoint.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_endpoint.py
@@ -220,7 +220,12 @@
         self.do_request('list_endpoints', expected_status=exceptions.Forbidden)
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -234,7 +239,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_endpoint_group.py b/keystone_tempest_plugin/tests/rbac/v3/test_endpoint_group.py
index 305b6e2..258c38a 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_endpoint_group.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_endpoint_group.py
@@ -496,7 +496,12 @@
                         project_id=project)
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -511,7 +516,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_grant.py b/keystone_tempest_plugin/tests/rbac/v3/test_grant.py
index 5e1a501..3681b9c 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_grant.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_grant.py
@@ -44,6 +44,8 @@
             name=data_utils.rand_name('role'))['role']['id']
         cls.addClassResourceCleanup(
             cls.admin_client.roles_v3_client.delete_role, cls.role_id)
+        cls.member_role_id = cls.admin_client.roles_v3_client.list_roles(
+            name='member')['roles'][0]['id']
 
         # own domain - if system or project user, this will be the user's
         # namespace and isn't applicable for RBAC testing
@@ -2747,9 +2749,9 @@
             role_id=self.role_id)
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
 
-    credentials = ['domain_member', 'system_admin']
+    credentials = ['domain_manager', 'system_admin']
 
     def test_identity_check_grant(self):
         ###################################################
@@ -3228,6 +3230,1369 @@
         ###################################################
         # RESOURCE IN OWN DOMAIN - IDENTITY IN OWN DOMAIN #
         ###################################################
+        # global role permitted for domain managers,
+        # project in own domain, user in own domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=204,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        self.addCleanup(
+            self.admin_roles_client.delete_role_from_user_on_project,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        # global role permitted for domain managers,
+        # project in own domain, group in own domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=204,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        self.addCleanup(
+            self.admin_roles_client.delete_role_from_group_on_project,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        # global role permitted for domain managers,
+        # own domain, user in own domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=204,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        self.addCleanup(
+            self.admin_roles_client.delete_role_from_user_on_domain,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        # global role permitted for domain managers,
+        # own domain, group in own domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=204,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        self.addCleanup(
+            self.admin_roles_client.delete_role_from_group_on_domain,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        # global role not permitted for domain managers,
+        # project in own domain, user in own domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_id)
+        # global role not permitted for domain managers,
+        # project in own domain, group in own domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_id)
+        # global role not permitted for domain managers,
+        # own domain, user in own domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_id)
+        # global role not permitted for domain managers,
+        # own domain, group in own domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_id)
+        # role in own domain, project in own domain, user in own domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in own domain, group in own domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, own domain, user in own domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, own domain, group in own domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in own domain, user in own domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in own domain, group in own domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, own domain, user in own domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, own domain, group in own domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        #####################################################
+        # RESOURCE IN OWN DOMAIN - IDENTITY IN OTHER DOMAIN #
+        #####################################################
+        # global role, project in own domain, user in other domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        # global role, project in own domain, group in other domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        # global role, own domain, user in other domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        # global role, own domain, group in other domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        # role in own domain, project in own domain, user in other domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in own domain, group in other domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, own domain, user in other domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, own domain, group in other domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in own domain, user in other domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in own domain, group in other domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, own domain, user in other domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        #####################################################
+        # RESOURCE IN OTHER DOMAIN - IDENTITY IN OWN DOMAIN #
+        #####################################################
+        # global role, project in other domain, user in own domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        # global role, project in other domain, group in own domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        # global role, other domain, user in own domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        # global role, other domain, group in own domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        # role in own domain, project in other domain, user in own domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in other domain, group in own domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, user in own domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, group in own domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in other domain, user in own domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in other domain, group in own domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, user in own domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, group in own domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        #######################################################
+        # RESOURCE IN OTHER DOMAIN - IDENTITY IN OTHER DOMAIN #
+        #######################################################
+        # global role, project in other domain, user in other domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        # global role, project in other domain, group in other domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        # global role, other domain, user in other domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        # global role, other domain, group in other domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        # role in own domain, project in other domain, user in other domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in other domain, group in other domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, user in other domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, group in other domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in other domain, user in other domain
+        self.do_request(
+            'create_user_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in other domain, group in other domain
+        self.do_request(
+            'create_group_role_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, user in other domain
+        self.do_request(
+            'create_user_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, group in other domain
+        self.do_request(
+            'create_group_role_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+
+    def test_identity_revoke_grant(self):
+        ###################################################
+        # RESOURCE IN OWN DOMAIN - IDENTITY IN OWN DOMAIN #
+        ###################################################
+        # global role permitted for domain managers,
+        # project in own domain, user in own domain
+        self.admin_roles_client.create_user_role_on_project(
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=204,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        # global role permitted for domain managers,
+        # project in own domain, group in own domain
+        self.admin_roles_client.create_group_role_on_project(
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=204,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        # global role permitted for domain managers,
+        # own domain, user in own domain
+        self.admin_roles_client.create_user_role_on_domain(
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=204,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        # global role permitted for domain managers,
+        # own domain, group in own domain
+        self.admin_roles_client.create_group_role_on_domain(
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=204,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        # global role not permitted for domain managers,
+        # project in own domain, user in own domain
+        self.admin_roles_client.create_user_role_on_project(
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_id)
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_id)
+        # global role not permitted for domain managers,
+        # project in own domain, group in own domain
+        self.admin_roles_client.create_group_role_on_project(
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_id)
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_id)
+        # global role not permitted for domain managers,
+        # own domain, user in own domain
+        self.admin_roles_client.create_user_role_on_domain(
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_id)
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_id)
+        # global role not permitted for domain managers,
+        # own domain, group in own domain
+        self.admin_roles_client.create_group_role_on_domain(
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_id)
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_id)
+        # role in own domain, project in own domain, user in own domain
+        self.admin_roles_client.create_user_role_on_project(
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in own domain, group in own domain
+        self.admin_roles_client.create_group_role_on_project(
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, own domain, user in own domain
+        self.admin_roles_client.create_user_role_on_domain(
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, own domain, group in own domain
+        self.admin_roles_client.create_group_role_on_domain(
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in own domain, user in own domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in own domain, group in own domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, own domain, user in own domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, own domain, group in own domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        #####################################################
+        # RESOURCE IN OWN DOMAIN - IDENTITY IN OTHER DOMAIN #
+        #####################################################
+        # global role, project in own domain, user in other domain
+        self.admin_roles_client.create_user_role_on_project(
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        # global role, project in own domain, group in other domain
+        self.admin_roles_client.create_group_role_on_project(
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        # global role, own domain, user in other domain
+        self.admin_roles_client.create_user_role_on_domain(
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        # global role, own domain, group in other domain
+        self.admin_roles_client.create_group_role_on_domain(
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        # role in own domain, project in own domain, user in other domain
+        self.admin_roles_client.create_user_role_on_project(
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in own domain, group in other domain
+        self.admin_roles_client.create_group_role_on_project(
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, own domain, user in other domain
+        self.admin_roles_client.create_user_role_on_domain(
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, own domain, group in other domain
+        self.admin_roles_client.create_group_role_on_domain(
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in own domain, user in other domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in own domain, group in other domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, own domain, user in other domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, own domain, group in other domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        #####################################################
+        # RESOURCE IN OTHER DOMAIN - IDENTITY IN OWN DOMAIN #
+        #####################################################
+        # global role, project in other domain, user in own domain
+        self.admin_roles_client.create_user_role_on_project(
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        # global role, project in other domain, group in own domain
+        self.admin_roles_client.create_group_role_on_project(
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        # global role, other domain, user in own domain
+        self.admin_roles_client.create_user_role_on_domain(
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        # global role, other domain, group in own domain
+        self.admin_roles_client.create_group_role_on_domain(
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        # role in own domain, project in other domain, user in own domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in other domain, group in own domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, user in own domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, group in own domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in other domain, user in own domain
+        self.admin_roles_client.create_user_role_on_project(
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in other domain, group in own domain
+        self.admin_roles_client.create_group_role_on_project(
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, user in own domain
+        self.admin_roles_client.create_user_role_on_domain(
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, group in own domain
+        self.admin_roles_client.create_group_role_on_domain(
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        #######################################################
+        # RESOURCE IN OTHER DOMAIN - IDENTITY IN OTHER DOMAIN #
+        #######################################################
+        # global role, project in other domain, user in other domain
+        self.admin_roles_client.create_user_role_on_project(
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        # global role, project in other domain, group in other domain
+        self.admin_roles_client.create_group_role_on_project(
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        # global role, other domain, user in other domain
+        self.admin_roles_client.create_user_role_on_domain(
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+        # global role, other domain, group in other domain
+        self.admin_roles_client.create_group_role_on_domain(
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        # role in own domain, project in other domain, user in other domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in other domain, group in other domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, user in other domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, group in other domain
+        # role assignment does not exist, should 403
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in other domain, user in other domain
+        self.admin_roles_client.create_user_role_on_project(
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        self.do_request(
+            'delete_role_from_user_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in other domain, group in other domain
+        self.admin_roles_client.create_group_role_on_project(
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        self.do_request(
+            'delete_role_from_group_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, user in other domain
+        self.admin_roles_client.create_user_role_on_domain(
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        self.do_request(
+            'delete_role_from_user_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, group in other domain
+        self.admin_roles_client.create_group_role_on_domain(
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        self.do_request(
+            'delete_role_from_group_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+
+    def test_identity_create_system_grant_for_user(self):
+        self.do_request(
+            'create_user_role_on_system',
+            expected_status=exceptions.Forbidden,
+            user_id=self.user_in_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'create_user_role_on_system',
+            expected_status=exceptions.Forbidden,
+            user_id=self.user_other_domain,
+            role_id=self.member_role_id)
+
+    def test_identity_revoke_system_grant_for_user(self):
+        # group in own domain
+        self.admin_roles_client.create_group_role_on_system(
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        self.addCleanup(
+            self.admin_roles_client.delete_role_from_group_on_system,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_group_on_system',
+            expected_status=exceptions.Forbidden,
+            group_id=self.group_in_domain,
+            role_id=self.member_role_id)
+        # group in other domain
+        self.admin_roles_client.create_group_role_on_system(
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        self.addCleanup(
+            self.admin_roles_client.delete_role_from_group_on_system,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+        self.do_request(
+            'delete_role_from_group_on_system',
+            expected_status=exceptions.Forbidden,
+            group_id=self.group_other_domain,
+            role_id=self.member_role_id)
+
+
+class DomainMemberTests(DomainManagerTests):
+
+    credentials = ['domain_member', 'system_admin']
+
+    def test_identity_check_grant(self):
+        ###################################################
+        # RESOURCE IN OWN DOMAIN - IDENTITY IN OWN DOMAIN #
+        ###################################################
+        # global role, project in own domain, user in own domain
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=204,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_id)
+        # global role, project in own domain, group in own domain
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=204,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_id)
+        # global role, own domain, user in own domain
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=204,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_id)
+        # global role, own domain, group in own domain
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=204,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_id)
+        # role in own domain, project in own domain, user in own domain
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=204,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in own domain, group in own domain
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=204,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, domain in own domain, user in own domain
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=204,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, domain in own domain, group in own domain
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=204,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in own domain, user in own domain
+        # (none created, should 403)
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in own domain, group in own domain
+        # (none created, should 403)
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, domain in own domain, user in own domain
+        # (none created, should 403)
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, domain in own domain, group in own domain
+        # (none created, should 403)
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        #####################################################
+        # RESOURCE IN OWN DOMAIN - IDENTITY IN OTHER DOMAIN #
+        #####################################################
+        # global role, project in own domain, user in other domain
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_id)
+        # global role, project in own domain, group in other domain
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_id)
+        # global role, own domain, user in other domain
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_id)
+        # global role, own domain, group in other domain
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_id)
+        # role in own domain, project in own domain, user in other domain
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in own domain, group in other domain
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, domain in own domain, user in other domain
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, domain in own domain, group in other domain
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in own domain, user in other domain
+        # (none created, should 403)
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in own domain, group in other domain
+        # (none created, should 403)
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_in_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, domain in own domain, user in other domain
+        # (none created, should 403)
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, domain in own domain, group in other domain
+        # (none created, should 403)
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.own_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+
+        #####################################################
+        # RESOURCE IN OTHER DOMAIN - IDENTITY IN OWN DOMAIN #
+        #####################################################
+        # global role, project in other domain, user in own domain
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_id)
+        # global role, project in other domain, group in own domain
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_id)
+        # global role, other domain, user in own domain
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_id)
+        # global role, other domain, group in own domain
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_id)
+        # role in own domain, project in other domain, user in own domain
+        # (none created, should 403)
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in other domain, group in own domain
+        # (none created, should 403)
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, user in own domain
+        # (none created, should 403)
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, group in own domain
+        # (none created, should 403)
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in other domain, user in own domain
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in other domain, group in own domain
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, user in own domain
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_in_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, group in own domain
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_in_domain,
+            role_id=self.role_other_domain)
+        #######################################################
+        # RESOURCE IN OTHER DOMAIN - IDENTITY IN OTHER DOMAIN #
+        #######################################################
+        # global role, project in other domain, user in other domain
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_id)
+        # global role, project in other domain, group in other domain
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_id)
+        # global role, other domain, user in other domain
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_id)
+        # global role, other domain, group in other domain
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_id)
+        # role in own domain, project in other domain, user in other domain
+        # (none created, should 403)
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, project in other domain, group in other domain
+        # (none created, should 403)
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, user in other domain
+        # (none created, should 403)
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_own_domain)
+        # role in own domain, other domain, group in other domain
+        # (none created, should 403)
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_own_domain)
+        # role in other domain, project in other domain, user in other domain
+        self.do_request(
+            'check_user_role_existence_on_project',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, project in other domain, group in other domain
+        self.do_request(
+            'check_role_from_group_on_project_existence',
+            expected_status=exceptions.Forbidden,
+            project_id=self.project_other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, user in other domain
+        self.do_request(
+            'check_user_role_existence_on_domain',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            user_id=self.user_other_domain,
+            role_id=self.role_other_domain)
+        # role in other domain, other domain, group in other domain
+        self.do_request(
+            'check_role_from_group_on_domain_existence',
+            expected_status=exceptions.Forbidden,
+            domain_id=self.other_domain,
+            group_id=self.group_other_domain,
+            role_id=self.role_other_domain)
+
+    def test_identity_create_grant(self):
+        ###################################################
+        # RESOURCE IN OWN DOMAIN - IDENTITY IN OWN DOMAIN #
+        ###################################################
         # global role, project in own domain, user in own domain
         self.do_request(
             'create_user_role_on_project',
@@ -4068,46 +5433,6 @@
             group_id=self.group_other_domain,
             role_id=self.role_other_domain)
 
-    def test_identity_create_system_grant_for_user(self):
-        self.do_request(
-            'create_user_role_on_system',
-            expected_status=exceptions.Forbidden,
-            user_id=self.user_in_domain,
-            role_id=self.role_id)
-        self.do_request(
-            'create_user_role_on_system',
-            expected_status=exceptions.Forbidden,
-            user_id=self.user_other_domain,
-            role_id=self.role_id)
-
-    def test_identity_revoke_system_grant_for_user(self):
-        # group in own domain
-        self.admin_roles_client.create_group_role_on_system(
-            group_id=self.group_in_domain,
-            role_id=self.role_id)
-        self.addCleanup(
-            self.admin_roles_client.delete_role_from_group_on_system,
-            group_id=self.group_in_domain,
-            role_id=self.role_id)
-        self.do_request(
-            'delete_role_from_group_on_system',
-            expected_status=exceptions.Forbidden,
-            group_id=self.group_in_domain,
-            role_id=self.role_id)
-        # group in other domain
-        self.admin_roles_client.create_group_role_on_system(
-            group_id=self.group_other_domain,
-            role_id=self.role_id)
-        self.addCleanup(
-            self.admin_roles_client.delete_role_from_group_on_system,
-            group_id=self.group_other_domain,
-            role_id=self.role_id)
-        self.do_request(
-            'delete_role_from_group_on_system',
-            expected_status=exceptions.Forbidden,
-            group_id=self.group_other_domain,
-            role_id=self.role_id)
-
 
 class DomainReaderTests(DomainMemberTests):
 
@@ -4119,9 +5444,9 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(ProjectAdminTests):
+class ProjectManagerTests(ProjectAdminTests):
 
-    credentials = ['project_member', 'system_admin']
+    credentials = ['project_manager', 'system_admin']
 
     def test_identity_check_grant(self):
         # global role, arbitrary project, arbitrary user
@@ -4460,6 +5785,11 @@
             role_id=self.role_id)
 
 
+class ProjectMemberTests(ProjectManagerTests):
+
+    credentials = ['project_member', 'system_admin']
+
+
 class ProjectReaderTests(ProjectMemberTests):
 
     credentials = ['project_reader', 'system_admin']
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_group.py b/keystone_tempest_plugin/tests/rbac/v3/test_group.py
index d62e801..d3ca20a 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_group.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_group.py
@@ -490,6 +490,282 @@
         self.assertEqual(0, len(user_ids))
 
 
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+    def test_identity_create_group(self):
+        # user can create group in own domain
+        resp = self.do_request('create_group',
+                               expected_status=201,
+                               **self.group(domain_id=self.own_domain))
+        self.addCleanup(self.admin_groups_client.delete_group,
+                        resp['group']['id'])
+        # user cannot create group in another domain
+        self.do_request('create_group',
+                        expected_status=exceptions.Forbidden,
+                        **self.group(domain_id=self.other_domain))
+
+    def test_identity_get_group(self):
+        group = self.admin_groups_client.create_group(
+            **self.group(domain_id=self.own_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group['id'])
+        # user can get group in own domain
+        self.do_request('show_group', group_id=group['id'])
+        # user cannot get group in other domain
+        group = self.admin_groups_client.create_group(
+            **self.group(domain_id=self.other_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group['id'])
+        self.do_request('show_group', expected_status=exceptions.Forbidden,
+                        group_id=group['id'])
+        # user gets a 403 for nonexistent group
+        self.do_request('show_group', expected_status=exceptions.Forbidden,
+                        group_id='fakegroup')
+
+    def test_identity_list_groups_for_user(self):
+        group1 = self.admin_groups_client.create_group(
+            **self.group(domain_id=self.own_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group1['id'])
+        user1 = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name('user'),
+            domain_id=self.own_domain)['user']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user,
+                        user1['id'])
+        group2 = self.admin_groups_client.create_group(
+            **self.group(domain_id=self.other_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group2['id'])
+        user2 = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name('user'),
+            domain_id=self.other_domain)['user']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user,
+                        user2['id'])
+        self.admin_groups_client.add_group_user(group1['id'], user1['id'])
+        self.admin_groups_client.add_group_user(group1['id'], user2['id'])
+        self.admin_groups_client.add_group_user(group2['id'], user1['id'])
+        self.admin_groups_client.add_group_user(group2['id'], user2['id'])
+        resp = self.do_request('list_user_groups', client=self.users_client,
+                               user_id=user1['id'])
+        # user can list groups in own domain for user in own domain
+        self.assertIn(group1['id'], set(g['id'] for g in resp['groups']))
+        # user cannot list groups in other domain for user in own domain
+        self.assertNotIn(group2['id'], set(g['id'] for g in resp['groups']))
+        # user cannot list groups for user in other domain
+        resp = self.do_request('list_user_groups', client=self.users_client,
+                               expected_status=exceptions.Forbidden,
+                               user_id=user2['id'])
+        # user gets a 403 for nonexistent user
+        self.do_request('list_user_groups', client=self.users_client,
+                        expected_status=exceptions.Forbidden,
+                        user_id='fakeuser')
+
+    def test_identity_update_group(self):
+        group1 = self.admin_groups_client.create_group(
+            **self.group(domain_id=self.own_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group1['id'])
+        group2 = self.admin_groups_client.create_group(
+            **self.group(domain_id=self.other_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group2['id'])
+        # user can update a group in own domain
+        group_update = {
+            'group_id': group1['id'],
+            'description': data_utils.arbitrary_string
+        }
+        self.do_request('update_group', **group_update)
+        # user cannot update a group in other domain
+        group_update = {
+            'group_id': group2['id'],
+            'description': data_utils.arbitrary_string
+        }
+        self.do_request('update_group', expected_status=exceptions.Forbidden,
+                        **group_update)
+        # user gets a 403 for nonexistent group
+        group_update = {
+            'group_id': 'fakegroup',
+            'description': data_utils.arbitrary_string
+        }
+        self.do_request('update_group', expected_status=exceptions.Forbidden,
+                        **group_update)
+
+    def test_identity_delete_group(self):
+        group1 = self.admin_groups_client.create_group(
+            **self.group(domain_id=self.own_domain))['group']
+        group2 = self.admin_groups_client.create_group(
+            **self.group(domain_id=self.other_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group2['id'])
+        # user can delete a group in own domain
+        self.do_request('delete_group', expected_status=204,
+                        group_id=group1['id'])
+        # user cannot delete a group in other domain
+        self.do_request('delete_group', expected_status=exceptions.Forbidden,
+                        group_id=group2['id'])
+        # user gets a 404 for nonexistent group
+        self.do_request('delete_group', expected_status=exceptions.NotFound,
+                        group_id='fakegroup')
+
+    def test_identity_list_users_in_group(self):
+        group1 = self.admin_groups_client.create_group(
+            **self.group(domain_id=self.own_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group1['id'])
+        user1 = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name('user'),
+            domain_id=self.own_domain)['user']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user,
+                        user1['id'])
+        group2 = self.admin_groups_client.create_group(
+            **self.group(domain_id=self.other_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group2['id'])
+        user2 = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name('user'),
+            domain_id=self.other_domain)['user']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user,
+                        user2['id'])
+        self.admin_groups_client.add_group_user(group1['id'], user1['id'])
+        self.admin_groups_client.add_group_user(group1['id'], user2['id'])
+        self.admin_groups_client.add_group_user(group2['id'], user1['id'])
+        self.admin_groups_client.add_group_user(group2['id'], user2['id'])
+        resp = self.do_request('list_group_users', group_id=group1['id'])
+        # user can list users in own domain for group in own domain
+        self.assertIn(user1['id'], set(u['id'] for u in resp['users']))
+        # user cannot list users in another domain for group in own domain
+        self.assertNotIn(user2['id'], set(u['id'] for u in resp['users']))
+        # user cannot list users for group in another domain
+        self.do_request('list_group_users',
+                        expected_status=exceptions.Forbidden,
+                        group_id=group2['id'])
+
+    def test_identity_add_user_to_group(self):
+        group1 = self.admin_groups_client.create_group(
+            **self.group(self.own_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group1['id'])
+        group2 = self.admin_groups_client.create_group(
+            **self.group(self.other_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group2['id'])
+        user1 = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name('user'),
+            domain_id=self.own_domain)['user']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user,
+                        user1['id'])
+        user2 = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name('user'),
+            domain_id=self.other_domain)['user']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user,
+                        user2['id'])
+        # user can add a user in own domain to a group in own domain
+        self.do_request('add_group_user', expected_status=204,
+                        group_id=group1['id'], user_id=user1['id'])
+        # user cannot add a user in another domain to a group in own domain
+        self.do_request('add_group_user', expected_status=exceptions.Forbidden,
+                        group_id=group1['id'], user_id=user2['id'])
+        # user cannot add a user in own domain to a group in another domain
+        self.do_request('add_group_user', expected_status=exceptions.Forbidden,
+                        group_id=group2['id'], user_id=user1['id'])
+        # user cannot add a user in another domain to a group in another domain
+        self.do_request('add_group_user', expected_status=exceptions.Forbidden,
+                        group_id=group2['id'], user_id=user2['id'])
+        # user gets a 403 for nonexistent group
+        self.do_request('add_group_user', expected_status=exceptions.Forbidden,
+                        group_id='fakegroup', user_id=user1['id'])
+        # user gets a 403 for nonexistent user
+        self.do_request('add_group_user', expected_status=exceptions.Forbidden,
+                        group_id=group1['id'], user_id='fakeuser')
+
+    def test_identity_remove_user_from_group(self):
+        group1 = self.admin_groups_client.create_group(
+            **self.group(self.own_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group1['id'])
+        group2 = self.admin_groups_client.create_group(
+            **self.group(self.other_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group2['id'])
+        user1 = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name('user'),
+            domain_id=self.own_domain)['user']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user,
+                        user1['id'])
+        user2 = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name('user'),
+            domain_id=self.other_domain)['user']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user,
+                        user2['id'])
+        self.admin_groups_client.add_group_user(group1['id'], user1['id'])
+        self.admin_groups_client.add_group_user(group1['id'], user2['id'])
+        self.admin_groups_client.add_group_user(group2['id'], user1['id'])
+        self.admin_groups_client.add_group_user(group2['id'], user2['id'])
+        # user can remove a user in own domain from a group in own domain
+        self.do_request('delete_group_user', expected_status=204,
+                        group_id=group1['id'], user_id=user1['id'])
+        # user cannot remove a user in another domain from a group in own
+        # domain
+        self.do_request('delete_group_user',
+                        expected_status=exceptions.Forbidden,
+                        group_id=group1['id'], user_id=user2['id'])
+        # user cannot remove a user in own domain from a group in another
+        # domain
+        self.do_request('delete_group_user',
+                        expected_status=exceptions.Forbidden,
+                        group_id=group2['id'], user_id=user1['id'])
+        # user cannot remove a user in another domain from a group in another
+        # domain
+        self.do_request('delete_group_user',
+                        expected_status=exceptions.Forbidden,
+                        group_id=group2['id'], user_id=user2['id'])
+        # user gets a 403 for nonexistent group
+        self.do_request('delete_group_user',
+                        expected_status=exceptions.Forbidden,
+                        group_id='fakegroup', user_id=user1['id'])
+        # user gets a 403 for nonexistent user
+        self.do_request('delete_group_user',
+                        expected_status=exceptions.Forbidden,
+                        group_id=group1['id'], user_id='fakeuser')
+
+    def test_identity_check_user_in_group(self):
+        group1 = self.admin_groups_client.create_group(
+            **self.group(self.own_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group1['id'])
+        group2 = self.admin_groups_client.create_group(
+            **self.group(self.other_domain))['group']
+        self.addCleanup(self.admin_groups_client.delete_group, group2['id'])
+        user1 = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name('user'),
+            domain_id=self.own_domain)['user']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user,
+                        user1['id'])
+        user2 = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name('user'),
+            domain_id=self.own_domain)['user']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user,
+                        user2['id'])
+        self.admin_groups_client.add_group_user(group1['id'], user1['id'])
+        self.admin_groups_client.add_group_user(group1['id'], user2['id'])
+        self.admin_groups_client.add_group_user(group2['id'], user1['id'])
+        self.admin_groups_client.add_group_user(group2['id'], user2['id'])
+        # user can check if a user in own domain is in a group in own domain
+        self.do_request('check_group_user_existence', expected_status=204,
+                        group_id=group1['id'], user_id=user1['id'])
+        # user can check if a user in another domain is in a group in own
+        # domain
+        self.do_request('check_group_user_existence',
+                        expected_status=204,
+                        group_id=group1['id'], user_id=user2['id'])
+        # user cannot check if a user in own domain is in a group in another
+        # domain
+        self.do_request('check_group_user_existence',
+                        expected_status=exceptions.Forbidden,
+                        group_id=group2['id'], user_id=user1['id'])
+        # user cannot check if a user in another domain is in a group in
+        # another domain
+        self.do_request('check_group_user_existence',
+                        expected_status=exceptions.Forbidden,
+                        group_id=group2['id'], user_id=user2['id'])
+        # user gets a 403 for nonexistent group
+        self.do_request('check_group_user_existence',
+                        expected_status=exceptions.Forbidden,
+                        group_id='fakegroup', user_id=user1['id'])
+        # user gets a 403 for nonexistent user
+        self.do_request('check_group_user_existence',
+                        expected_status=exceptions.Forbidden,
+                        group_id=group1['id'], user_id='fakeuser')
+
+
 class DomainMemberTests(IdentityV3RbacGroupTest, base.BaseIdentityTest):
 
     credentials = ['domain_member', 'system_admin']
@@ -659,7 +935,7 @@
                         user1['id'])
         user2 = self.admin_client.users_v3_client.create_user(
             name=data_utils.rand_name('user'),
-            domain_id=self.own_domain)['user']
+            domain_id=self.other_domain)['user']
         self.addCleanup(self.admin_client.users_v3_client.delete_user,
                         user2['id'])
         # user cannot add a user in own domain to a group in own domain
@@ -695,7 +971,7 @@
                         user1['id'])
         user2 = self.admin_client.users_v3_client.create_user(
             name=data_utils.rand_name('user'),
-            domain_id=self.own_domain)['user']
+            domain_id=self.other_domain)['user']
         self.addCleanup(self.admin_client.users_v3_client.delete_user,
                         user2['id'])
         self.admin_groups_client.add_group_user(group1['id'], user1['id'])
@@ -789,9 +1065,9 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(IdentityV3RbacGroupTest, base.BaseIdentityTest):
+class ProjectManagerTests(IdentityV3RbacGroupTest, base.BaseIdentityTest):
 
-    credentials = ['project_member', 'system_admin']
+    credentials = ['project_manager', 'system_admin']
 
     def test_identity_create_group(self):
         # user cannot create group in own domain
@@ -1072,6 +1348,11 @@
                         group_id=group1['id'], user_id='fakeuser')
 
 
+class ProjectMemberTests(ProjectManagerTests):
+
+    credentials = ['project_member', 'system_admin']
+
+
 class ProjectReaderTests(ProjectMemberTests):
 
     credentials = ['project_reader', 'system_admin']
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_identity_provider.py b/keystone_tempest_plugin/tests/rbac/v3/test_identity_provider.py
index fa6d9c1..c2c2178 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_identity_provider.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_identity_provider.py
@@ -258,7 +258,12 @@
                         expected_status=exceptions.Forbidden)
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -273,7 +278,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_implied_role.py b/keystone_tempest_plugin/tests/rbac/v3/test_implied_role.py
index f73d510..c7d2c4d 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_implied_role.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_implied_role.py
@@ -232,7 +232,12 @@
                         implies_role=self.implied_role)
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -247,7 +252,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_limit.py b/keystone_tempest_plugin/tests/rbac/v3/test_limit.py
index 456b850..bb96fa0 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_limit.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_limit.py
@@ -355,9 +355,9 @@
                         limit_id=reg_limit_id)
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
 
-    credentials = ['domain_member', 'system_admin']
+    credentials = ['domain_manager', 'system_admin']
 
     def test_identity_get_limit(self):
         # random project
@@ -382,6 +382,11 @@
                         limit_id=reg_limit_2)
 
 
+class DomainMemberTests(DomainManagerTests):
+
+    credentials = ['domain_member', 'system_admin']
+
+
 class DomainReaderTests(DomainMemberTests):
 
     credentials = ['domain_reader', 'system_admin']
@@ -392,7 +397,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_mapping.py b/keystone_tempest_plugin/tests/rbac/v3/test_mapping.py
index c519426..3a5da2b 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_mapping.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_mapping.py
@@ -230,7 +230,12 @@
                         expected_status=exceptions.Forbidden)
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -245,7 +250,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_policy.py b/keystone_tempest_plugin/tests/rbac/v3/test_policy.py
index df5844f..dddf084 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_policy.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_policy.py
@@ -207,7 +207,12 @@
         self.do_request('list_policies', expected_status=exceptions.Forbidden)
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -222,7 +227,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_policy_association.py b/keystone_tempest_plugin/tests/rbac/v3/test_policy_association.py
index a3cf76d..c122eab 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_policy_association.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_policy_association.py
@@ -444,7 +444,12 @@
             policy_id=self.policy_id)
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -459,7 +464,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_project.py b/keystone_tempest_plugin/tests/rbac/v3/test_project.py
index 8d975e7..2b00035 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_project.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_project.py
@@ -342,7 +342,122 @@
                         project_id=project_id)
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+    def test_identity_create_project(self):
+        # user can create project in own domain
+        project_id = self.do_request(
+            'create_project', expected_status=201,
+            name=data_utils.rand_name(),
+            domain_id=self.own_domain
+        )['project']['id']
+        self.addCleanup(self.admin_projects_client.delete_project, project_id)
+        # user cannot create project in other domain
+        self.do_request(
+            'create_project', expected_status=exceptions.Forbidden,
+            name=data_utils.rand_name(), domain_id=self.other_domain
+        )
+
+    def test_identity_get_project(self):
+        # user can get project in own domain
+        project_id = self.admin_projects_client.create_project(
+            name=data_utils.rand_name(),
+            domain_id=self.own_domain)['project']['id']
+        self.addCleanup(self.admin_projects_client.delete_project, project_id)
+        self.do_request('show_project', project_id=project_id)
+        # user cannot get project in other domain
+        project_id = self.admin_projects_client.create_project(
+            name=data_utils.rand_name(),
+            domain_id=self.other_domain)['project']['id']
+        self.addCleanup(self.admin_projects_client.delete_project, project_id)
+        self.do_request('show_project', expected_status=exceptions.Forbidden,
+                        project_id=project_id)
+        # user gets a 403 for nonexistent project
+        self.do_request('show_project', expected_status=exceptions.Forbidden,
+                        project_id=data_utils.rand_uuid_hex())
+
+    def test_identity_list_user_projects(self):
+        # user can list projects for user in own domain
+        user_id = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name(),
+            domain_id=self.own_domain)['user']['id']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user, user_id)
+        project_id = self.admin_projects_client.create_project(
+            name=data_utils.rand_name())['project']['id']
+        self.addCleanup(self.admin_projects_client.delete_project, project_id)
+        role_id = self.admin_client.roles_v3_client.create_role(
+            name=data_utils.rand_name())['role']['id']
+        self.addCleanup(self.admin_client.roles_v3_client.delete_role,
+                        role_id)
+        self.admin_client.roles_v3_client.create_user_role_on_project(
+            project_id, user_id, role_id)
+        resp = self.do_request('list_user_projects', client=self.users_client,
+                               user_id=user_id)
+        self.assertIn(project_id, [p['id'] for p in resp['projects']])
+        # user cannot list projects for user in other domain
+        user_id = self.admin_client.users_v3_client.create_user(
+            name=data_utils.rand_name(),
+            domain_id=self.other_domain)['user']['id']
+        self.addCleanup(self.admin_client.users_v3_client.delete_user, user_id)
+        project_id = self.admin_projects_client.create_project(
+            name=data_utils.rand_name())['project']['id']
+        self.addCleanup(self.admin_projects_client.delete_project, project_id)
+        role_id = self.admin_client.roles_v3_client.create_role(
+            name=data_utils.rand_name())['role']['id']
+        self.addCleanup(self.admin_client.roles_v3_client.delete_role,
+                        role_id)
+        self.admin_client.roles_v3_client.create_user_role_on_project(
+            project_id, user_id, role_id)
+        self.do_request('list_user_projects', client=self.users_client,
+                        expected_status=exceptions.Forbidden,
+                        user_id=user_id)
+        # user can list projects for self
+        resp = self.do_request('list_user_projects', client=self.users_client,
+                               user_id=self.persona.credentials.user_id)
+        self.assertEqual(0, len([p['id'] for p in resp['projects']]))
+
+    def test_identity_update_project(self):
+        # user can update project in own domain
+        project_id = self.admin_projects_client.create_project(
+            name=data_utils.rand_name(),
+            domain_id=self.own_domain)['project']['id']
+        self.addCleanup(self.admin_projects_client.delete_project, project_id)
+        self.do_request('update_project',
+                        project_id=project_id,
+                        description=data_utils.arbitrary_string())
+        # user cannot update project in other domain
+        project_id = self.admin_projects_client.create_project(
+            name=data_utils.rand_name(),
+            domain_id=self.other_domain)['project']['id']
+        self.addCleanup(self.admin_projects_client.delete_project, project_id)
+        self.do_request('update_project',
+                        expected_status=exceptions.Forbidden,
+                        project_id=project_id,
+                        description=data_utils.arbitrary_string())
+        # user gets a 403 for nonexistent domain
+        self.do_request('update_project', expected_status=exceptions.Forbidden,
+                        project_id=data_utils.rand_uuid_hex(),
+                        description=data_utils.arbitrary_string())
+
+    def test_identity_delete_project(self):
+        # user can delete project in own domain
+        project_id = self.admin_projects_client.create_project(
+            name=data_utils.rand_name(),
+            domain_id=self.own_domain)['project']['id']
+        self.do_request('delete_project', expected_status=204,
+                        project_id=project_id)
+        # user cannot delete project in other domain
+        project_id = self.admin_projects_client.create_project(
+            name=data_utils.rand_name(),
+            domain_id=self.other_domain)['project']['id']
+        self.addCleanup(self.admin_projects_client.delete_project, project_id)
+        self.do_request('delete_project', expected_status=exceptions.Forbidden,
+                        project_id=project_id)
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -491,9 +606,9 @@
         self.assertEqual(1, len([p['id'] for p in resp['projects']]))
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
 
-    credentials = ['project_member', 'system_admin']
+    credentials = ['project_manager', 'system_admin']
 
     def test_identity_get_project(self):
         # user cannot get arbitrary project
@@ -542,6 +657,11 @@
                       [p['id'] for p in resp['projects']])
 
 
+class ProjectMemberTests(ProjectManagerTests):
+
+    credentials = ['project_member', 'system_admin']
+
+
 class ProjectReaderTests(ProjectMemberTests):
 
     credentials = ['project_reader', 'system_admin']
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_project_endpoint.py b/keystone_tempest_plugin/tests/rbac/v3/test_project_endpoint.py
index 34bb13e..b225ee2 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_project_endpoint.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_project_endpoint.py
@@ -226,7 +226,12 @@
                         project_id=self.project_id)
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -241,7 +246,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_project_tag.py b/keystone_tempest_plugin/tests/rbac/v3/test_project_tag.py
index 646fa86..d10b9fa 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_project_tag.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_project_tag.py
@@ -326,7 +326,105 @@
                         project_id=self.other_project_id)
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+    def test_identity_create_project_tag(self):
+        # user can add tags to project in own domain
+        tag = data_utils.rand_uuid_hex()
+        self.do_request(
+            'update_project_tag', expected_status=201,
+            project_id=self.own_project_id,
+            tag=tag
+        )
+        # user cannot add tags to project in other domain
+        tag = data_utils.rand_uuid_hex()
+        self.do_request(
+            'update_project_tag', expected_status=exceptions.Forbidden,
+            project_id=self.other_project_id,
+            tag=tag
+        )
+
+    def test_identity_get_project_tag(self):
+        # user can get tag for project in own domain
+        tag = data_utils.rand_uuid_hex()
+        self.admin_project_tags_client.update_project_tag(
+            project_id=self.own_project_id, tag=tag)
+        self.do_request('check_project_tag_existence',
+                        expected_status=204,
+                        project_id=self.own_project_id, tag=tag)
+        # user cannot get tag for project in other domain
+        tag = data_utils.rand_uuid_hex()
+        self.admin_project_tags_client.update_project_tag(
+            project_id=self.other_project_id, tag=tag)
+        self.do_request('check_project_tag_existence',
+                        expected_status=exceptions.Forbidden,
+                        project_id=self.other_project_id, tag=tag)
+
+    def test_identity_list_project_tags(self):
+        # user can list tags for project in own domain
+        tag = data_utils.rand_uuid_hex()
+        self.admin_project_tags_client.update_project_tag(
+            project_id=self.own_project_id, tag=tag)
+        resp = self.do_request('list_project_tags',
+                               project_id=self.own_project_id)
+        self.assertIn(tag, resp['tags'])
+        # user can list tags for project in other domain
+        tag = data_utils.rand_uuid_hex()
+        self.admin_project_tags_client.update_project_tag(
+            project_id=self.other_project_id, tag=tag)
+        self.do_request('list_project_tags',
+                        expected_status=exceptions.Forbidden,
+                        project_id=self.other_project_id)
+
+    def test_identity_update_project_tags(self):
+        # user can update tags for project in own domain
+        tag = data_utils.rand_uuid_hex()
+        self.do_request('update_all_project_tags',
+                        project_id=self.own_project_id,
+                        tags=[tag])
+        # user cannot update tags for project in other domain
+        tag = data_utils.rand_uuid_hex()
+        self.do_request('update_all_project_tags',
+                        expected_status=exceptions.Forbidden,
+                        project_id=self.other_project_id,
+                        tags=[tag])
+
+    def test_identity_delete_project_tag(self):
+        # user can delete tag for project in own domain
+        tag = data_utils.rand_uuid_hex()
+        self.admin_project_tags_client.update_project_tag(
+            project_id=self.own_project_id, tag=tag)
+        self.do_request('delete_project_tag', expected_status=204,
+                        project_id=self.own_project_id,
+                        tag=tag)
+        # user cannot delete tag for project in other domain
+        tag = data_utils.rand_uuid_hex()
+        self.admin_project_tags_client.update_project_tag(
+            project_id=self.other_project_id, tag=tag)
+        self.do_request('delete_project_tag',
+                        expected_status=exceptions.Forbidden,
+                        project_id=self.other_project_id,
+                        tag=tag)
+
+    def test_identity_delete_project_tags(self):
+        # user can delete tags for project in own domain
+        tag = data_utils.rand_uuid_hex()
+        self.admin_project_tags_client.update_project_tag(
+            project_id=self.own_project_id, tag=tag)
+        self.do_request('delete_all_project_tags', expected_status=204,
+                        project_id=self.own_project_id)
+        # user cannot delete tags for project in other domain
+        tag = data_utils.rand_uuid_hex()
+        self.admin_project_tags_client.update_project_tag(
+            project_id=self.other_project_id, tag=tag)
+        self.do_request('delete_all_project_tags',
+                        expected_status=exceptions.Forbidden,
+                        project_id=self.other_project_id)
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -437,9 +535,9 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainMemberTests):
+class ProjectManagerTests(DomainMemberTests):
 
-    credentials = ['project_member', 'system_admin']
+    credentials = ['project_manager', 'system_admin']
 
     def setUp(self):
         super().setUp()
@@ -558,6 +656,11 @@
                         project_id=self.other_project_id)
 
 
+class ProjectMemberTests(ProjectManagerTests):
+
+    credentials = ['project_member', 'system_admin']
+
+
 class ProjectReaderTests(ProjectMemberTests):
 
     credentials = ['project_reader', 'system_admin']
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_protocol.py b/keystone_tempest_plugin/tests/rbac/v3/test_protocol.py
index f766b1f..c438cff 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_protocol.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_protocol.py
@@ -277,7 +277,12 @@
                         idp_id=self.idp_id)
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -292,7 +297,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_region.py b/keystone_tempest_plugin/tests/rbac/v3/test_region.py
index ab5969e..b22f586 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_region.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_region.py
@@ -184,7 +184,12 @@
     credentials = ['domain_admin', 'system_admin']
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -199,7 +204,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_registered_limit.py b/keystone_tempest_plugin/tests/rbac/v3/test_registered_limit.py
index 31e78e4..c88fe8e 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_registered_limit.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_registered_limit.py
@@ -197,7 +197,12 @@
     credentials = ['domain_admin', 'system_admin']
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -212,7 +217,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_role.py b/keystone_tempest_plugin/tests/rbac/v3/test_role.py
index 32fa424..1db157c 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_role.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_role.py
@@ -45,6 +45,8 @@
             cls.admin_client.domains_client.update_domain,
             cls.domain_id,
             enabled=False)
+        cls.member_role_id = cls.admin_client.roles_v3_client.list_roles(
+            name='member')['roles'][0]['id']
 
     def role(self, domain_id=None):
         role = {}
@@ -304,7 +306,7 @@
                         description=data_utils.arbitrary_string())
 
     def test_identity_delete_domain_role(self):
-        # user can delete domain role
+        # user cannot delete domain role
         role = self.admin_roles_client.create_role(
             **self.role(domain_id=self.domain_id))['role']
         self.do_request('delete_role', expected_status=exceptions.Forbidden,
@@ -349,7 +351,27 @@
                         domain_id=self.domain_id)
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+    def test_identity_get_role(self):
+        # user can get role that is part of the domain_managed_target_role
+        # list for domain managers, which per default includes "member"
+        self.do_request('show_role', role_id=self.member_role_id)
+        # user cannot get arbitrary global role not part of the
+        # domain_managed_target_role list
+        role = self.admin_roles_client.create_role(
+            **self.role())['role']
+        self.addCleanup(self.admin_roles_client.delete_role, role['id'])
+        self.do_request('show_role', expected_status=exceptions.Forbidden,
+                        role_id=role['id'])
+        # user gets a 404 for nonexistent role
+        self.do_request('show_role', expected_status=exceptions.NotFound,
+                        role_id=data_utils.rand_uuid_hex())
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -381,7 +403,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainMemberTests):
+class ProjectManagerTests(DomainMemberTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_role_assignment.py b/keystone_tempest_plugin/tests/rbac/v3/test_role_assignment.py
index 14e164a..e7f9201 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_role_assignment.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_role_assignment.py
@@ -982,9 +982,9 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(IdentityV3RbacAssignmentTest, base.BaseIdentityTest):
+class ProjectManagerTests(IdentityV3RbacAssignmentTest, base.BaseIdentityTest):
 
-    credentials = ['project_member', 'system_admin']
+    credentials = ['project_manager', 'system_admin']
 
     def test_identity_list_role_assignments(self):
         # Listing all assignments with no filters should fail
@@ -1117,6 +1117,11 @@
                         expected_status=exceptions.Forbidden, **query)
 
 
+class ProjectMemberTests(ProjectManagerTests):
+
+    credentials = ['project_member', 'system_admin']
+
+
 class ProjectReaderTests(ProjectMemberTests):
 
     credentials = ['project_reader', 'system_admin']
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_service.py b/keystone_tempest_plugin/tests/rbac/v3/test_service.py
index 616741a..92d7a84 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_service.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_service.py
@@ -208,7 +208,12 @@
         self.do_request('list_services', expected_status=exceptions.Forbidden)
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -223,7 +228,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_service_provider.py b/keystone_tempest_plugin/tests/rbac/v3/test_service_provider.py
index 668289b..5e9914f 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_service_provider.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_service_provider.py
@@ -225,7 +225,12 @@
                         expected_status=exceptions.Forbidden)
 
 
-class DomainMemberTests(DomainAdminTests, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests, base.BaseIdentityTest):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -240,7 +245,12 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(DomainReaderTests):
+class ProjectManagerTests(DomainReaderTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_token.py b/keystone_tempest_plugin/tests/rbac/v3/test_token.py
index 4e654cf..87db0eb 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_token.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_token.py
@@ -243,9 +243,9 @@
         super(SystemAdminTests, self).setUp()
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
 
-    credentials = ['domain_member', 'system_admin']
+    credentials = ['domain_manager', 'system_admin']
 
     def test_identity_check_token(self):
         # user can check own token
@@ -294,6 +294,11 @@
                         resp_token=self.project_token)
 
 
+class DomainMemberTests(DomainManagerTests):
+
+    credentials = ['domain_member', 'system_admin']
+
+
 class DomainReaderTests(DomainMemberTests):
 
     credentials = ['domain_reader', 'system_admin']
@@ -313,7 +318,21 @@
         super(SystemAdminTests, self).setUp()
 
 
-class ProjectMemberTests(DomainMemberTests):
+class ProjectManagerTests(DomainMemberTests):
+
+    credentials = ['project_manager', 'system_admin']
+
+    def setUp(self):
+        self.own_keystone_creds = {
+            'user_id': self.persona.credentials.user_id,
+            'password': self.persona.credentials.password,
+            'project_id': self.persona.credentials.project_id
+        }
+        # call base setUp directly to ensure we don't use system creds
+        super(SystemAdminTests, self).setUp()
+
+
+class ProjectMemberTests(ProjectManagerTests):
 
     credentials = ['project_member', 'system_admin']
 
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_trust.py b/keystone_tempest_plugin/tests/rbac/v3/test_trust.py
index 9165503..7a2a26c 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_trust.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_trust.py
@@ -357,7 +357,12 @@
                         trust_id=trust_id, role_id=self.roles[0]['id'])
 
 
-class DomainMemberTests(DomainAdminTests):
+class DomainManagerTests(DomainAdminTests):
+
+    credentials = ['domain_manager', 'system_admin']
+
+
+class DomainMemberTests(DomainManagerTests):
 
     credentials = ['domain_member', 'system_admin']
 
@@ -396,12 +401,12 @@
             **self.trust())
 
 
-class ProjectMemberTests(IdentityV3RbacTrustTest, base.BaseIdentityTest):
+class ProjectManagerTests(IdentityV3RbacTrustTest, base.BaseIdentityTest):
 
-    credentials = ['project_member', 'system_admin']
+    credentials = ['project_manager', 'system_admin']
 
     def setUp(self):
-        super(ProjectMemberTests, self).setUp()
+        super(ProjectManagerTests, self).setUp()
         self.role_id = self.member_role_id
 
     def test_identity_create_trust(self):
@@ -570,6 +575,11 @@
                         trust_id=trust_id)
 
 
+class ProjectMemberTests(ProjectManagerTests):
+
+    credentials = ['project_member', 'system_admin']
+
+
 class ProjectReaderTests(ProjectMemberTests):
 
     credentials = ['project_reader', 'system_admin']
diff --git a/keystone_tempest_plugin/tests/rbac/v3/test_user.py b/keystone_tempest_plugin/tests/rbac/v3/test_user.py
index c031cfe..08edfe6 100644
--- a/keystone_tempest_plugin/tests/rbac/v3/test_user.py
+++ b/keystone_tempest_plugin/tests/rbac/v3/test_user.py
@@ -266,12 +266,12 @@
         self.assertIn(user1['id'], user_ids)
 
 
-class DomainMemberTests(IdentityV3RbacUserTest, base.BaseIdentityTest):
+class DomainManagerTests(DomainAdminTests):
 
-    credentials = ['domain_member', 'system_admin']
+    credentials = ['domain_manager', 'system_admin']
 
     def setUp(self):
-        super(DomainMemberTests, self).setUp()
+        super(DomainManagerTests, self).setUp()
         self.other_domain = self.admin_domains_client.create_domain(
             name=data_utils.rand_name())['domain']
         self.addCleanup(self.admin_domains_client.delete_domain,
@@ -281,6 +281,112 @@
 
     def test_identity_create_user(self):
         user_create = self.user()
+        # cannot create user without domain specified
+        self.do_request('create_user', expected_status=exceptions.Forbidden,
+                        **user_create)
+        # cannot create user in other domain
+        user_create['domain_id'] = self.other_domain['id']
+        self.do_request('create_user', expected_status=exceptions.Forbidden,
+                        **user_create)
+        # can create user in own domain
+        user_create['domain_id'] = self.persona.credentials.domain_id
+        resp = self.do_request('create_user', expected_status=201,
+                               **user_create)
+        self.addCleanup(self.admin_users_client.delete_user,
+                        resp['user']['id'])
+
+    def test_identity_get_user(self):
+        user_create = self.user()
+        user_create['domain_id'] = self.other_domain['id']
+        user = self.admin_users_client.create_user(**user_create)['user']
+        self.addCleanup(self.admin_users_client.delete_user, user['id'])
+        # user cannot get user in other domain
+        self.do_request('show_user', expected_status=exceptions.Forbidden,
+                        user_id=user['id'])
+        user_create['domain_id'] = self.persona.credentials.domain_id
+        user = self.admin_users_client.create_user(**user_create)['user']
+        self.addCleanup(self.admin_users_client.delete_user, user['id'])
+        # user can get user in own domain
+        resp = self.do_request('show_user', user_id=user['id'])
+        self.assertEqual(resp['user']['id'], user['id'])
+        # user can get own user
+        user_id = self.persona.credentials.user_id
+        resp = self.do_request('show_user', user_id=user_id)
+        self.assertEqual(resp['user']['id'], user_id)
+        # user gets a 403 for nonexistent user
+        self.do_request('show_user', expected_status=exceptions.Forbidden,
+                        user_id='fakeuser')
+
+    def test_identity_list_users(self):
+        user_create = self.user()
+        # create user in other domain
+        user_create['domain_id'] = self.other_domain['id']
+        user1 = self.admin_users_client.create_user(**user_create)['user']
+        self.addCleanup(self.admin_users_client.delete_user, user1['id'])
+        # create user in own domain
+        user_create['domain_id'] = self.persona.credentials.domain_id
+        user2 = self.admin_users_client.create_user(**user_create)['user']
+        self.addCleanup(self.admin_users_client.delete_user, user2['id'])
+        resp = self.do_request('list_users')
+        user_ids = set(u['id'] for u in resp['users'])
+        self.assertNotIn(user1['id'], user_ids)
+        self.assertIn(user2['id'], user_ids)
+
+    def test_identity_update_user(self):
+        user_create = self.user()
+        # create user in other domain
+        user_create['domain_id'] = self.other_domain['id']
+        user = self.admin_users_client.create_user(**user_create)['user']
+        self.addCleanup(self.admin_users_client.delete_user, user['id'])
+        user_update = {
+            'user_id': user['id'],
+            'description': data_utils.arbitrary_string()
+        }
+        self.do_request('update_user', expected_status=exceptions.Forbidden,
+                        **user_update)
+        # create user in own domain
+        user_create['domain_id'] = self.persona.credentials.domain_id
+        user = self.admin_users_client.create_user(**user_create)['user']
+        self.addCleanup(self.admin_users_client.delete_user, user['id'])
+        # user can update user in own domain
+        user_update = {
+            'user_id': user['id'],
+            'description': data_utils.arbitrary_string()
+        }
+        self.do_request('update_user', **user_update)
+        # user gets a 403 for nonexistent user
+        user_update = {
+            'user_id': 'fakeuser',
+            'description': data_utils.arbitrary_string()
+        }
+        self.do_request('update_user', expected_status=exceptions.Forbidden,
+                        **user_update)
+
+    def test_identity_delete_user(self):
+        user_create = self.user()
+        # create user in other domain
+        user_create['domain_id'] = self.other_domain['id']
+        user = self.admin_users_client.create_user(**user_create)['user']
+        self.addCleanup(self.admin_users_client.delete_user, user['id'])
+        # user cannot delete user in other domain
+        self.do_request('delete_user', expected_status=exceptions.Forbidden,
+                        user_id=user['id'])
+        # create user in own domain
+        user_create['domain_id'] = self.persona.credentials.domain_id
+        user = self.admin_users_client.create_user(**user_create)['user']
+        # user can delete user in own domain
+        self.do_request('delete_user', expected_status=204, user_id=user['id'])
+        # user gets a 403 for nonexistent user
+        self.do_request('delete_user', expected_status=exceptions.Forbidden,
+                        user_id='fakeuser')
+
+
+class DomainMemberTests(DomainManagerTests):
+
+    credentials = ['domain_member', 'system_admin']
+
+    def test_identity_create_user(self):
+        user_create = self.user()
         # create user without domain specified
         self.do_request('create_user', expected_status=exceptions.Forbidden,
                         **user_create)
@@ -388,9 +494,9 @@
     credentials = ['project_admin', 'system_admin']
 
 
-class ProjectMemberTests(IdentityV3RbacUserTest, base.BaseIdentityTest):
+class ProjectManagerTests(IdentityV3RbacUserTest, base.BaseIdentityTest):
 
-    credentials = ['project_member', 'system_admin']
+    credentials = ['project_manager', 'system_admin']
 
     def test_identity_create_user(self):
         self.do_request('create_user', expected_status=exceptions.Forbidden,
@@ -443,6 +549,11 @@
                         user_id='fakeuser')
 
 
+class ProjectMemberTests(ProjectManagerTests):
+
+    credentials = ['project_member', 'system_admin']
+
+
 class ProjectReaderTests(ProjectMemberTests):
 
     credentials = ['project_reader', 'system_admin']