keycloak-aplcache

auth changes

5/29/2017 10:53:17 AM

Changes

services/src/main/java/org/keycloak/authorization/admin/permissions/MgmtPermissions.java 118(+0 -118)

services/src/main/java/org/keycloak/authorization/admin/permissions/RoleMgmtPermissions.java 208(+0 -208)

services/src/main/java/org/keycloak/authorization/admin/permissions/UsersPermissions.java 246(+0 -246)

Details

diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java
index 47b4db4..3c8552e 100755
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java
@@ -48,6 +48,10 @@ public interface ClientsResource {
 
     @GET
     @Produces(MediaType.APPLICATION_JSON)
+    public List<ClientRepresentation> findAll(@QueryParam("viewableOnly") boolean viewableOnly);
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
     public List<ClientRepresentation> findByClientId(@QueryParam("clientId") String clientId);
 
 
diff --git a/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java b/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java
index a4ff868..d062856 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java
@@ -23,7 +23,7 @@ import org.keycloak.authorization.AuthorizationProvider;
 import org.keycloak.authorization.model.ResourceServer;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.services.resources.admin.RealmAuth;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.Path;
 
@@ -32,22 +32,18 @@ import javax.ws.rs.Path;
  */
 public class AuthorizationService {
 
-    private final RealmAuth auth;
+    private final AdminPermissionEvaluator auth;
     private final ClientModel client;
     private final KeycloakSession session;
     private final ResourceServer resourceServer;
     private final AuthorizationProvider authorization;
 
-    public AuthorizationService(KeycloakSession session, ClientModel client, RealmAuth auth) {
+    public AuthorizationService(KeycloakSession session, ClientModel client, AdminPermissionEvaluator auth) {
         this.session = session;
         this.client = client;
         this.authorization = session.getProvider(AuthorizationProvider.class);
         this.resourceServer = this.authorization.getStoreFactory().getResourceServerStore().findByClient(this.client.getId());
         this.auth = auth;
-
-        if (auth != null) {
-            this.auth.init(RealmAuth.Resource.AUTHORIZATION);
-        }
     }
 
     @Path("/resource-server")
diff --git a/services/src/main/java/org/keycloak/authorization/admin/PermissionService.java b/services/src/main/java/org/keycloak/authorization/admin/PermissionService.java
index 4ada87d..e7f4633 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PermissionService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PermissionService.java
@@ -22,14 +22,14 @@ import java.util.Map;
 import org.keycloak.authorization.AuthorizationProvider;
 import org.keycloak.authorization.model.Policy;
 import org.keycloak.authorization.model.ResourceServer;
-import org.keycloak.services.resources.admin.RealmAuth;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
 public class PermissionService extends PolicyService {
 
-    public PermissionService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
+    public PermissionService(ResourceServer resourceServer, AuthorizationProvider authorization, AdminPermissionEvaluator auth) {
         super(resourceServer, authorization, auth);
     }
 
diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
index 24e1a89..0a913dd 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
@@ -63,14 +63,12 @@ import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.protocol.ProtocolMapper;
-import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 import org.keycloak.representations.idm.authorization.ScopeRepresentation;
 import org.keycloak.services.Urls;
 import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.services.resources.admin.RealmAuth;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.sessions.AuthenticationSessionModel;
 
 /**
@@ -79,13 +77,13 @@ import org.keycloak.sessions.AuthenticationSessionModel;
 public class PolicyEvaluationService {
 
     private final AuthorizationProvider authorization;
-    private final RealmAuth auth;
+    private final AdminPermissionEvaluator auth;
     @Context
     private HttpRequest httpRequest;
 
     private final ResourceServer resourceServer;
 
-    PolicyEvaluationService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
+    PolicyEvaluationService(ResourceServer resourceServer, AuthorizationProvider authorization, AdminPermissionEvaluator auth) {
         this.resourceServer = resourceServer;
         this.authorization = authorization;
         this.auth = auth;
@@ -117,7 +115,7 @@ public class PolicyEvaluationService {
     @Consumes("application/json")
     @Produces("application/json")
     public Response evaluate(PolicyEvaluationRequest evaluationRequest) throws Throwable {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         CloseableKeycloakIdentity identity = createIdentity(evaluationRequest);
         try {
             EvaluationContext evaluationContext = createEvaluationContext(evaluationRequest, identity);
diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java
index 85e0943..51bc2a6 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java
@@ -42,7 +42,7 @@ import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentati
 import org.keycloak.representations.idm.authorization.PolicyRepresentation;
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 import org.keycloak.representations.idm.authorization.ScopeRepresentation;
-import org.keycloak.services.resources.admin.RealmAuth;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.util.JsonSerialization;
 
 /**
@@ -53,9 +53,9 @@ public class PolicyResourceService {
     private final Policy policy;
     protected final ResourceServer resourceServer;
     protected final AuthorizationProvider authorization;
-    protected final RealmAuth auth;
+    protected final AdminPermissionEvaluator auth;
 
-    public PolicyResourceService(Policy policy, ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
+    public PolicyResourceService(Policy policy, ResourceServer resourceServer, AuthorizationProvider authorization, AdminPermissionEvaluator auth) {
         this.policy = policy;
         this.resourceServer = resourceServer;
         this.authorization = authorization;
@@ -67,7 +67,7 @@ public class PolicyResourceService {
     @Produces("application/json")
     @NoCache
     public Response update(String payload) {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
 
         AbstractPolicyRepresentation representation = doCreateRepresentation(payload);
 
@@ -84,7 +84,7 @@ public class PolicyResourceService {
 
     @DELETE
     public Response delete() {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
 
         if (policy == null) {
             return Response.status(Status.NOT_FOUND).build();
@@ -105,7 +105,7 @@ public class PolicyResourceService {
     @Produces("application/json")
     @NoCache
     public Response findById() {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
 
         if (policy == null) {
             return Response.status(Status.NOT_FOUND).build();
@@ -123,7 +123,7 @@ public class PolicyResourceService {
     @Produces("application/json")
     @NoCache
     public Response getDependentPolicies() {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
 
         if (policy == null) {
             return Response.status(Status.NOT_FOUND).build();
@@ -147,7 +147,7 @@ public class PolicyResourceService {
     @Produces("application/json")
     @NoCache
     public Response getScopes() {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
 
         if (policy == null) {
             return Response.status(Status.NOT_FOUND).build();
@@ -168,7 +168,7 @@ public class PolicyResourceService {
     @Produces("application/json")
     @NoCache
     public Response getResources() {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
 
         if (policy == null) {
             return Response.status(Status.NOT_FOUND).build();
@@ -189,7 +189,7 @@ public class PolicyResourceService {
     @Produces("application/json")
     @NoCache
     public Response getAssociatedPolicies() {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
 
         if (policy == null) {
             return Response.status(Status.NOT_FOUND).build();
diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java
index 011aa2d..6ebed11 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java
@@ -52,7 +52,7 @@ import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentati
 import org.keycloak.representations.idm.authorization.PolicyProviderRepresentation;
 import org.keycloak.representations.idm.authorization.PolicyRepresentation;
 import org.keycloak.services.ErrorResponseException;
-import org.keycloak.services.resources.admin.RealmAuth;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.util.JsonSerialization;
 
 /**
@@ -62,9 +62,9 @@ public class PolicyService {
 
     protected final ResourceServer resourceServer;
     protected final AuthorizationProvider authorization;
-    protected final RealmAuth auth;
+    protected final AdminPermissionEvaluator auth;
 
-    public PolicyService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
+    public PolicyService(ResourceServer resourceServer, AuthorizationProvider authorization, AdminPermissionEvaluator auth) {
         this.resourceServer = resourceServer;
         this.authorization = authorization;
         this.auth = auth;
@@ -92,7 +92,7 @@ public class PolicyService {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public Response create(String payload) {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
 
         AbstractPolicyRepresentation representation = doCreateRepresentation(payload);
         Policy policy = create(representation);
@@ -130,7 +130,7 @@ public class PolicyService {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public Response findByName(@QueryParam("name") String name) {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         StoreFactory storeFactory = authorization.getStoreFactory();
 
         if (name == null) {
@@ -157,7 +157,7 @@ public class PolicyService {
                             @QueryParam("permission") Boolean permission,
                             @QueryParam("first") Integer firstResult,
                             @QueryParam("max") Integer maxResult) {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
 
         Map<String, String[]> search = new HashMap<>();
 
@@ -236,7 +236,7 @@ public class PolicyService {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public Response findPolicyProviders() {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         return Response.ok(
                 authorization.getProviderFactories().stream()
                         .map(provider -> {
@@ -254,7 +254,7 @@ public class PolicyService {
 
     @Path("evaluate")
     public PolicyEvaluationService getPolicyEvaluateResource() {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         PolicyEvaluationService resource = new PolicyEvaluationService(this.resourceServer, this.authorization, this.auth);
 
         ResteasyProviderFactory.getInstance().injectProperties(resource);
diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyTypeResourceService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyTypeResourceService.java
index 8756721..71a6695 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PolicyTypeResourceService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyTypeResourceService.java
@@ -24,7 +24,7 @@ import org.keycloak.authorization.model.ResourceServer;
 import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
-import org.keycloak.services.resources.admin.RealmAuth;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.util.JsonSerialization;
 
 /**
@@ -32,7 +32,7 @@ import org.keycloak.util.JsonSerialization;
  */
 public class PolicyTypeResourceService extends PolicyResourceService {
 
-    public PolicyTypeResourceService(Policy policy, ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
+    public PolicyTypeResourceService(Policy policy, ResourceServer resourceServer, AuthorizationProvider authorization, AdminPermissionEvaluator auth) {
         super(policy, resourceServer, authorization, auth);
     }
 
diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyTypeService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyTypeService.java
index c2e4db5..d6868c5 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PolicyTypeService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyTypeService.java
@@ -28,7 +28,7 @@ import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
 import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
-import org.keycloak.services.resources.admin.RealmAuth;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.util.JsonSerialization;
 
 /**
@@ -38,7 +38,7 @@ public class PolicyTypeService extends PolicyService {
 
     private final String type;
 
-    PolicyTypeService(String type, ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
+    PolicyTypeService(String type, ResourceServer resourceServer, AuthorizationProvider authorization, AdminPermissionEvaluator auth) {
         super(resourceServer, authorization, auth);
         this.type = type;
     }
diff --git a/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java b/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java
index 15f1db7..a9dc6e0 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java
@@ -53,7 +53,7 @@ import org.keycloak.representations.idm.authorization.PolicyRepresentation;
 import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
-import org.keycloak.services.resources.admin.RealmAuth;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@@ -61,12 +61,12 @@ import org.keycloak.services.resources.admin.RealmAuth;
 public class ResourceServerService {
 
     private final AuthorizationProvider authorization;
-    private final RealmAuth auth;
+    private final AdminPermissionEvaluator auth;
     private final KeycloakSession session;
     private ResourceServer resourceServer;
     private final ClientModel client;
 
-    public ResourceServerService(AuthorizationProvider authorization, ResourceServer resourceServer, ClientModel client, RealmAuth auth) {
+    public ResourceServerService(AuthorizationProvider authorization, ResourceServer resourceServer, ClientModel client, AdminPermissionEvaluator auth) {
         this.authorization = authorization;
         this.session = authorization.getKeycloakSession();
         this.client = client;
@@ -75,7 +75,7 @@ public class ResourceServerService {
     }
 
     public void create() {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
 
         UserModel serviceAccount = this.session.users().getServiceAccount(client);
 
@@ -92,7 +92,7 @@ public class ResourceServerService {
     @Consumes("application/json")
     @Produces("application/json")
     public Response update(ResourceServerRepresentation server) {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
         this.resourceServer.setAllowRemoteResourceManagement(server.isAllowRemoteResourceManagement());
         this.resourceServer.setPolicyEnforcementMode(server.getPolicyEnforcementMode());
 
@@ -100,7 +100,7 @@ public class ResourceServerService {
     }
 
     public void delete() {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
         StoreFactory storeFactory = authorization.getStoreFactory();
         ResourceStore resourceStore = storeFactory.getResourceStore();
         String id = resourceServer.getId();
@@ -121,7 +121,7 @@ public class ResourceServerService {
     @GET
     @Produces("application/json")
     public Response findById() {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         return Response.ok(toRepresentation(this.resourceServer, this.client)).build();
     }
 
@@ -129,7 +129,7 @@ public class ResourceServerService {
     @GET
     @Produces("application/json")
     public Response exportSettings() {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
         return Response.ok(ExportUtils.exportAuthorizationSettings(session, client)).build();
     }
 
@@ -137,7 +137,7 @@ public class ResourceServerService {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response importSettings(@Context final UriInfo uriInfo, ResourceServerRepresentation rep) throws IOException {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
 
         rep.setClientId(client.getId());
 
@@ -175,7 +175,7 @@ public class ResourceServerService {
 
     @Path("/permission")
     public Object getPermissionTypeResource() {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         PermissionService resource = new PermissionService(this.resourceServer, this.authorization, this.auth);
 
         ResteasyProviderFactory.getInstance().injectProperties(resource);
diff --git a/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java b/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java
index 5d65923..c8eaafe 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java
@@ -37,7 +37,7 @@ import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentatio
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 import org.keycloak.representations.idm.authorization.ScopeRepresentation;
 import org.keycloak.services.ErrorResponse;
-import org.keycloak.services.resources.admin.RealmAuth;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -69,10 +69,10 @@ import static org.keycloak.models.utils.RepresentationToModel.toModel;
 public class ResourceSetService {
 
     private final AuthorizationProvider authorization;
-    private final RealmAuth auth;
+    private final AdminPermissionEvaluator auth;
     private ResourceServer resourceServer;
 
-    public ResourceSetService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
+    public ResourceSetService(ResourceServer resourceServer, AuthorizationProvider authorization, AdminPermissionEvaluator auth) {
         this.resourceServer = resourceServer;
         this.authorization = authorization;
         this.auth = auth;
@@ -272,7 +272,7 @@ public class ResourceSetService {
     @Produces("application/json")
     @NoCache
     public Response find(@QueryParam("name") String name) {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         StoreFactory storeFactory = authorization.getStoreFactory();
 
         if (name == null) {
@@ -367,13 +367,13 @@ public class ResourceSetService {
 
     private void requireView() {
         if (this.auth != null) {
-            this.auth.requireView();
+            this.auth.realm().requireViewAuthorization();
         }
     }
 
     private void requireManage() {
         if (this.auth != null) {
-            this.auth.requireManage();
+            this.auth.realm().requireManageAuthorization();
         }
     }
 }
\ No newline at end of file
diff --git a/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java b/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java
index 1ec9a13..157b3a0 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java
@@ -30,7 +30,7 @@ import org.keycloak.representations.idm.authorization.PolicyRepresentation;
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 import org.keycloak.representations.idm.authorization.ScopeRepresentation;
 import org.keycloak.services.ErrorResponse;
-import org.keycloak.services.resources.admin.RealmAuth;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -60,10 +60,10 @@ import static org.keycloak.models.utils.RepresentationToModel.toModel;
 public class ScopeService {
 
     private final AuthorizationProvider authorization;
-    private final RealmAuth auth;
+    private final AdminPermissionEvaluator auth;
     private ResourceServer resourceServer;
 
-    public ScopeService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
+    public ScopeService(ResourceServer resourceServer, AuthorizationProvider authorization, AdminPermissionEvaluator auth) {
         this.resourceServer = resourceServer;
         this.authorization = authorization;
         this.auth = auth;
@@ -73,7 +73,7 @@ public class ScopeService {
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public Response create(ScopeRepresentation scope) {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
         Scope model = toModel(scope, this.resourceServer, authorization);
 
         scope.setId(model.getId());
@@ -86,7 +86,7 @@ public class ScopeService {
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public Response update(@PathParam("id") String id, ScopeRepresentation scope) {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
         scope.setId(id);
         StoreFactory storeFactory = authorization.getStoreFactory();
         Scope model = storeFactory.getScopeStore().findById(scope.getId(), resourceServer.getId());
@@ -103,7 +103,7 @@ public class ScopeService {
     @Path("{id}")
     @DELETE
     public Response delete(@PathParam("id") String id) {
-        this.auth.requireManage();
+        this.auth.realm().requireManageAuthorization();
         StoreFactory storeFactory = authorization.getStoreFactory();
         List<Resource> resources = storeFactory.getResourceStore().findByScope(Arrays.asList(id), resourceServer.getId());
 
@@ -137,7 +137,7 @@ public class ScopeService {
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     public Response findById(@PathParam("id") String id) {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         Scope model = this.authorization.getStoreFactory().getScopeStore().findById(id, resourceServer.getId());
 
         if (model == null) {
@@ -151,7 +151,7 @@ public class ScopeService {
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     public Response getResources(@PathParam("id") String id) {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         StoreFactory storeFactory = this.authorization.getStoreFactory();
         Scope model = storeFactory.getScopeStore().findById(id, resourceServer.getId());
 
@@ -173,7 +173,7 @@ public class ScopeService {
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     public Response getPermissions(@PathParam("id") String id) {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         StoreFactory storeFactory = this.authorization.getStoreFactory();
         Scope model = storeFactory.getScopeStore().findById(id, resourceServer.getId());
 
@@ -199,7 +199,7 @@ public class ScopeService {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public Response find(@QueryParam("name") String name) {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
         StoreFactory storeFactory = authorization.getStoreFactory();
 
         if (name == null) {
@@ -222,7 +222,7 @@ public class ScopeService {
                             @QueryParam("deep") Boolean deep,
                             @QueryParam("first") Integer firstResult,
                             @QueryParam("max") Integer maxResult) {
-        this.auth.requireView();
+        this.auth.realm().requireViewAuthorization();
 
         if (deep == null) {
             deep = true;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java
index 924b35e..98d4538 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java
@@ -98,4 +98,7 @@ public class AdminAuth {
         return false;
     }
 
+    public enum Resource {
+        CLIENT, USER, REALM, EVENTS, IDENTITY_PROVIDER, IMPERSONATION, AUTHORIZATION
+    }
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java b/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java
index 5ac7593..2154ad6 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java
@@ -26,6 +26,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserLoginFailureModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.services.managers.BruteForceProtector;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -48,7 +49,7 @@ import java.util.Map;
  */
 public class AttackDetectionResource {
     protected static final Logger logger = Logger.getLogger(AttackDetectionResource.class);
-    protected RealmAuth auth;
+    protected AdminPermissionEvaluator auth;
     protected RealmModel realm;
     private AdminEventBuilder adminEvent;
 
@@ -64,12 +65,10 @@ public class AttackDetectionResource {
     @Context
     protected HttpHeaders headers;
 
-    public AttackDetectionResource(RealmAuth auth, RealmModel realm, AdminEventBuilder adminEvent) {
+    public AttackDetectionResource(AdminPermissionEvaluator auth, RealmModel realm, AdminEventBuilder adminEvent) {
         this.auth = auth;
         this.realm = realm;
         this.adminEvent = adminEvent.realm(realm).resource(ResourceType.USER_LOGIN_FAILURE);
-
-        auth.init(RealmAuth.Resource.USER);
     }
 
     /**
@@ -83,7 +82,8 @@ public class AttackDetectionResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Map<String, Object> bruteForceUserStatus(@PathParam("userId") String userId) {
-        auth.requireView();
+        UserModel user = session.users().getUserById(userId, realm);
+        auth.users().requireView(user);
 
         Map<String, Object> data = new HashMap<>();
         data.put("disabled", false);
@@ -92,7 +92,6 @@ public class AttackDetectionResource {
         data.put("lastIPFailure", "n/a");
         if (!realm.isBruteForceProtected()) return data;
 
-        UserModel user = session.users().getUserById(userId, realm);
 
         UserLoginFailureModel model = session.sessions().getUserLoginFailure(realm, userId);
         if (model == null) return data;
@@ -115,10 +114,10 @@ public class AttackDetectionResource {
     @Path("brute-force/users/{userId}")
     @DELETE
     public void clearBruteForceForUser(@PathParam("userId") String userId) {
-        auth.requireManage();
-
         UserLoginFailureModel model = session.sessions().getUserLoginFailure(realm, userId);
         if (model != null) {
+            UserModel user = session.users().getUserById(userId, realm);
+            auth.users().requireView(user);
             session.sessions().removeUserLoginFailure(realm, userId);
             adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
         }
@@ -133,7 +132,7 @@ public class AttackDetectionResource {
     @Path("brute-force/users")
     @DELETE
     public void clearAllBruteForce() {
-        auth.requireManage();
+        auth.users().requireManage();
 
         session.sessions().removeAllUserLoginFailures(realm);
         adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
index 2f7362b..ba7eccc 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
@@ -50,6 +50,7 @@ import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
 import org.keycloak.representations.idm.ConfigPropertyRepresentation;
 import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
 import org.keycloak.services.ErrorResponse;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.utils.CredentialHelper;
 
 import javax.ws.rs.Consumes;
@@ -80,18 +81,17 @@ public class AuthenticationManagementResource {
 
     private final RealmModel realm;
     private final KeycloakSession session;
-    private RealmAuth auth;
+    private AdminPermissionEvaluator auth;
     private AdminEventBuilder adminEvent;
     @Context
     private UriInfo uriInfo;
 
     protected static final Logger logger = Logger.getLogger(AuthenticationManagementResource.class);
 
-    public AuthenticationManagementResource(RealmModel realm, KeycloakSession session, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public AuthenticationManagementResource(RealmModel realm, KeycloakSession session, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.session = session;
         this.auth = auth;
-        this.auth.init(RealmAuth.Resource.REALM);
         this.adminEvent = adminEvent.resource(ResourceType.AUTH_FLOW);
     }
 
@@ -105,7 +105,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<Map<String, Object>> getFormProviders() {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(FormAuthenticator.class);
         return buildProviderMetadata(factories);
@@ -121,7 +121,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<Map<String, Object>> getAuthenticatorProviders() {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(Authenticator.class);
         return buildProviderMetadata(factories);
@@ -137,7 +137,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<Map<String, Object>> getClientAuthenticatorProviders() {
-        auth.requireAny();
+        auth.realm().requireViewRealm();
 
         List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(ClientAuthenticator.class);
         return buildProviderMetadata(factories);
@@ -167,7 +167,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<Map<String, Object>> getFormActionProviders() {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(FormAction.class);
         return buildProviderMetadata(factories);
@@ -184,7 +184,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<AuthenticationFlowRepresentation> getFlows() {
-        auth.requireAny();
+        auth.realm().requireViewRealm();
 
         List<AuthenticationFlowRepresentation> flows = new LinkedList<>();
         for (AuthenticationFlowModel flow : realm.getAuthenticationFlows()) {
@@ -207,7 +207,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Consumes(MediaType.APPLICATION_JSON)
     public Response createFlow(AuthenticationFlowRepresentation flow) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         if (flow.getAlias() == null || flow.getAlias().isEmpty()) {
             return ErrorResponse.exists("Failed to create flow with empty alias name");
@@ -235,7 +235,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public AuthenticationFlowRepresentation getFlow(@PathParam("id") String id) {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         AuthenticationFlowModel flow = realm.getAuthenticationFlowById(id);
         if (flow == null) {
@@ -253,7 +253,7 @@ public class AuthenticationManagementResource {
     @DELETE
     @NoCache
     public void deleteFlow(@PathParam("id") String id) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
         
         deleteFlow(id, true);
     }
@@ -292,7 +292,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Consumes(MediaType.APPLICATION_JSON)
     public Response copy(@PathParam("flowAlias") String flowAlias, Map<String, String> data) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         String newName = data.get("newName");
         if (realm.getFlowByAlias(newName) != null) {
@@ -351,7 +351,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Consumes(MediaType.APPLICATION_JSON)
     public Response addExecutionFlow(@PathParam("flowAlias") String flowAlias, Map<String, String> data) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticationFlowModel parentFlow = realm.getFlowByAlias(flowAlias);
         if (parentFlow == null) {
@@ -403,7 +403,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Consumes(MediaType.APPLICATION_JSON)
     public void addExecution(@PathParam("flowAlias") String flowAlias, Map<String, String> data) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticationFlowModel parentFlow = realm.getFlowByAlias(flowAlias);
         if (parentFlow == null) {
@@ -450,7 +450,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Response getExecutions(@PathParam("flowAlias") String flowAlias) {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias);
         if (flow == null) {
@@ -535,7 +535,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Consumes(MediaType.APPLICATION_JSON)
     public void updateExecutions(@PathParam("flowAlias") String flowAlias, AuthenticationExecutionInfoRepresentation rep) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias);
         if (flow == null) {
@@ -566,7 +566,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Consumes(MediaType.APPLICATION_JSON)
     public Response addExecution(AuthenticationExecutionRepresentation execution) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticationExecutionModel model = RepresentationToModel.toModel(realm, execution);
         AuthenticationFlowModel parentFlow = getParentFlow(model);
@@ -601,7 +601,7 @@ public class AuthenticationManagementResource {
     @POST
     @NoCache
     public void raisePriority(@PathParam("executionId") String execution) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution);
         if (model == null) {
@@ -647,7 +647,7 @@ public class AuthenticationManagementResource {
     @POST
     @NoCache
     public void lowerPriority(@PathParam("executionId") String execution) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution);
         if (model == null) {
@@ -687,7 +687,7 @@ public class AuthenticationManagementResource {
     @DELETE
     @NoCache
     public void removeExecution(@PathParam("executionId") String execution) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution);
         if (model == null) {
@@ -723,7 +723,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Consumes(MediaType.APPLICATION_JSON)
     public Response newExecutionConfig(@PathParam("executionId") String execution, AuthenticatorConfigRepresentation json) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution);
         if (model == null) {
@@ -753,7 +753,7 @@ public class AuthenticationManagementResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public AuthenticatorConfigRepresentation getAuthenticatorConfig(@PathParam("executionId") String execution,@PathParam("id") String id) {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         AuthenticatorConfigModel config = realm.getAuthenticatorConfigById(id);
         if (config == null) {
@@ -773,7 +773,7 @@ public class AuthenticationManagementResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<Map<String, String>> getUnregisteredRequiredActions() {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(RequiredActionProvider.class);
         List<Map<String, String>> unregisteredList = new LinkedList<>();
@@ -807,7 +807,7 @@ public class AuthenticationManagementResource {
     @Consumes(MediaType.APPLICATION_JSON)
     @NoCache
     public void registerRequiredAction(Map<String, String> data) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         String providerId = data.get("providerId");
         String name = data.get("name");
@@ -834,7 +834,7 @@ public class AuthenticationManagementResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RequiredActionProviderRepresentation> getRequiredActions() {
-        auth.requireAny();
+        auth.realm().requireViewRealm();
 
         List<RequiredActionProviderRepresentation> list = new LinkedList<>();
         for (RequiredActionProviderModel model : realm.getRequiredActionProviders()) {
@@ -863,7 +863,7 @@ public class AuthenticationManagementResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public RequiredActionProviderRepresentation getRequiredAction(@PathParam("alias") String alias) {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(alias);
         if (model == null) {
@@ -883,7 +883,7 @@ public class AuthenticationManagementResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public void updateRequiredAction(@PathParam("alias") String alias, RequiredActionProviderRepresentation rep) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(alias);
         if (model == null) {
@@ -909,7 +909,7 @@ public class AuthenticationManagementResource {
     @Path("required-actions/{alias}")
     @DELETE
     public void removeRequiredAction(@PathParam("alias") String alias) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(alias);
         if (model == null) {
@@ -928,7 +928,7 @@ public class AuthenticationManagementResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public AuthenticatorConfigInfoRepresentation getAuthenticatorConfigDescription(@PathParam("providerId") String providerId) {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         ConfigurableAuthenticatorFactory factory = CredentialHelper.getConfigurableAuthenticatorFactory(session, providerId);
         if (factory == null) {
@@ -959,7 +959,7 @@ public class AuthenticationManagementResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public Map<String, List<ConfigPropertyRepresentation>> getPerClientConfigDescription() {
-        auth.requireAny();
+        auth.realm().requireViewRealm();
 
         List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(ClientAuthenticator.class);
 
@@ -991,7 +991,7 @@ public class AuthenticationManagementResource {
     @NoCache
     @Consumes(MediaType.APPLICATION_JSON)
     public Response createAuthenticatorConfig(AuthenticatorConfigRepresentation rep) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticatorConfigModel config = realm.addAuthenticatorConfig(RepresentationToModel.toModel(rep));
         adminEvent.operation(OperationType.CREATE).resource(ResourceType.AUTHENTICATOR_CONFIG).resourcePath(uriInfo, config.getId()).representation(rep).success();
@@ -1007,7 +1007,7 @@ public class AuthenticationManagementResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public AuthenticatorConfigRepresentation getAuthenticatorConfig(@PathParam("id") String id) {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         AuthenticatorConfigModel config = realm.getAuthenticatorConfigById(id);
         if (config == null) {
@@ -1025,7 +1025,7 @@ public class AuthenticationManagementResource {
     @DELETE
     @NoCache
     public void removeAuthenticatorConfig(@PathParam("id") String id) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticatorConfigModel config = realm.getAuthenticatorConfigById(id);
         if (config == null) {
@@ -1057,7 +1057,7 @@ public class AuthenticationManagementResource {
     @Consumes(MediaType.APPLICATION_JSON)
     @NoCache
     public void updateAuthenticatorConfig(@PathParam("id") String id, AuthenticatorConfigRepresentation rep) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         AuthenticatorConfigModel exists = realm.getAuthenticatorConfigById(id);
         if (exists == null) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
index 1f4277b..1de2c9d 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
@@ -37,6 +37,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.representations.KeyStoreConfig;
 import org.keycloak.representations.idm.CertificateRepresentation;
 import org.keycloak.services.ErrorResponseException;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.services.util.CertificateInfoHelper;
 import org.keycloak.util.JWKSUtils;
 import org.keycloak.util.JsonSerialization;
@@ -73,13 +74,13 @@ public class ClientAttributeCertificateResource {
     public static final String JSON_WEB_KEY_SET = "JSON Web Key Set";
 
     protected RealmModel realm;
-    private RealmAuth auth;
+    private AdminPermissionEvaluator auth;
     protected ClientModel client;
     protected KeycloakSession session;
     protected AdminEventBuilder adminEvent;
     protected String attributePrefix;
 
-    public ClientAttributeCertificateResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, String attributePrefix, AdminEventBuilder adminEvent) {
+    public ClientAttributeCertificateResource(RealmModel realm, AdminPermissionEvaluator auth, ClientModel client, KeycloakSession session, String attributePrefix, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
         this.client = client;
@@ -97,11 +98,7 @@ public class ClientAttributeCertificateResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public CertificateRepresentation getKeyInfo() {
-        auth.requireView();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireView(client);
 
         CertificateRepresentation info = CertificateInfoHelper.getCertificateFromClient(client, attributePrefix);
         return info;
@@ -117,11 +114,7 @@ public class ClientAttributeCertificateResource {
     @Path("generate")
     @Produces(MediaType.APPLICATION_JSON)
     public CertificateRepresentation generate() {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         CertificateRepresentation info = KeycloakModelUtils.generateKeyPairCertificate(client.getClientId());
 
@@ -145,11 +138,7 @@ public class ClientAttributeCertificateResource {
     @Consumes(MediaType.MULTIPART_FORM_DATA)
     @Produces(MediaType.APPLICATION_JSON)
     public CertificateRepresentation uploadJks(@Context final UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         try {
             CertificateRepresentation info = getCertFromRequest(input);
@@ -175,11 +164,7 @@ public class ClientAttributeCertificateResource {
     @Consumes(MediaType.MULTIPART_FORM_DATA)
     @Produces(MediaType.APPLICATION_JSON)
     public CertificateRepresentation uploadJksCertificate(@Context final UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         try {
             CertificateRepresentation info = getCertFromRequest(input);
@@ -194,7 +179,7 @@ public class ClientAttributeCertificateResource {
     }
 
     private CertificateRepresentation getCertFromRequest(MultipartFormDataInput input) throws IOException {
-        auth.requireManage();
+        auth.clients().requireManage(client);
         CertificateRepresentation info = new CertificateRepresentation();
         Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
         String keystoreFormat = uploadForm.get("keystoreFormat").get(0).getBodyAsString();
@@ -279,11 +264,7 @@ public class ClientAttributeCertificateResource {
     @Produces(MediaType.APPLICATION_OCTET_STREAM)
     @Consumes(MediaType.APPLICATION_JSON)
     public byte[] getKeystore(final KeyStoreConfig config) {
-        auth.requireView();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireView(client);
 
         if (config.getFormat() != null && !config.getFormat().equals("JKS") && !config.getFormat().equals("PKCS12")) {
             throw new NotAcceptableException("Only support jks or pkcs12 format.");
@@ -322,11 +303,7 @@ public class ClientAttributeCertificateResource {
     @Produces(MediaType.APPLICATION_OCTET_STREAM)
     @Consumes(MediaType.APPLICATION_JSON)
     public byte[] generateAndGetKeystore(final KeyStoreConfig config) {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         if (config.getFormat() != null && !config.getFormat().equals("JKS") && !config.getFormat().equals("PKCS12")) {
             throw new NotAcceptableException("Only support jks or pkcs12 format.");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java
index dfd28cc..65941af 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java
@@ -25,6 +25,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation;
 import org.keycloak.representations.idm.ClientInitialAccessPresentation;
 import org.keycloak.services.clientregistration.ClientRegistrationTokenUtils;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.Consumes;
@@ -48,7 +49,7 @@ import java.util.List;
  */
 public class ClientInitialAccessResource {
 
-    private final RealmAuth auth;
+    private final AdminPermissionEvaluator auth;
     private final RealmModel realm;
     private final AdminEventBuilder adminEvent;
 
@@ -58,12 +59,11 @@ public class ClientInitialAccessResource {
     @Context
     protected UriInfo uriInfo;
 
-    public ClientInitialAccessResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public ClientInitialAccessResource(RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.auth = auth;
         this.realm = realm;
         this.adminEvent = adminEvent.resource(ResourceType.CLIENT_INITIAL_ACCESS_MODEL);
 
-        auth.init(RealmAuth.Resource.CLIENT);
     }
 
     /**
@@ -76,7 +76,7 @@ public class ClientInitialAccessResource {
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public ClientInitialAccessPresentation create(ClientInitialAccessCreatePresentation config, @Context final HttpServletResponse response) {
-        auth.requireManage();
+        auth.clients().requireManage();
 
         int expiration = config.getExpiration() != null ? config.getExpiration() : 0;
         int count = config.getCount() != null ? config.getCount() : 1;
@@ -99,7 +99,7 @@ public class ClientInitialAccessResource {
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     public List<ClientInitialAccessPresentation> list() {
-        auth.requireView();
+        auth.clients().requireView();
 
         List<ClientInitialAccessModel> models = session.sessions().listClientInitialAccess(realm);
         List<ClientInitialAccessPresentation> reps = new LinkedList<>();
@@ -113,7 +113,7 @@ public class ClientInitialAccessResource {
     @DELETE
     @Path("{id}")
     public void delete(final @PathParam("id") String id) {
-        auth.requireManage();
+        auth.clients().requireManage();
 
         session.sessions().removeClientInitialAccessModel(realm, id);
         adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientRegistrationPolicyResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientRegistrationPolicyResource.java
index f8c57e2..9250326 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientRegistrationPolicyResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientRegistrationPolicyResource.java
@@ -37,6 +37,7 @@ import org.keycloak.provider.ProviderFactory;
 import org.keycloak.representations.idm.ComponentTypeRepresentation;
 import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy;
 import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicyFactory;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 /**
  * @resource Client Registration Policy
@@ -44,7 +45,7 @@ import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicyF
  */
 public class ClientRegistrationPolicyResource {
 
-    private final RealmAuth auth;
+    private final AdminPermissionEvaluator auth;
     private final RealmModel realm;
     private final AdminEventBuilder adminEvent;
 
@@ -54,12 +55,11 @@ public class ClientRegistrationPolicyResource {
     @Context
     protected UriInfo uriInfo;
 
-    public ClientRegistrationPolicyResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public ClientRegistrationPolicyResource(RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.auth = auth;
         this.realm = realm;
         this.adminEvent = adminEvent.resource(ResourceType.CLIENT_INITIAL_ACCESS_MODEL);
 
-        auth.init(RealmAuth.Resource.CLIENT);
     }
 
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
index ac5e6d1..ba6bd03 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
@@ -51,6 +51,7 @@ import org.keycloak.services.managers.ClientManager;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.resources.KeycloakApplication;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.services.validation.ClientValidator;
 import org.keycloak.services.validation.PairwiseClientValidator;
 import org.keycloak.services.validation.ValidationMessages;
@@ -89,7 +90,7 @@ import static java.lang.Boolean.TRUE;
 public class ClientResource {
     protected static final Logger logger = Logger.getLogger(ClientResource.class);
     protected RealmModel realm;
-    private RealmAuth auth;
+    private AdminPermissionEvaluator auth;
     private AdminEventBuilder adminEvent;
     protected ClientModel client;
     protected KeycloakSession session;
@@ -104,19 +105,19 @@ public class ClientResource {
         return keycloak;
     }
 
-    public ClientResource(RealmModel realm, RealmAuth auth, ClientModel clientModel, KeycloakSession session, AdminEventBuilder adminEvent) {
+    public ClientResource(RealmModel realm, AdminPermissionEvaluator auth, ClientModel clientModel, KeycloakSession session, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
         this.client = clientModel;
         this.session = session;
         this.adminEvent = adminEvent.resource(ResourceType.CLIENT);
-
-        auth.init(RealmAuth.Resource.CLIENT);
     }
 
     @Path("protocol-mappers")
     public ProtocolMappersResource getProtocolMappers() {
-        ProtocolMappersResource mappers = new ProtocolMappersResource(realm, client, auth, adminEvent);
+        AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.clients().requireManage(client);
+        AdminPermissionEvaluator.RequirePermissionCheck viewCheck = () -> auth.clients().requireView(client);
+        ProtocolMappersResource mappers = new ProtocolMappersResource(realm, client, auth, adminEvent, manageCheck, viewCheck);
         ResteasyProviderFactory.getInstance().injectProperties(mappers);
         return mappers;
     }
@@ -129,15 +130,11 @@ public class ClientResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public Response update(final ClientRepresentation rep) {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         ValidationMessages validationMessages = new ValidationMessages();
         if (!ClientValidator.validate(rep, validationMessages) || !PairwiseClientValidator.validate(session, rep, validationMessages)) {
-            Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale());
+            Properties messages = AdminRoot.getMessages(session, realm, auth.adminAuth().getToken().getLocale());
             throw new ErrorResponseException(
                     validationMessages.getStringMessages(),
                     validationMessages.getStringMessages(messages),
@@ -187,11 +184,7 @@ public class ClientResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public ClientRepresentation getClient() {
-        auth.requireView();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireView(client);
 
         ClientRepresentation representation = ModelToRepresentation.toRepresentation(client);
 
@@ -217,11 +210,7 @@ public class ClientResource {
     @NoCache
     @Path("installation/providers/{providerId}")
     public Response getInstallationProvider(@PathParam("providerId") String providerId) {
-        auth.requireView();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireView(client);
 
         ClientInstallationProvider provider = session.getProvider(ClientInstallationProvider.class, providerId);
         if (provider == null) throw new NotFoundException("Unknown Provider");
@@ -235,7 +224,7 @@ public class ClientResource {
     @DELETE
     @NoCache
     public void deleteClient() {
-        auth.requireManage();
+        auth.clients().requireManage(client);
 
         if (client == null) {
             throw new NotFoundException("Could not find client");
@@ -256,11 +245,7 @@ public class ClientResource {
     @Produces(MediaType.APPLICATION_JSON)
     @Consumes(MediaType.APPLICATION_JSON)
     public CredentialRepresentation regenerateSecret() {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         logger.debug("regenerateSecret");
         UserCredentialModel cred = KeycloakModelUtils.generateSecret(client);
@@ -279,11 +264,7 @@ public class ClientResource {
     @Produces(MediaType.APPLICATION_JSON)
     @Consumes(MediaType.APPLICATION_JSON)
     public ClientRepresentation regenerateRegistrationAccessToken() {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         String token = ClientRegistrationTokenUtils.updateRegistrationAccessToken(session, realm, uriInfo, client, RegistrationAuth.AUTHENTICATED);
 
@@ -304,11 +285,7 @@ public class ClientResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public CredentialRepresentation getClientSecret() {
-        auth.requireView();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireView(client);
 
         logger.debug("getClientSecret");
         UserCredentialModel model = UserCredentialModel.secret(client.getSecret());
@@ -323,12 +300,16 @@ public class ClientResource {
      */
     @Path("scope-mappings")
     public ScopeMappedResource getScopeMappedResource() {
-        return new ScopeMappedResource(realm, auth, client, session, adminEvent);
+        AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.clients().requireManage(client);
+        AdminPermissionEvaluator.RequirePermissionCheck viewCheck = () -> auth.clients().requireView(client);
+        return new ScopeMappedResource(realm, auth, client, session, adminEvent, manageCheck, viewCheck);
     }
 
     @Path("roles")
     public RoleContainerResource getRoleContainerResource() {
-        return new RoleContainerResource(session, uriInfo, realm, auth, client, adminEvent);
+        AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.clients().requireManage(client);
+        AdminPermissionEvaluator.RequirePermissionCheck viewCheck = () -> auth.clients().requireView(client);
+        return new RoleContainerResource(session, uriInfo, realm, auth, client, adminEvent, manageCheck, viewCheck);
     }
 
     /**
@@ -341,11 +322,7 @@ public class ClientResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public UserRepresentation getServiceAccountUser() {
-        auth.requireView();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireView(client);
 
         UserModel user = session.users().getServiceAccount(client);
         if (user == null) {
@@ -369,11 +346,7 @@ public class ClientResource {
     @POST
     @Produces(MediaType.APPLICATION_JSON)
     public GlobalRequestResult pushRevocation() {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).resource(ResourceType.CLIENT).success();
         return new ResourceAdminManager(session).pushClientRevocationPolicy(uriInfo.getRequestUri(), realm, client);
@@ -396,11 +369,7 @@ public class ClientResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Map<String, Long> getApplicationSessionCount() {
-        auth.requireView();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireView(client);
 
         Map<String, Long> map = new HashMap<>();
         map.put("count", session.sessions().getActiveUserSessions(client.getRealm(), client));
@@ -421,11 +390,7 @@ public class ClientResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<UserSessionRepresentation> getUserSessions(@QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) {
-        auth.requireView();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireView(client);
 
         firstResult = firstResult != null ? firstResult : -1;
         maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS;
@@ -453,11 +418,7 @@ public class ClientResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Map<String, Long> getOfflineSessionCount() {
-        auth.requireView();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireView(client);
 
         Map<String, Long> map = new HashMap<>();
         map.put("count", session.sessions().getOfflineSessionsCount(client.getRealm(), client));
@@ -478,11 +439,7 @@ public class ClientResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<UserSessionRepresentation> getOfflineUserSessions(@QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) {
-        auth.requireView();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireView(client);
 
         firstResult = firstResult != null ? firstResult : -1;
         maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS;
@@ -519,11 +476,7 @@ public class ClientResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public void registerNode(Map<String, String> formParams) {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         String node = formParams.get("node");
         if (node == null) {
@@ -543,11 +496,7 @@ public class ClientResource {
     @DELETE
     @NoCache
     public void unregisterNode(final @PathParam("node") String node) {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         if (logger.isDebugEnabled()) logger.debug("Unregister node: " + node);
 
@@ -571,11 +520,7 @@ public class ClientResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public GlobalRequestResult testNodesAvailable() {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.clients().requireManage(client);
 
         logger.debug("Test availability of cluster nodes");
         GlobalRequestResult result = new ResourceAdminManager(session).testNodesAvailability(uriInfo.getRequestUri(), realm, client);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java
index b5f1996..c619669 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java
@@ -19,7 +19,7 @@ package org.keycloak.services.resources.admin;
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.authorization.admin.permissions.MgmtPermissions;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.admin.ResourceType;
 import org.keycloak.models.ClientModel;
@@ -61,30 +61,29 @@ public class ClientRoleMappingsResource {
 
     protected KeycloakSession session;
     protected RealmModel realm;
-    protected RealmAuth auth;
+    protected AdminPermissionEvaluator auth;
     protected RoleMapperModel user;
     protected ClientModel client;
     protected AdminEventBuilder adminEvent;
     private UriInfo uriInfo;
-    private RoleMapperResource.ManageResourcePermissionCheck manageResourcePermissionCheck;
+    protected AdminPermissionEvaluator.RequirePermissionCheck managePermission;
+    protected AdminPermissionEvaluator.RequirePermissionCheck viewPermission;
 
 
-    public ClientRoleMappingsResource(UriInfo uriInfo, KeycloakSession session, RealmModel realm, RealmAuth auth, RoleMapperModel user, ClientModel client, AdminEventBuilder adminEvent) {
+    public ClientRoleMappingsResource(UriInfo uriInfo, KeycloakSession session, RealmModel realm, AdminPermissionEvaluator auth,
+                                      RoleMapperModel user, ClientModel client, AdminEventBuilder adminEvent,
+                                      AdminPermissionEvaluator.RequirePermissionCheck manageCheck, AdminPermissionEvaluator.RequirePermissionCheck viewCheck ) {
         this.uriInfo = uriInfo;
         this.session = session;
         this.realm = realm;
         this.auth = auth;
         this.user = user;
         this.client = client;
+        this.managePermission = manageCheck;
+        this.viewPermission = viewCheck;
         this.adminEvent = adminEvent.resource(ResourceType.CLIENT_ROLE_MAPPING);
     }
 
-    public void setManageCheck(RoleMapperResource.ManageResourcePermissionCheck mapperPermissions) {
-        this.manageResourcePermissionCheck = mapperPermissions;
-    }
-
-
-
     /**
      * Get client-level role mappings for the user, and the app
      *
@@ -94,11 +93,7 @@ public class ClientRoleMappingsResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getClientRoleMappings() {
-        auth.requireView();
-
-        if (user == null || client == null) {
-            throw new NotFoundException("Not found");
-        }
+        viewPermission.require();
 
         Set<RoleModel> mappings = user.getClientRoleMappings(client);
         List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>();
@@ -120,11 +115,8 @@ public class ClientRoleMappingsResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getCompositeClientRoleMappings() {
-        auth.requireView();
+        viewPermission.require();
 
-        if (user == null || client == null) {
-            throw new NotFoundException("Not found");
-        }
 
         Set<RoleModel> roles = client.getRoles();
         List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>();
@@ -144,11 +136,7 @@ public class ClientRoleMappingsResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getAvailableClientRoleMappings() {
-        auth.requireView();
-
-        if (user == null || client == null) {
-            throw new NotFoundException("Not found");
-        }
+        viewPermission.require();
 
         Set<RoleModel> available = client.getRoles();
         available = available.stream().filter(r ->
@@ -171,17 +159,6 @@ public class ClientRoleMappingsResource {
         return mappings;
     }
 
-    private void checkManagePermission() {
-        if (manageResourcePermissionCheck == null) {
-            auth.requireManage();
-        } else {
-            if (!manageResourcePermissionCheck.canManage()) {
-                throw new ForbiddenException();
-            }
-        }
-    }
-
-
     /**
      * Add client-level roles to the user role mapping
      *
@@ -190,11 +167,7 @@ public class ClientRoleMappingsResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public void addClientRoleMapping(List<RoleRepresentation> roles) {
-        checkManagePermission();
-
-        if (user == null || client == null) {
-            throw new NotFoundException("Not found");
-        }
+        managePermission.require();
 
         for (RoleRepresentation role : roles) {
             RoleModel roleModel = client.getRole(role.getName());
@@ -215,7 +188,7 @@ public class ClientRoleMappingsResource {
     }
 
     private boolean canMapRole(RoleModel roleModel) {
-        return new MgmtPermissions(session, realm, auth.getAuth()).roles().canMapRole(roleModel);
+        return auth.roles().canMapRole(roleModel);
     }
 
     /**
@@ -226,11 +199,7 @@ public class ClientRoleMappingsResource {
     @DELETE
     @Consumes(MediaType.APPLICATION_JSON)
     public void deleteClientRoleMapping(List<RoleRepresentation> roles) {
-        checkManagePermission();
-
-        if (user == null || client == null) {
-            throw new NotFoundException("Not found");
-        }
+        managePermission.require();
 
         if (roles == null) {
             Set<RoleModel> roleModels = user.getClientRoleMappings(client);
@@ -257,7 +226,7 @@ public class ClientRoleMappingsResource {
                 try {
                     user.deleteRoleMapping(roleModel);
                 } catch (ModelException me) {
-                    Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale());
+                    Properties messages = AdminRoot.getMessages(session, realm, auth.adminAuth().getToken().getLocale());
                     throw new ErrorResponseException(me.getMessage(), MessageFormat.format(messages.getProperty(me.getMessage(), me.getMessage()), me.getParameters()),
                             Response.Status.BAD_REQUEST);
                 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
index 3fa3c75..e02f225 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
@@ -26,6 +26,7 @@ import org.keycloak.common.Profile;
 import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.admin.ResourceType;
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
@@ -34,14 +35,18 @@ import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.services.ErrorResponse;
 import org.keycloak.services.ErrorResponseException;
+import org.keycloak.services.ForbiddenException;
 import org.keycloak.services.managers.ClientManager;
 import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.services.validation.ClientValidator;
 import org.keycloak.services.validation.PairwiseClientValidator;
 import org.keycloak.services.validation.ValidationMessages;
 
 import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
+import javax.ws.rs.NotFoundException;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
@@ -65,18 +70,17 @@ import java.util.Properties;
 public class ClientsResource {
     protected static final Logger logger = Logger.getLogger(ClientsResource.class);
     protected RealmModel realm;
-    private RealmAuth auth;
+    private AdminPermissionEvaluator auth;
     private AdminEventBuilder adminEvent;
 
     @Context
     protected KeycloakSession session;
 
-    public ClientsResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public ClientsResource(RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
         this.adminEvent = adminEvent.resource(ResourceType.CLIENT);
 
-        auth.init(RealmAuth.Resource.CLIENT);
     }
 
     /**
@@ -85,21 +89,20 @@ public class ClientsResource {
      * Returns a list of clients belonging to the realm
      *
      * @param clientId filter by clientId
+     * @param viewableOnly filter clients that cannot be viewed in full by admin
      */
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
-    public List<ClientRepresentation> getClients(@QueryParam("clientId") String clientId) {
-        auth.requireAny();
-
+    public List<ClientRepresentation> getClients(@QueryParam("clientId") String clientId, @QueryParam("viewableOnly") @DefaultValue("false") boolean viewableOnly) {
         List<ClientRepresentation> rep = new ArrayList<>();
 
         if (clientId == null) {
             List<ClientModel> clientModels = realm.getClients();
-
-            boolean view = auth.hasView();
+            auth.clients().requireList();
+            boolean view = auth.clients().canView();
             for (ClientModel clientModel : clientModels) {
-                if (view) {
+                if (view || auth.clients().canView(clientModel)) {
                     ClientRepresentation representation = ModelToRepresentation.toRepresentation(clientModel);
 
                     if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) {
@@ -111,7 +114,7 @@ public class ClientsResource {
                     }
 
                     rep.add(representation);
-                } else {
+                } else if (!viewableOnly) {
                     ClientRepresentation client = new ClientRepresentation();
                     client.setId(clientModel.getId());
                     client.setClientId(clientModel.getClientId());
@@ -120,9 +123,20 @@ public class ClientsResource {
                 }
             }
         } else {
-            ClientModel client = realm.getClientByClientId(clientId);
-            if (client != null) {
-                rep.add(ModelToRepresentation.toRepresentation(client));
+            ClientModel clientModel = realm.getClientByClientId(clientId);
+            if (clientModel != null) {
+                if (auth.clients().canView(clientModel)) {
+                    rep.add(ModelToRepresentation.toRepresentation(clientModel));
+                } else if (!viewableOnly && auth.clients().canList()){
+                    ClientRepresentation client = new ClientRepresentation();
+                    client.setId(clientModel.getId());
+                    client.setClientId(clientModel.getClientId());
+                    client.setDescription(clientModel.getDescription());
+                    rep.add(client);
+
+                } else {
+                    throw new ForbiddenException();
+                }
             }
         }
         return rep;
@@ -144,11 +158,11 @@ public class ClientsResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response createClient(final @Context UriInfo uriInfo, final ClientRepresentation rep) {
-        auth.requireManage();
+        auth.clients().requireManage();
 
         ValidationMessages validationMessages = new ValidationMessages();
         if (!ClientValidator.validate(rep, validationMessages) || !PairwiseClientValidator.validate(session, rep, validationMessages)) {
-            Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale());
+            Properties messages = AdminRoot.getMessages(session, realm, auth.adminAuth().getToken().getLocale());
             throw new ErrorResponseException(
                     validationMessages.getStringMessages(),
                     validationMessages.getStringMessages(messages),
@@ -190,6 +204,9 @@ public class ClientsResource {
     @Path("{id}")
     public ClientResource getClient(final @PathParam("id") String id) {
         ClientModel clientModel = realm.getClientById(id);
+        if (clientModel == null) {
+            throw new NotFoundException("Could not find client");
+        }
 
         session.getContext().setClient(clientModel);
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java
index f760a41..f076850 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java
@@ -31,6 +31,7 @@ import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.ClientTemplateRepresentation;
 import org.keycloak.services.ErrorResponse;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -54,7 +55,7 @@ import javax.ws.rs.core.UriInfo;
 public class ClientTemplateResource {
     protected static final Logger logger = Logger.getLogger(ClientTemplateResource.class);
     protected RealmModel realm;
-    private RealmAuth auth;
+    private AdminPermissionEvaluator auth;
     private AdminEventBuilder adminEvent;
     protected ClientTemplateModel template;
     protected KeycloakSession session;
@@ -62,19 +63,20 @@ public class ClientTemplateResource {
     @Context
     protected UriInfo uriInfo;
 
-    public ClientTemplateResource(RealmModel realm, RealmAuth auth, ClientTemplateModel template, KeycloakSession session, AdminEventBuilder adminEvent) {
+    public ClientTemplateResource(RealmModel realm, AdminPermissionEvaluator auth, ClientTemplateModel template, KeycloakSession session, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
         this.template = template;
         this.session = session;
         this.adminEvent = adminEvent.resource(ResourceType.CLIENT_TEMPLATE);
 
-        auth.init(RealmAuth.Resource.CLIENT);
     }
 
     @Path("protocol-mappers")
     public ProtocolMappersResource getProtocolMappers() {
-        ProtocolMappersResource mappers = new ProtocolMappersResource(realm, template, auth, adminEvent);
+        AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.clients().requireManage(template);
+        AdminPermissionEvaluator.RequirePermissionCheck viewCheck = () -> auth.clients().requireView(template);
+        ProtocolMappersResource mappers = new ProtocolMappersResource(realm, template, auth, adminEvent, manageCheck, viewCheck);
         ResteasyProviderFactory.getInstance().injectProperties(mappers);
         return mappers;
     }
@@ -86,7 +88,9 @@ public class ClientTemplateResource {
      */
     @Path("scope-mappings")
     public ScopeMappedResource getScopeMappedResource() {
-        return new ScopeMappedResource(realm, auth, template, session, adminEvent);
+        AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.clients().requireManage(template);
+        AdminPermissionEvaluator.RequirePermissionCheck viewCheck = () -> auth.clients().requireView(template);
+        return new ScopeMappedResource(realm, auth, template, session, adminEvent, manageCheck, viewCheck);
     }
 
     /**
@@ -97,11 +101,7 @@ public class ClientTemplateResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public Response update(final ClientTemplateRepresentation rep) {
-        auth.requireManage();
-
-        if (template == null) {
-            throw new NotFoundException("Could not find client template");
-        }
+        auth.clients().requireManageTemplates();
 
         try {
             RepresentationToModel.updateClientTemplate(rep, template);
@@ -125,11 +125,8 @@ public class ClientTemplateResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public ClientTemplateRepresentation getClient() {
-        auth.requireView();
+        auth.clients().requireView(template);
 
-        if (template == null) {
-            throw new NotFoundException("Could not find client template");
-        }
 
         return ModelToRepresentation.toRepresentation(template);
     }
@@ -141,11 +138,7 @@ public class ClientTemplateResource {
     @DELETE
     @NoCache
     public Response deleteClientTemplate() {
-        auth.requireManage();
-
-        if (template == null) {
-            throw new NotFoundException("Could not find client template");
-        }
+        auth.clients().requireManage(template);
 
         try {
             realm.removeClientTemplate(template.getId());
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java
index 5e27712..954f0c8 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java
@@ -18,6 +18,7 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.admin.ResourceType;
@@ -29,6 +30,7 @@ import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.ClientTemplateRepresentation;
 import org.keycloak.services.ErrorResponse;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
@@ -53,18 +55,16 @@ import java.util.List;
 public class ClientTemplatesResource {
     protected static final Logger logger = Logger.getLogger(ClientTemplatesResource.class);
     protected RealmModel realm;
-    private RealmAuth auth;
+    private AdminPermissionEvaluator auth;
     private AdminEventBuilder adminEvent;
 
     @Context
     protected KeycloakSession session;
 
-    public ClientTemplatesResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public ClientTemplatesResource(RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
         this.adminEvent = adminEvent.resource(ResourceType.CLIENT_TEMPLATE);
-
-        auth.init(RealmAuth.Resource.CLIENT);
     }
 
     /**
@@ -76,22 +76,14 @@ public class ClientTemplatesResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<ClientTemplateRepresentation> getClientTemplates() {
-        auth.requireView();
 
         List<ClientTemplateRepresentation> rep = new ArrayList<>();
         List<ClientTemplateModel> clientModels = realm.getClientTemplates();
 
-        boolean view = auth.hasView();
+        boolean view = auth.clients().canViewTemplates();
         for (ClientTemplateModel clientModel : clientModels) {
-            if (view) {
+            if (view || auth.clients().canView(clientModel)) {
                 rep.add(ModelToRepresentation.toRepresentation(clientModel));
-            } else {
-                ClientTemplateRepresentation client = new ClientTemplateRepresentation();
-                client.setId(clientModel.getId());
-                client.setName(clientModel.getName());
-                client.setDescription(clientModel.getDescription());
-                client.setProtocol(clientModel.getProtocol());
-                rep.add(client);
             }
         }
         return rep;
@@ -109,7 +101,7 @@ public class ClientTemplatesResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response createClientTemplate(final @Context UriInfo uriInfo, final ClientTemplateRepresentation rep) {
-        auth.requireManage();
+        auth.clients().requireManageTemplates();
 
         try {
             ClientTemplateModel clientModel = RepresentationToModel.createClientTemplate(session, realm, rep);
@@ -131,6 +123,9 @@ public class ClientTemplatesResource {
     @Path("{id}")
     public ClientTemplateResource getClient(final @PathParam("id") String id) {
         ClientTemplateModel clientModel = realm.getClientTemplateById(id);
+        if (clientModel == null) {
+            throw new NotFoundException("Could not find client template");
+        }
         ClientTemplateResource clientResource = new ClientTemplateResource(realm, auth, clientModel, session, adminEvent);
         ResteasyProviderFactory.getInstance().injectProperties(clientResource);
         return clientResource;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ComponentResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ComponentResource.java
index b39b773..c532245 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/ComponentResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ComponentResource.java
@@ -38,7 +38,7 @@ import org.keycloak.representations.idm.ComponentRepresentation;
 import org.keycloak.representations.idm.ComponentTypeRepresentation;
 import org.keycloak.representations.idm.ConfigPropertyRepresentation;
 import org.keycloak.services.ErrorResponse;
-import org.keycloak.services.ErrorResponseException;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.BadRequestException;
 import javax.ws.rs.Consumes;
@@ -63,7 +63,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import java.util.stream.Collectors;
 
 /**
  * @resource Component
@@ -75,7 +74,7 @@ public class ComponentResource {
 
     protected RealmModel realm;
 
-    private RealmAuth auth;
+    private AdminPermissionEvaluator auth;
 
     private AdminEventBuilder adminEvent;
 
@@ -91,12 +90,10 @@ public class ComponentResource {
     @Context
     protected HttpHeaders headers;
 
-    public ComponentResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public ComponentResource(RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.auth = auth;
         this.realm = realm;
         this.adminEvent = adminEvent.resource(ResourceType.COMPONENT);
-
-        auth.init(RealmAuth.Resource.REALM);
     }
 
     @GET
@@ -105,7 +102,7 @@ public class ComponentResource {
     public List<ComponentRepresentation> getComponents(@QueryParam("parent") String parent,
                                                        @QueryParam("type") String type,
                                                        @QueryParam("name") String name) {
-        auth.requireView();
+        auth.realm().requireViewRealm();
         List<ComponentModel> components = Collections.EMPTY_LIST;
         if (parent == null && type == null) {
             components = realm.getComponents();
@@ -135,7 +132,7 @@ public class ComponentResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response create(ComponentRepresentation rep) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
         try {
             ComponentModel model = RepresentationToModel.toModel(session, rep);
             if (model.getParentId() == null) model.setParentId(realm.getId());
@@ -156,7 +153,7 @@ public class ComponentResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public ComponentRepresentation getComponent(@PathParam("id") String id) {
-        auth.requireView();
+        auth.realm().requireViewRealm();
         ComponentModel model = realm.getComponent(id);
         if (model == null) {
             throw new NotFoundException("Could not find component");
@@ -169,7 +166,7 @@ public class ComponentResource {
     @Path("{id}")
     @Consumes(MediaType.APPLICATION_JSON)
     public Response updateComponent(@PathParam("id") String id, ComponentRepresentation rep) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
         try {
             ComponentModel model = realm.getComponent(id);
             if (model == null) {
@@ -188,7 +185,7 @@ public class ComponentResource {
     @DELETE
     @Path("{id}")
     public void removeComponent(@PathParam("id") String id) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
         ComponentModel model = realm.getComponent(id);
         if (model == null) {
             throw new NotFoundException("Could not find component");
@@ -199,7 +196,7 @@ public class ComponentResource {
     }
 
     private Response localizedErrorResponse(ComponentValidationException cve) {
-        Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale(), "admin-messages", "messages");
+        Properties messages = AdminRoot.getMessages(session, realm, auth.adminAuth().getToken().getLocale(), "admin-messages", "messages");
 
         Object[] localizedParameters = cve.getParameters()==null ? null : Arrays.asList(cve.getParameters()).stream().map((Object parameter) -> {
 
@@ -228,7 +225,7 @@ public class ComponentResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<ComponentTypeRepresentation> getSubcomponentConfig(@PathParam("id") String parentId, @QueryParam("type") String subtype) {
-        auth.requireView();
+        auth.realm().requireViewRealm();
         ComponentModel parent = realm.getComponent(parentId);
         if (parent == null) {
             throw new NotFoundException("Could not find parent component");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java
index c9fe194..a529a48 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java
@@ -49,6 +49,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.keycloak.services.ErrorResponse;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 /**
  * @resource Groups
@@ -58,11 +59,11 @@ public class GroupResource {
 
     private final RealmModel realm;
     private final KeycloakSession session;
-    private final RealmAuth auth;
+    private final AdminPermissionEvaluator auth;
     private final AdminEventBuilder adminEvent;
     private final GroupModel group;
 
-    public GroupResource(RealmModel realm, GroupModel group, KeycloakSession session, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public GroupResource(RealmModel realm, GroupModel group, KeycloakSession session, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.session = session;
         this.auth = auth;
@@ -81,11 +82,7 @@ public class GroupResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public GroupRepresentation getGroup() {
-        this.auth.requireView();
-
-        if (group == null) {
-            throw new NotFoundException("Could not find group by id");
-        }
+        this.auth.groups().requireView(group);
 
         return ModelToRepresentation.toGroupHierarchy(group, true);
     }
@@ -98,11 +95,7 @@ public class GroupResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public void updateGroup(GroupRepresentation rep) {
-        this.auth.requireManage();
-
-        if (group == null) {
-            throw new NotFoundException("Could not find group by id");
-        }
+        this.auth.groups().requireManage(group);
 
         updateGroup(rep, group);
         adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
@@ -112,11 +105,7 @@ public class GroupResource {
 
     @DELETE
     public void deleteGroup() {
-        this.auth.requireManage();
-
-        if (group == null) {
-            throw new NotFoundException("Could not find group by id");
-        }
+        this.auth.groups().requireManage(group);
 
         realm.removeGroup(group);
         adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
@@ -135,12 +124,8 @@ public class GroupResource {
     @Produces(MediaType.APPLICATION_JSON)
     @Consumes(MediaType.APPLICATION_JSON)
     public Response addChild(GroupRepresentation rep) {
-        this.auth.requireManage();
+        this.auth.groups().requireManage(group);
 
-        if (group == null) {
-            throw new NotFoundException("Could not find group by id");
-        }
-        
         for (GroupModel group : group.getSubGroups()) {
             if (group.getName().equals(rep.getName())) {
                 return ErrorResponse.exists("Parent already contains subgroup named '" + rep.getName() + "'");
@@ -191,9 +176,9 @@ public class GroupResource {
 
     @Path("role-mappings")
     public RoleMapperResource getRoleMappings() {
-        auth.init(RealmAuth.Resource.USER);
-
-        RoleMapperResource resource =  new RoleMapperResource(realm, auth, group, adminEvent);
+        AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.groups().requireManage(group);
+        AdminPermissionEvaluator.RequirePermissionCheck viewCheck = () -> auth.groups().requireView(group);
+        RoleMapperResource resource =  new RoleMapperResource(realm, auth, group, adminEvent, manageCheck, viewCheck);
         ResteasyProviderFactory.getInstance().injectProperties(resource);
         return resource;
 
@@ -214,11 +199,8 @@ public class GroupResource {
     @Produces(MediaType.APPLICATION_JSON)
     public List<UserRepresentation> getMembers(@QueryParam("first") Integer firstResult,
                                                @QueryParam("max") Integer maxResults) {
-        auth.requireView();
+        this.auth.groups().requireViewMembers(group);
 
-        if (group == null) {
-            throw new NotFoundException("Could not find group by id");
-        }
 
         firstResult = firstResult != null ? firstResult : 0;
         maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java
index 5be1c0d..2a1909b 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java
@@ -40,6 +40,7 @@ import javax.ws.rs.core.UriInfo;
 import java.net.URI;
 import java.util.List;
 import org.keycloak.services.ErrorResponse;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 /**
  * @resource Groups
@@ -49,15 +50,14 @@ public class GroupsResource {
 
     private final RealmModel realm;
     private final KeycloakSession session;
-    private final RealmAuth auth;
+    private final AdminPermissionEvaluator auth;
     private final AdminEventBuilder adminEvent;
 
-    public GroupsResource(RealmModel realm, KeycloakSession session, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public GroupsResource(RealmModel realm, KeycloakSession session, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.session = session;
         this.auth = auth;
         this.adminEvent = adminEvent.resource(ResourceType.GROUP);
-        auth.init(RealmAuth.Resource.USER);
 
     }
 
@@ -72,7 +72,7 @@ public class GroupsResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<GroupRepresentation> getGroups() {
-        auth.requireView();
+        auth.groups().requireList();
 
         return ModelToRepresentation.toGroupHierarchy(realm, false);
     }
@@ -85,9 +85,10 @@ public class GroupsResource {
      */
     @Path("{id}")
     public GroupResource getGroupById(@PathParam("id") String id) {
-        auth.requireView();
-
         GroupModel group = realm.getGroupById(id);
+        if (group == null) {
+            throw new NotFoundException("Could not find group by id");
+        }
         GroupResource resource =  new GroupResource(realm, group, session, this.auth, adminEvent);
         ResteasyProviderFactory.getInstance().injectProperties(resource);
         return resource;
@@ -102,7 +103,7 @@ public class GroupsResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response addTopLevelGroup(GroupRepresentation rep) {
-        auth.requireManage();
+        auth.groups().requireManage();
 
         for (GroupModel group : realm.getGroups()) {
             if (group.getName().equals(rep.getName())) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
index aa4a054..4c08c20 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
@@ -44,6 +44,7 @@ import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
 import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation;
 import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.services.ErrorResponse;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -72,7 +73,7 @@ public class IdentityProviderResource {
 
     protected static final Logger logger = Logger.getLogger(IdentityProviderResource.class);
 
-    private final RealmAuth auth;
+    private final AdminPermissionEvaluator auth;
     private final RealmModel realm;
     private final KeycloakSession session;
     private final IdentityProviderModel identityProviderModel;
@@ -80,7 +81,7 @@ public class IdentityProviderResource {
 
     @Context private UriInfo uriInfo;
 
-    public IdentityProviderResource(RealmAuth auth, RealmModel realm, KeycloakSession session, IdentityProviderModel identityProviderModel, AdminEventBuilder adminEvent) {
+    public IdentityProviderResource(AdminPermissionEvaluator auth, RealmModel realm, KeycloakSession session, IdentityProviderModel identityProviderModel, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.session = session;
         this.identityProviderModel = identityProviderModel;
@@ -97,7 +98,7 @@ public class IdentityProviderResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public IdentityProviderRepresentation getIdentityProvider() {
-        this.auth.requireView();
+        this.auth.realm().requireViewIdentityProviders();
 
         if (identityProviderModel == null) {
             throw new javax.ws.rs.NotFoundException();
@@ -115,7 +116,7 @@ public class IdentityProviderResource {
     @DELETE
     @NoCache
     public Response delete() {
-        this.auth.requireManage();
+        this.auth.realm().requireManageIdentityProviders();
 
         if (identityProviderModel == null) {
             throw new javax.ws.rs.NotFoundException();
@@ -138,7 +139,7 @@ public class IdentityProviderResource {
     @Consumes(MediaType.APPLICATION_JSON)
     @NoCache
     public Response update(IdentityProviderRepresentation providerRep) {
-        this.auth.requireManage();
+        this.auth.realm().requireManageIdentityProviders();
 
         if (identityProviderModel == null) {
             throw new javax.ws.rs.NotFoundException();
@@ -229,7 +230,7 @@ public class IdentityProviderResource {
     @Path("export")
     @NoCache
     public Response export(@Context UriInfo uriInfo, @QueryParam("format") String format) {
-        this.auth.requireView();
+        this.auth.realm().requireViewIdentityProviders();
 
         if (identityProviderModel == null) {
             throw new javax.ws.rs.NotFoundException();
@@ -250,7 +251,7 @@ public class IdentityProviderResource {
     @Path("mapper-types")
     @NoCache
     public Map<String, IdentityProviderMapperTypeRepresentation> getMapperTypes() {
-        this.auth.requireView();
+        this.auth.realm().requireViewIdentityProviders();
 
         if (identityProviderModel == null) {
             throw new javax.ws.rs.NotFoundException();
@@ -289,7 +290,7 @@ public class IdentityProviderResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<IdentityProviderMapperRepresentation> getMappers() {
-        this.auth.requireView();
+        this.auth.realm().requireViewIdentityProviders();
 
         if (identityProviderModel == null) {
             throw new javax.ws.rs.NotFoundException();
@@ -312,7 +313,7 @@ public class IdentityProviderResource {
     @Path("mappers")
     @Consumes(MediaType.APPLICATION_JSON)
     public Response addMapper(IdentityProviderMapperRepresentation mapper) {
-        auth.requireManage();
+        this.auth.realm().requireManageIdentityProviders();
 
         if (identityProviderModel == null) {
             throw new javax.ws.rs.NotFoundException();
@@ -343,7 +344,7 @@ public class IdentityProviderResource {
     @Path("mappers/{id}")
     @Produces(MediaType.APPLICATION_JSON)
     public IdentityProviderMapperRepresentation getMapperById(@PathParam("id") String id) {
-        auth.requireView();
+        this.auth.realm().requireViewIdentityProviders();
 
         if (identityProviderModel == null) {
             throw new javax.ws.rs.NotFoundException();
@@ -365,7 +366,7 @@ public class IdentityProviderResource {
     @Path("mappers/{id}")
     @Consumes(MediaType.APPLICATION_JSON)
     public void update(@PathParam("id") String id, IdentityProviderMapperRepresentation rep) {
-        auth.requireManage();
+        this.auth.realm().requireManageIdentityProviders();
 
         if (identityProviderModel == null) {
             throw new javax.ws.rs.NotFoundException();
@@ -388,7 +389,7 @@ public class IdentityProviderResource {
     @NoCache
     @Path("mappers/{id}")
     public void delete(@PathParam("id") String id) {
-        auth.requireManage();
+        this.auth.realm().requireManageIdentityProviders();
 
         if (identityProviderModel == null) {
             throw new javax.ws.rs.NotFoundException();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
index c5250ac..646b463 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
@@ -37,6 +37,7 @@ import org.keycloak.models.utils.StripSecretsUtils;
 import org.keycloak.provider.ProviderFactory;
 import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.services.ErrorResponse;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.BadRequestException;
 import javax.ws.rs.Consumes;
@@ -65,14 +66,13 @@ public class IdentityProvidersResource {
 
     private final RealmModel realm;
     private final KeycloakSession session;
-    private RealmAuth auth;
+    private AdminPermissionEvaluator auth;
     private AdminEventBuilder adminEvent;
 
-    public IdentityProvidersResource(RealmModel realm, KeycloakSession session, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public IdentityProvidersResource(RealmModel realm, KeycloakSession session, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.session = session;
         this.auth = auth;
-        this.auth.init(RealmAuth.Resource.IDENTITY_PROVIDER);
         this.adminEvent = adminEvent.resource(ResourceType.IDENTITY_PROVIDER);
     }
 
@@ -87,7 +87,7 @@ public class IdentityProvidersResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Response getIdentityProviders(@PathParam("provider_id") String providerId) {
-        this.auth.requireView();
+        this.auth.realm().requireViewIdentityProviders();
         IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
         if (providerFactory != null) {
             return Response.ok(providerFactory).build();
@@ -108,7 +108,7 @@ public class IdentityProvidersResource {
     @Consumes(MediaType.MULTIPART_FORM_DATA)
     @Produces(MediaType.APPLICATION_JSON)
     public Map<String, String> importFrom(@Context UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
-        this.auth.requireManage();
+        this.auth.realm().requireManageIdentityProviders();
         Map<String, List<InputPart>> formDataMap = input.getFormDataMap();
         if (!(formDataMap.containsKey("providerId") && formDataMap.containsKey("file"))) {
             throw new BadRequestException();
@@ -134,7 +134,7 @@ public class IdentityProvidersResource {
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public Map<String, String> importFrom(@Context UriInfo uriInfo, Map<String, Object> data) throws IOException {
-        this.auth.requireManage();
+        this.auth.realm().requireManageIdentityProviders();
         if (!(data.containsKey("providerId") && data.containsKey("fromUrl"))) {
             throw new BadRequestException();
         }
@@ -164,7 +164,7 @@ public class IdentityProvidersResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<IdentityProviderRepresentation> getIdentityProviders() {
-        this.auth.requireView();
+        this.auth.realm().requireViewIdentityProviders();
 
         List<IdentityProviderRepresentation> representations = new ArrayList<IdentityProviderRepresentation>();
 
@@ -185,7 +185,7 @@ public class IdentityProvidersResource {
     @Path("instances")
     @Consumes(MediaType.APPLICATION_JSON)
     public Response create(@Context UriInfo uriInfo, IdentityProviderRepresentation representation) {
-        this.auth.requireManage();
+        this.auth.realm().requireManageIdentityProviders();
 
         try {
             IdentityProviderModel identityProvider = RepresentationToModel.toModel(realm, representation);
@@ -203,7 +203,7 @@ public class IdentityProvidersResource {
 
     @Path("instances/{alias}")
     public IdentityProviderResource getIdentityProvider(@PathParam("alias") String alias) {
-        this.auth.requireView();
+        this.auth.realm().requireViewIdentityProviders();
         IdentityProviderModel identityProviderModel = null;
 
         for (IdentityProviderModel storedIdentityProvider : this.realm.getIdentityProviders()) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/KeyResource.java b/services/src/main/java/org/keycloak/services/resources/admin/KeyResource.java
index f2c9401..d990fd1 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/KeyResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/KeyResource.java
@@ -26,6 +26,7 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeyManager;
 import org.keycloak.models.RealmModel;
 import org.keycloak.representations.idm.KeysMetadataRepresentation;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Produces;
@@ -43,9 +44,9 @@ public class KeyResource {
 
     private RealmModel realm;
     private KeycloakSession session;
-    private RealmAuth auth;
+    private AdminPermissionEvaluator auth;
 
-    public KeyResource(RealmModel realm, KeycloakSession session, RealmAuth auth) {
+    public KeyResource(RealmModel realm, KeycloakSession session, AdminPermissionEvaluator auth) {
         this.realm = realm;
         this.session = session;
         this.auth = auth;
@@ -55,7 +56,7 @@ public class KeyResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public KeysMetadataRepresentation getKeyMetadata() {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         KeyManager keystore = session.keys();
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionEvaluator.java
new file mode 100644
index 0000000..56be4cf
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionEvaluator.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.services.resources.admin.AdminAuth;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface AdminPermissionEvaluator {
+    RealmPermissionEvaluator realm();
+
+    AdminAuth adminAuth();
+
+    RolePermissionEvaluator roles();
+    UserPermissionEvaluator users();
+    ClientPermissionEvaluator clients();
+    GroupPermissionEvaluator groups();
+
+    /**
+     * Useful as a function pointer, i.e. RoleMapperResource is reused bewteen GroupResource and UserResource to manage role mappings.
+     * We don't know what type of resource we're managing here (user or group), so we don't know how to query the policy engine to determine
+     * if an action is allowed.
+     *
+     */
+    interface PermissionCheck {
+        boolean evaluate();
+    }
+    /**
+     * Useful as a function pointer, i.e. RoleMapperResource is reused bewteen GroupResource and UserResource to manage role mappings.
+     * We don't know what type of resource we're managing here (user or group), so we don't know how to query the policy engine to determine
+     * if an action is allowed.
+     *
+     * throws appropriate exception if permission is deny
+     *
+     */
+    interface RequirePermissionCheck {
+        void require();
+    }
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionManagement.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionManagement.java
new file mode 100644
index 0000000..1f0a34d
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissionManagement.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.authorization.model.ResourceServer;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface AdminPermissionManagement {
+    public static final String MANAGE_SCOPE = "manage";
+    public static final String VIEW_SCOPE = "view";
+
+    RolePermissionManagement roles();
+    UserPermissionManagement users();
+    GroupPermissionManagement groups();
+    ClientPermissionManagement clients();
+
+    ResourceServer realmResourceServer();
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissions.java
new file mode 100644
index 0000000..61a8bff
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/AdminPermissions.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.services.resources.admin.AdminAuth;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class AdminPermissions {
+
+
+    public static AdminPermissionEvaluator evaluator(KeycloakSession session, RealmModel realm, AdminAuth auth) {
+        return new MgmtPermissions(session, realm, auth);
+    }
+    public static AdminPermissionEvaluator evaluator(KeycloakSession session, RealmModel realm, RealmModel adminsRealm, UserModel admin) {
+        return new MgmtPermissions(session, realm, adminsRealm, admin);
+    }
+
+    public static AdminPermissionManagement management(KeycloakSession session, RealmModel realm) {
+        return new MgmtPermissions(session, realm);
+    }
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissionEvaluator.java
new file mode 100644
index 0000000..8f0af4b
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissionEvaluator.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientTemplateModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface ClientPermissionEvaluator {
+    boolean isPermissionsEnabled(ClientModel client);
+
+    void setPermissionsEnabled(ClientModel client, boolean enable);
+
+    boolean canManage();
+
+    void requireManage();
+
+    boolean canManageTemplates();
+
+    void requireManageTemplates();
+
+    boolean canView();
+
+    boolean canList();
+
+    boolean canViewTemplates();
+
+    void requireList();
+
+    boolean canListTemplates();
+
+    void requireView();
+
+    void requireViewTemplates();
+
+    boolean canManage(ClientModel client);
+
+    void requireManage(ClientModel client);
+
+    boolean canView(ClientModel client);
+
+    void requireView(ClientModel client);
+
+    boolean canManage(ClientTemplateModel template);
+
+    void requireManage(ClientTemplateModel template);
+
+    boolean canView(ClientTemplateModel template);
+
+    void requireView(ClientTemplateModel template);
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissionManagement.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissionManagement.java
new file mode 100644
index 0000000..27f5527
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissionManagement.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.models.ClientModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface ClientPermissionManagement {
+    boolean isPermissionsEnabled(ClientModel client);
+
+    void setPermissionsEnabled(ClientModel client, boolean enable);
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java
new file mode 100644
index 0000000..da1d24b
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.jboss.logging.Logger;
+import org.keycloak.authorization.AuthorizationProvider;
+import org.keycloak.authorization.model.Policy;
+import org.keycloak.authorization.model.Resource;
+import org.keycloak.authorization.model.ResourceServer;
+import org.keycloak.authorization.model.Scope;
+import org.keycloak.models.AdminRoles;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientTemplateModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.services.ForbiddenException;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Manages default policies for all users.
+ *
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionManagement {
+    private static final Logger logger = Logger.getLogger(ClientPermissions.class);
+    protected final KeycloakSession session;
+    protected final RealmModel realm;
+    protected final AuthorizationProvider authz;
+    protected final MgmtPermissions root;
+
+    public ClientPermissions(KeycloakSession session, RealmModel realm, AuthorizationProvider authz, MgmtPermissions root) {
+        this.session = session;
+        this.realm = realm;
+        this.authz = authz;
+        this.root = root;
+    }
+
+    private String getResourceName(ClientModel client) {
+        return "group.resource." + client.getId();
+    }
+
+    private String getManagePermissionName(ClientModel client) {
+        return "manage.permission.client." + client.getId();
+    }
+    private String getViewPermissionName(ClientModel client) {
+        return "view.permission.client." + client.getId();
+    }
+
+    private void initialize(ClientModel client) {
+        ResourceServer server = root.findOrCreateResourceServer(client);
+        Scope manageScope = manageScope(server);
+        if (manageScope == null) {
+            authz.getStoreFactory().getScopeStore().create(AdminPermissionManagement.MANAGE_SCOPE, server);
+        }
+        Scope viewScope = viewScope(server);
+        if (manageScope == null) {
+            authz.getStoreFactory().getScopeStore().create(AdminPermissionManagement.VIEW_SCOPE, server);
+        }
+
+        String resourceName = getResourceName(client);
+        Resource resource = authz.getStoreFactory().getResourceStore().findByName(resourceName, server.getId());
+        if (resource == null) {
+            resource = authz.getStoreFactory().getResourceStore().create(resourceName, server, server.getClientId());
+            Set<Scope> scopeset = new HashSet<>();
+            scopeset.add(manageScope);
+            scopeset.add(viewScope);
+            resource.updateScopes(scopeset);
+        }
+        String managePermissionName = getManagePermissionName(client);
+        Policy managePermission = authz.getStoreFactory().getPolicyStore().findByName(managePermissionName, server.getId());
+        if (managePermission == null) {
+            RoleModel role = root.getRealmManagementClient().getRole(AdminRoles.MANAGE_CLIENTS);
+            Policy manageClientsPolicy = root.roles().rolePolicy(server, role);
+            Helper.addScopePermission(authz, server, managePermissionName, resource, manageScope, manageClientsPolicy);
+        }
+        String viewPermissionName = getViewPermissionName(client);
+        Policy viewPermission = authz.getStoreFactory().getPolicyStore().findByName(viewPermissionName, server.getId());
+        if (viewPermission == null) {
+            RoleModel role = root.getRealmManagementClient().getRole(AdminRoles.VIEW_CLIENTS);
+            Policy viewClientsPolicy = root.roles().rolePolicy(server, role);
+            Helper.addScopePermission(authz, server, viewPermissionName, resource, viewScope, viewClientsPolicy);
+        }
+    }
+
+    private void deletePermissions(ClientModel client) {
+        ResourceServer server = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId());
+        if (server == null) return;
+        Policy managePermission = authz.getStoreFactory().getPolicyStore().findByName(getManagePermissionName(client), server.getId());
+        if (managePermission != null) {
+            authz.getStoreFactory().getPolicyStore().delete(managePermission.getId());
+        }
+        Policy viewPermission = authz.getStoreFactory().getPolicyStore().findByName(getViewPermissionName(client), server.getId());
+        if (viewPermission != null) {
+            authz.getStoreFactory().getPolicyStore().delete(viewPermission.getId());
+        }
+        Resource resource = authz.getStoreFactory().getResourceStore().findByName(getResourceName(client), server.getId());;
+        if (resource != null) authz.getStoreFactory().getResourceStore().delete(resource.getId());
+    }
+
+    @Override
+    public boolean isPermissionsEnabled(ClientModel client) {
+        ResourceServer server = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId());
+        if (server == null) return false;
+
+        return authz.getStoreFactory().getResourceStore().findByName(getResourceName(client), server.getId()) != null;
+    }
+
+    @Override
+    public void setPermissionsEnabled(ClientModel client, boolean enable) {
+        if (enable) {
+            initialize(client);
+        } else {
+            deletePermissions(client);
+        }
+    }
+
+
+
+    private Scope manageScope(ResourceServer server) {
+        return authz.getStoreFactory().getScopeStore().findByName(AdminPermissionManagement.MANAGE_SCOPE, server.getId());
+    }
+
+    private Scope viewScope(ResourceServer server) {
+        return authz.getStoreFactory().getScopeStore().findByName(AdminPermissionManagement.VIEW_SCOPE, server.getId());
+    }
+
+    @Override
+    public boolean canList() {
+        return root.hasAnyAdminRole();
+    }
+
+    @Override
+    public void requireList() {
+        if (!canList()) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public boolean canListTemplates() {
+        return root.hasAnyAdminRole();
+    }
+
+    public boolean canManageClientDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_CLIENTS);
+    }
+    public boolean canViewClientDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_CLIENTS, AdminRoles.VIEW_CLIENTS);
+    }
+
+    @Override
+    public boolean canManage() {
+        return canManageClientDefault();
+    }
+
+    @Override
+    public void requireManage() {
+        if (!canManage()) {
+            throw new ForbiddenException();
+        }
+    }
+    @Override
+    public boolean canView() {
+        return canManageClientDefault() || canViewClientDefault();
+    }
+
+    @Override
+    public void requireView() {
+        if (!canView()) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public boolean canManage(ClientModel client) {
+        if (!root.isAdminSameRealm()) {
+            return canManage();
+        }
+
+        ResourceServer server = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId());
+        if (server == null) return canManage();
+
+        Resource resource =  authz.getStoreFactory().getResourceStore().findByName(getResourceName(client), server.getId());
+        if (resource == null) return canManage();
+
+        Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getManagePermissionName(client), server.getId());
+        if (policy == null) {
+            return canManage();
+        }
+
+        Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+        // if no policies attached to permission then just do default behavior
+        if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+            return canManage();
+        }
+
+        Scope scope = manageScope(server);
+        return root.evaluatePermission(resource, scope, server);
+    }
+
+    @Override
+    public void requireManage(ClientModel client) {
+        if (!canManage(client)) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public boolean canView(ClientModel client) {
+        if (!root.isAdminSameRealm()) {
+            return canView();
+        }
+
+        ResourceServer server = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId());
+        if (server == null) return canView();
+
+        Resource resource =  authz.getStoreFactory().getResourceStore().findByName(getResourceName(client), server.getId());
+        if (resource == null) return canView();
+
+        Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getViewPermissionName(client), server.getId());
+        if (policy == null) {
+            return canView();
+        }
+
+        Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+        // if no policies attached to permission then just do default behavior
+        if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+            return canView();
+        }
+
+        Scope scope = viewScope(server);
+        return root.evaluatePermission(resource, scope, server);
+    }
+
+    @Override
+    public void requireView(ClientModel client) {
+        if (!canView(client)) {
+            throw new ForbiddenException();
+        }
+    }
+
+    // templates
+
+    @Override
+    public boolean canViewTemplates() {
+        return canView();
+    }
+
+    @Override
+    public boolean canManageTemplates() {
+        return canManageClientDefault();
+    }
+
+    @Override
+    public void requireManageTemplates() {
+        if (!canManageTemplates()) {
+            throw new ForbiddenException();
+        }
+    }
+    @Override
+    public void requireViewTemplates() {
+        if (!canViewTemplates()) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public boolean canManage(ClientTemplateModel template) {
+        return canManageClientDefault();
+    }
+
+    @Override
+    public void requireManage(ClientTemplateModel template) {
+        if (!canManage(template)) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public boolean canView(ClientTemplateModel template) {
+        return canViewClientDefault();
+    }
+
+    @Override
+    public void requireView(ClientTemplateModel template) {
+        if (!canView(template)) {
+            throw new ForbiddenException();
+        }
+    }
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionEvaluator.java
new file mode 100644
index 0000000..91ca5c5
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionEvaluator.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.models.GroupModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface GroupPermissionEvaluator {
+    boolean canList();
+
+    void requireList();
+
+    boolean canManage(GroupModel group);
+
+    void requireManage(GroupModel group);
+
+    boolean canView(GroupModel group);
+
+    void requireView(GroupModel group);
+
+    boolean canManage();
+
+    void requireManage();
+
+    boolean canView();
+
+    void requireView();
+
+    boolean canViewMembers(GroupModel group);
+
+    void requireViewMembers(GroupModel group);
+
+    boolean canManageMembers(GroupModel group);
+
+    void requireManageMembers(GroupModel group);
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionManagement.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionManagement.java
new file mode 100644
index 0000000..5f4097b
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissionManagement.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.authorization.model.Policy;
+import org.keycloak.models.GroupModel;
+import org.keycloak.models.RoleModel;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface GroupPermissionManagement {
+    boolean isPermissionsEnabled(GroupModel group);
+    void setPermissionsEnabled(GroupModel group, boolean enable);
+
+    Policy viewMembersPermission(GroupModel group);
+    Policy manageMembersPermission(GroupModel group);
+    Policy viewPermissionGroup(GroupModel group);
+    Policy managePermissionGroup(GroupModel group);
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java
new file mode 100644
index 0000000..46d8fb6
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.jboss.logging.Logger;
+import org.keycloak.authorization.AuthorizationProvider;
+import org.keycloak.authorization.model.Policy;
+import org.keycloak.authorization.model.Resource;
+import org.keycloak.authorization.model.ResourceServer;
+import org.keycloak.authorization.model.Scope;
+import org.keycloak.models.AdminRoles;
+import org.keycloak.models.GroupModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.services.ForbiddenException;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManagement {
+    private static final Logger logger = Logger.getLogger(GroupPermissions.class);
+    public static final String MAP_ROLE_SCOPE = "map-role";
+    public static final String MANAGE_MEMBERS_SCOPE = "manage.members";
+    public static final String VIEW_MEMBERS_SCOPE = "view.members";
+    protected final KeycloakSession session;
+    protected final RealmModel realm;
+    protected final AuthorizationProvider authz;
+    protected final MgmtPermissions root;
+
+    public GroupPermissions(KeycloakSession session, RealmModel realm, AuthorizationProvider authz, MgmtPermissions root) {
+        this.session = session;
+        this.realm = realm;
+        this.authz = authz;
+        this.root = root;
+    }
+
+    private static String getGroupResourceName(GroupModel group) {
+        return "group.resource." + getGroupSuffix(group);
+    }
+
+
+    public static String getManagePermissionGroup(GroupModel group) {
+        return "manage.permission.group." + getGroupSuffix(group);
+    }
+
+    public static String getManageMembersPermissionGroup(GroupModel group) {
+        return "manage.members.permission.group." + getGroupSuffix(group);
+    }
+
+    public static String getGroupSuffix(GroupModel group) {
+        return ModelToRepresentation.buildGroupPath(group).replace('/', '.');
+    }
+
+    public static String getViewPermissionGroup(GroupModel group) {
+        return "view.permission.group." + getGroupSuffix(group);
+    }
+
+    public static String getViewMembersPermissionGroup(GroupModel group) {
+        return "view.members.permission.group." + getGroupSuffix(group);
+    }
+
+    private void initialize(GroupModel group) {
+        root.initializeRealmResourceServer();
+        root.initializeRealmDefaultScopes();
+        ResourceServer server = root.realmResourceServer();
+        Scope manageScope = root.realmManageScope();
+        Scope viewScope = root.realmViewScope();
+        Scope manageMembersScope = root.initializeRealmScope(MANAGE_MEMBERS_SCOPE);
+        Scope viewMembersScope = root.initializeRealmScope(VIEW_MEMBERS_SCOPE);
+
+        String groupResourceName = getGroupResourceName(group);
+        Resource groupResource = authz.getStoreFactory().getResourceStore().findByName(groupResourceName, server.getId());
+        if (groupResource == null) {
+            groupResource = authz.getStoreFactory().getResourceStore().create(groupResourceName, server, server.getClientId());
+            Set<Scope> scopeset = new HashSet<>();
+            scopeset.add(manageScope);
+            scopeset.add(viewScope);
+            groupResource.updateScopes(scopeset);
+        }
+        String managePermissionName = getManagePermissionGroup(group);
+        Policy managePermission = authz.getStoreFactory().getPolicyStore().findByName(managePermissionName, server.getId());
+        if (managePermission == null) {
+            Policy manageUsersPolicy = root.roles().manageUsersPolicy(server);
+            Helper.addScopePermission(authz, server, managePermissionName, groupResource, manageScope, manageUsersPolicy);
+        }
+        String viewPermissionName = getManagePermissionGroup(group);
+        Policy viewPermission = authz.getStoreFactory().getPolicyStore().findByName(viewPermissionName, server.getId());
+        if (viewPermission == null) {
+            Policy viewUsersPolicy = root.roles().viewUsersPolicy(server);
+            Helper.addScopePermission(authz, server, viewPermissionName, groupResource, viewScope, viewUsersPolicy);
+        }
+        String manageMembersPermissionName = getManageMembersPermissionGroup(group);
+        Policy manageMembersPermission = authz.getStoreFactory().getPolicyStore().findByName(manageMembersPermissionName, server.getId());
+        if (manageMembersPermission == null) {
+            Policy manageUsersPolicy = root.roles().manageUsersPolicy(server);
+            Helper.addScopePermission(authz, server, manageMembersPermissionName, groupResource, manageMembersScope, manageUsersPolicy);
+        }
+        String viewMembersPermissionName = getViewMembersPermissionGroup(group);
+        Policy viewMembersPermission = authz.getStoreFactory().getPolicyStore().findByName(viewMembersPermissionName, server.getId());
+        if (viewMembersPermission == null) {
+            Policy viewUsersPolicy = root.roles().viewUsersPolicy(server);
+            Helper.addScopePermission(authz, server, viewMembersPermissionName, groupResource, viewMembersScope, viewUsersPolicy);
+        }
+    }
+
+    @Override
+    public boolean canList() {
+        return root.hasOneAdminRole(AdminRoles.VIEW_USERS, AdminRoles.MANAGE_USERS);
+    }
+
+    @Override
+    public void requireList() {
+        if (!canList()) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+
+    @Override
+    public boolean isPermissionsEnabled(GroupModel group) {
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return false;
+
+        return authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId()) != null;
+    }
+
+    private Resource groupResource(GroupModel group) {
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return null;
+        String groupResourceName = getGroupResourceName(group);
+        return authz.getStoreFactory().getResourceStore().findByName(groupResourceName, server.getId());
+    }
+
+    @Override
+    public void setPermissionsEnabled(GroupModel group, boolean enable) {
+       if (enable) {
+           initialize(group);
+       } else {
+           deletePermissions(group);
+       }
+    }
+
+    private void deletePermissions(GroupModel group) {
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return;
+        Policy managePermission = managePermissionGroup(group);
+        if (managePermission != null) {
+            authz.getStoreFactory().getPolicyStore().delete(managePermission.getId());
+        }
+        Policy viewPermission = viewPermissionGroup(group);
+        if (viewPermission != null) {
+            authz.getStoreFactory().getPolicyStore().delete(viewPermission.getId());
+        }
+        Policy manageMembersPermission = manageMembersPermission(group);
+        if (manageMembersPermission != null) {
+            authz.getStoreFactory().getPolicyStore().delete(manageMembersPermission.getId());
+        }
+        Policy viewMembersPermission = viewMembersPermission(group);
+        if (manageMembersPermission == null) {
+            authz.getStoreFactory().getPolicyStore().delete(viewMembersPermission.getId());
+        }
+        Resource resource = groupResource(group);
+        if (resource != null) authz.getStoreFactory().getResourceStore().delete(resource.getId());
+    }
+
+    @Override
+    public Policy viewMembersPermission(GroupModel group) {
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return null;
+        String viewMembersPermissionName = getViewMembersPermissionGroup(group);
+        return authz.getStoreFactory().getPolicyStore().findByName(viewMembersPermissionName, server.getId());
+    }
+
+    @Override
+    public Policy manageMembersPermission(GroupModel group) {
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return null;
+        String manageMembersPermissionName = getManageMembersPermissionGroup(group);
+        return authz.getStoreFactory().getPolicyStore().findByName(manageMembersPermissionName, server.getId());
+    }
+
+    @Override
+    public Policy viewPermissionGroup(GroupModel group) {
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return null;
+        String viewPermissionName = getViewPermissionGroup(group);
+        return authz.getStoreFactory().getPolicyStore().findByName(viewPermissionName, server.getId());
+    }
+
+    @Override
+    public Policy managePermissionGroup(GroupModel group) {
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return null;
+        String managePermissionName = getManagePermissionGroup(group);
+        return authz.getStoreFactory().getPolicyStore().findByName(managePermissionName, server.getId());
+    }
+
+
+    @Override
+    public boolean canManage(GroupModel group) {
+        if (!root.isAdminSameRealm()) {
+            return canManage();
+        }
+
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return canManage();
+
+        Resource resource =  authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
+        if (resource == null) return canManage();
+
+        Policy policy = managePermissionGroup(group);
+        if (policy == null) {
+            return canManage();
+        }
+
+        Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+        // if no policies attached to permission then just do default behavior
+        if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+            return canManage();
+        }
+
+        Scope scope = root.realmManageScope();
+        return root.evaluatePermission(resource, scope, server);
+    }
+
+    @Override
+    public void requireManage(GroupModel group) {
+        if (!canManage(group)) {
+            throw new ForbiddenException();
+        }
+    }
+    @Override
+    public boolean canView(GroupModel group) {
+        if (!root.isAdminSameRealm()) {
+            return canView();
+        }
+
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return canView();
+
+        Resource resource =  authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
+        if (resource == null) return canView();
+
+        Policy policy = viewPermissionGroup(group);
+        if (policy == null) {
+            return canView();
+        }
+
+        Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+        // if no policies attached to permission then abort
+        if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+            return canView();
+        }
+
+        Scope scope = root.realmViewScope();
+        return root.evaluatePermission(resource, scope, server);
+    }
+
+    @Override
+    public void requireView(GroupModel group) {
+        if (!canView(group)) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public boolean canManage() {
+        return root.users().canManageDefault();
+    }
+
+    @Override
+    public void requireManage() {
+        if (!canManage()) {
+            throw new ForbiddenException();
+        }
+    }
+    @Override
+    public boolean canView() {
+        return root.users().canViewDefault();
+    }
+
+    @Override
+    public void requireView() {
+        if (!canView()) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+
+    @Override
+    public boolean canViewMembers(GroupModel group) {
+        if (!root.isAdminSameRealm()) {
+            return root.users().canView();
+        }
+
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return root.users().canView();
+
+        Resource resource =  authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
+        if (resource == null) return root.users().canView();
+
+        Policy policy = viewMembersPermission(group);
+        if (policy == null) {
+            return root.users().canView();
+        }
+
+        Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+        // if no policies attached to permission then just do default behavior
+        if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+            return root.users().canView();
+        }
+
+        Scope scope = authz.getStoreFactory().getScopeStore().findByName(VIEW_MEMBERS_SCOPE, server.getId());
+
+        return root.evaluatePermission(resource, scope, server);
+    }
+
+    @Override
+    public void requireViewMembers(GroupModel group) {
+        if (!canViewMembers(group)) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+    @Override
+    public boolean canManageMembers(GroupModel group) {
+        if (!root.isAdminSameRealm()) {
+            return root.users().canManage();
+        }
+
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return root.users().canManage();
+
+        Resource resource =  authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
+        if (resource == null) return root.users().canManage();
+
+        Policy policy = manageMembersPermission(group);
+        if (policy == null) {
+            return root.users().canManage();
+        }
+
+        Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+        // if no policies attached to permission then just do default behavior
+        if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+            return root.users().canManage();
+        }
+
+        Scope scope = authz.getStoreFactory().getScopeStore().findByName(MANAGE_MEMBERS_SCOPE, server.getId());
+        return root.evaluatePermission(resource, scope, server);
+    }
+
+    @Override
+    public void requireManageMembers(GroupModel group) {
+        if (!canManageMembers(group)) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java
new file mode 100644
index 0000000..9434283
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.jboss.logging.Logger;
+import org.keycloak.Config;
+import org.keycloak.authorization.AuthorizationProvider;
+import org.keycloak.authorization.AuthorizationProviderFactory;
+import org.keycloak.authorization.Decision;
+import org.keycloak.authorization.common.DefaultEvaluationContext;
+import org.keycloak.authorization.common.KeycloakIdentity;
+import org.keycloak.authorization.common.UserModelIdentity;
+import org.keycloak.authorization.identity.Identity;
+import org.keycloak.authorization.model.Resource;
+import org.keycloak.authorization.model.ResourceServer;
+import org.keycloak.authorization.model.Scope;
+import org.keycloak.authorization.permission.ResourcePermission;
+import org.keycloak.authorization.permission.evaluator.PermissionEvaluator;
+import org.keycloak.authorization.policy.evaluation.DecisionResult;
+import org.keycloak.authorization.policy.evaluation.EvaluationContext;
+import org.keycloak.authorization.store.ResourceServerStore;
+import org.keycloak.authorization.util.Permissions;
+import org.keycloak.models.AdminRoles;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.services.ForbiddenException;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.resources.admin.AdminAuth;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManagement {
+    private static final Logger logger = Logger.getLogger(MgmtPermissions.class);
+
+    protected RealmModel realm;
+    protected KeycloakSession session;
+    protected AuthorizationProvider authz;
+    protected AdminAuth auth;
+    protected Identity identity;
+    protected UserModel admin;
+    protected RealmModel adminsRealm;
+    protected ResourceServer realmResourceServer;
+    protected UserPermissions users;
+    protected GroupPermissions groups;
+    protected RealmPermissions realmPermissions;
+    protected ClientPermissions clientPermissions;
+
+
+    MgmtPermissions(KeycloakSession session, RealmModel realm) {
+        this.session = session;
+        this.realm = realm;
+        KeycloakSessionFactory keycloakSessionFactory = session.getKeycloakSessionFactory();
+        AuthorizationProviderFactory factory = (AuthorizationProviderFactory) keycloakSessionFactory.getProviderFactory(AuthorizationProvider.class);
+        this.authz = factory.create(session, realm);
+    }
+
+    MgmtPermissions(KeycloakSession session, RealmModel realm, AdminAuth auth) {
+        this(session, realm);
+        this.auth = auth;
+        this.admin = auth.getUser();
+        this.adminsRealm = auth.getRealm();
+        if (!auth.getRealm().equals(realm)
+                && !auth.getRealm().equals(new RealmManager(session).getKeycloakAdminstrationRealm())) {
+            throw new ForbiddenException();
+        }
+        if (auth.getClient().getClientId().equals(Constants.ADMIN_CLI_CLIENT_ID)) {
+            this.identity = new UserModelIdentity(auth.getRealm(), auth.getUser());
+
+        } else {
+            this.identity = new KeycloakIdentity(auth.getToken(), session);
+        }
+    }
+    MgmtPermissions(KeycloakSession session, RealmModel realm, RealmModel adminsRealm, UserModel admin) {
+        this(session, realm);
+        this.admin = admin;
+        this.adminsRealm = adminsRealm;
+        this.identity = new UserModelIdentity(realm, admin);
+    }
+
+    public ClientModel getRealmManagementClient() {
+        ClientModel client = null;
+        if (realm.getName().equals(Config.getAdminRealm())) {
+            client = realm.getClientByClientId(Config.getAdminRealm() + "-realm");
+        } else {
+            client = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
+
+        }
+        return client;
+    }
+
+
+
+    public boolean hasAnyAdminRole() {
+        return hasOneAdminRole(AdminRoles.ALL_REALM_ROLES);
+    }
+
+    public boolean hasOneAdminRole(String... adminRoles) {
+        String clientId;
+        RealmManager realmManager = new RealmManager(session);
+        if (adminsRealm.equals(realmManager.getKeycloakAdminstrationRealm())) {
+            clientId = realm.getMasterAdminClient().getClientId();
+        } else {
+            clientId = realm.getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm())).getClientId();
+        }
+        for (String adminRole : adminRoles) {
+            if (identity.hasClientRole(clientId, adminRole)) return true;
+        }
+        return false;
+    }
+
+
+
+    public boolean isAdminSameRealm() {
+        return auth == null || realm.getId().equals(auth.getRealm().getId());
+    }
+
+    @Override
+    public AdminAuth adminAuth() {
+        return auth;
+    }
+
+    public Identity identity() {
+        return identity;
+    }
+
+    public UserModel admin() {
+        return admin;
+    }
+
+
+    @Override
+    public RolePermissions roles() {
+        return new RolePermissions(session, realm, authz, this);
+    }
+
+    @Override
+    public UserPermissions users() {
+        if (users != null) return users;
+        users = new UserPermissions(session, realm, authz, this);
+        return users;
+    }
+
+    @Override
+    public RealmPermissions realm() {
+        if (realmPermissions != null) return realmPermissions;
+        realmPermissions = new RealmPermissions(session, realm, authz, this);
+        return realmPermissions;
+    }
+
+    @Override
+    public ClientPermissions clients() {
+        if (clientPermissions != null) return clientPermissions;
+        clientPermissions = new ClientPermissions(session, realm, authz, this);
+        return clientPermissions;
+    }
+
+    @Override
+    public GroupPermissions groups() {
+        if (groups != null) return groups;
+        groups = new GroupPermissions(session, realm, authz, this);
+        return groups;
+    }
+
+    public ResourceServer findOrCreateResourceServer(ClientModel client) {
+        ResourceServer server = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId());
+        if (server == null) {
+            server = authz.getStoreFactory().getResourceServerStore().create(client.getId());
+        }
+        return server;
+    }
+
+    @Override
+    public ResourceServer realmResourceServer() {
+        if (realmResourceServer != null) return realmResourceServer;
+        ResourceServerStore resourceServerStore = authz.getStoreFactory().getResourceServerStore();
+        ClientModel client = getRealmManagementClient();
+        realmResourceServer = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId());
+        return realmResourceServer;
+
+    }
+
+    public ResourceServer initializeRealmResourceServer() {
+        if (realmResourceServer != null) return realmResourceServer;
+        ClientModel client = getRealmManagementClient();
+        return findOrCreateResourceServer(client);
+    }
+
+    protected Scope manageScope;
+    protected Scope viewScope;
+
+    public void initializeRealmDefaultScopes() {
+        ResourceServer server = initializeRealmResourceServer();
+        manageScope = initializeRealmScope(MgmtPermissions.MANAGE_SCOPE);
+        viewScope = initializeRealmScope(MgmtPermissions.VIEW_SCOPE);
+    }
+
+    public Scope initializeRealmScope(String name) {
+        ResourceServer server = initializeRealmResourceServer();
+        Scope scope  = authz.getStoreFactory().getScopeStore().findByName(name, server.getId());
+        if (scope == null) {
+            scope = authz.getStoreFactory().getScopeStore().create(name, server);
+        }
+        return scope;
+    }
+
+
+
+    public Scope realmManageScope() {
+        if (manageScope != null) return manageScope;
+        manageScope = realmScope(MgmtPermissions.MANAGE_SCOPE);
+        return manageScope;
+    }
+
+
+    public Scope realmViewScope() {
+        if (viewScope != null) return viewScope;
+        viewScope = realmScope(MgmtPermissions.VIEW_SCOPE);
+        return viewScope;
+    }
+
+    public Scope realmScope(String scope) {
+        ResourceServer server = realmResourceServer();
+        if (server == null) return null;
+        return authz.getStoreFactory().getScopeStore().findByName(scope, server.getId());
+    }
+
+    public boolean evaluatePermission(Resource resource, Scope scope, ResourceServer resourceServer) {
+        Identity identity = identity();
+        if (identity == null) {
+            throw new RuntimeException("Identity of admin is not set for permission query");
+        }
+        RealmModel oldRealm = session.getContext().getRealm();
+        try {
+            session.getContext().setRealm(realm);
+            EvaluationContext context = new DefaultEvaluationContext(identity, session);
+            DecisionResult decisionCollector = new DecisionResult();
+            List<ResourcePermission> permissions = Permissions.permission(resourceServer, resource, scope);
+            PermissionEvaluator from = authz.evaluators().from(permissions, context);
+            from.evaluate(decisionCollector);
+            if (!decisionCollector.completed()) {
+                logger.error("Failed to run permission check", decisionCollector.getError());
+                return false;
+            }
+            return decisionCollector.getResults().get(0).getEffect() == Decision.Effect.PERMIT;
+        } finally {
+            session.getContext().setRealm(oldRealm);
+        }
+    }
+
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissionEvaluator.java
new file mode 100644
index 0000000..cf350a1
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissionEvaluator.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface RealmPermissionEvaluator {
+    boolean canListRealm();
+
+    void requireViewRealmNameList();
+
+    boolean canManageRealm();
+
+    void requireManageRealm();
+
+    boolean canViewRealm();
+
+    void requireViewRealm();
+
+    boolean canManageIdentityProviders();
+
+    boolean canViewIdentityProviders();
+
+    void requireViewIdentityProviders();
+
+    void requireManageIdentityProviders();
+
+    boolean canManageAuthorization();
+
+    boolean canViewAuthorization();
+
+    void requireManageAuthorization();
+
+    void requireViewAuthorization();
+
+    boolean canManageEvents();
+
+    void requireManageEvents();
+
+    boolean canViewEvents();
+
+    void requireViewEvents();
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java
new file mode 100644
index 0000000..84b6ceb
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RealmPermissions.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.jboss.logging.Logger;
+import org.keycloak.authorization.AuthorizationProvider;
+import org.keycloak.models.AdminRoles;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.services.ForbiddenException;
+
+/**
+ * Manages default policies for all users.
+ *
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+class RealmPermissions implements RealmPermissionEvaluator {
+    private static final Logger logger = Logger.getLogger(RealmPermissions.class);
+    protected final KeycloakSession session;
+    protected final RealmModel realm;
+    protected final AuthorizationProvider authz;
+    protected final MgmtPermissions root;
+
+    public RealmPermissions(KeycloakSession session, RealmModel realm, AuthorizationProvider authz, MgmtPermissions root) {
+        this.session = session;
+        this.realm = realm;
+        this.authz = authz;
+        this.root = root;
+    }
+
+
+    public boolean canManageRealmDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_REALM);
+
+    }
+    public boolean canViewRealmDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_REALM, AdminRoles.VIEW_REALM);
+    }
+
+    public boolean canManageIdentityProvidersDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_IDENTITY_PROVIDERS);
+
+    }
+    public boolean canViewIdentityProvidersDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_IDENTITY_PROVIDERS, AdminRoles.VIEW_IDENTITY_PROVIDERS);
+    }
+
+    public boolean canManageAuthorizationDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_AUTHORIZATION);
+
+    }
+    public boolean canViewAuthorizationDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_AUTHORIZATION, AdminRoles.VIEW_AUTHORIZATION);
+    }
+    public boolean canManageEventsDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_EVENTS);
+    }
+    public boolean canViewEventsDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_EVENTS, AdminRoles.VIEW_EVENTS);
+    }
+
+    @Override
+    public boolean canListRealm() {
+        return root.hasAnyAdminRole();
+    }
+
+    @Override
+    public void requireViewRealmNameList() {
+        if (!canListRealm()) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public boolean canManageRealm() {
+        return canManageRealmDefault();
+    }
+
+    @Override
+    public void requireManageRealm() {
+        if (!canManageRealm()) {
+            throw new ForbiddenException();
+        }
+    }
+    @Override
+    public boolean canViewRealm() {
+        return canViewRealmDefault();
+    }
+
+    @Override
+    public void requireViewRealm() {
+        if (!canViewRealm()) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public boolean canManageIdentityProviders() {
+        return canManageIdentityProvidersDefault();
+    }
+
+    @Override
+    public boolean canViewIdentityProviders() {
+        return canViewIdentityProvidersDefault();
+    }
+
+    @Override
+    public void requireViewIdentityProviders() {
+        if (!canViewIdentityProviders()) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+    @Override
+    public void requireManageIdentityProviders() {
+        if (!canManageIdentityProviders()) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+    @Override
+    public boolean canManageAuthorization() {
+        return canManageAuthorizationDefault();
+    }
+
+    @Override
+    public boolean canViewAuthorization() {
+        return canViewAuthorizationDefault();
+    }
+
+    @Override
+    public void requireManageAuthorization() {
+        if (!canManageEvents()) {
+            throw new ForbiddenException();
+        }
+    }
+    @Override
+    public void requireViewAuthorization() {
+        if (!canManageEvents()) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public boolean canManageEvents() {
+        return canManageEventsDefault();
+    }
+
+    @Override
+    public void requireManageEvents() {
+        if (!canManageEvents()) {
+            throw new ForbiddenException();
+        }
+    }
+    @Override
+    public boolean canViewEvents() {
+        return canViewEventsDefault();
+    }
+
+    @Override
+    public void requireViewEvents() {
+        if (!canViewEvents()) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissionEvaluator.java
new file mode 100644
index 0000000..3a87cb3
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissionEvaluator.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.models.RoleContainerModel;
+import org.keycloak.models.RoleModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface RolePermissionEvaluator {
+    boolean canList(RoleContainerModel container);
+
+    void requireList(RoleContainerModel container);
+
+    boolean canMapRole(RoleModel role);
+    void requireMapRole(RoleModel role);
+
+    boolean canManage(RoleModel role);
+
+    void requireManage(RoleModel role);
+
+    boolean canView(RoleModel role);
+
+    void requireView(RoleModel role);
+
+    boolean canMapClientScope(RoleModel role);
+    void requireMapClientScope(RoleModel role);
+
+    boolean canMapComposite(RoleModel role);
+    void requireMapComposite(RoleModel role);
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissionManagement.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissionManagement.java
new file mode 100644
index 0000000..977e109
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissionManagement.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.authorization.model.Policy;
+import org.keycloak.authorization.model.Resource;
+import org.keycloak.authorization.model.ResourceServer;
+import org.keycloak.models.RoleContainerModel;
+import org.keycloak.models.RoleModel;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface RolePermissionManagement {
+    public static final String MAP_ROLE_SCOPE = "map-role";
+    public static final String MAP_ROLE_CLIENT_SCOPE_SCOPE = "map-role-client-scope";
+    public static final String MAP_ROLE_COMPOSITE_SCOPE = "map-role-composite";
+
+    boolean isPermissionsEnabled(RoleModel role);
+    void setPermissionsEnabled(RoleModel role, boolean enable);
+
+    Map<String, String> getPermissions(RoleModel role);
+
+    Policy mapRolePermission(RoleModel role);
+
+    Policy mapCompositePermission(RoleModel role);
+
+    Policy mapClientScopePermission(RoleModel role);
+
+    Resource resource(RoleModel role);
+
+    ResourceServer resourceServer(RoleModel role);
+
+    Policy manageUsersPolicy(ResourceServer server);
+
+    Policy viewUsersPolicy(ResourceServer server);
+
+    Policy rolePolicy(ResourceServer server, RoleModel role);
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java
new file mode 100644
index 0000000..d2531ec
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.jboss.logging.Logger;
+import org.keycloak.authorization.AuthorizationProvider;
+import org.keycloak.authorization.model.Policy;
+import org.keycloak.authorization.model.Resource;
+import org.keycloak.authorization.model.ResourceServer;
+import org.keycloak.authorization.model.Scope;
+import org.keycloak.authorization.store.ResourceStore;
+import org.keycloak.models.AdminRoles;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleContainerModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.services.ForbiddenException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+class RolePermissions implements RolePermissionEvaluator, RolePermissionManagement {
+    private static final Logger logger = Logger.getLogger(RolePermissions.class);
+    protected final KeycloakSession session;
+    protected final RealmModel realm;
+    protected final AuthorizationProvider authz;
+    protected final MgmtPermissions root;
+
+    public RolePermissions(KeycloakSession session, RealmModel realm, AuthorizationProvider authz, MgmtPermissions root) {
+        this.session = session;
+        this.realm = realm;
+        this.authz = authz;
+        this.root = root;
+    }
+
+    @Override
+    public boolean isPermissionsEnabled(RoleModel role) {
+        return mapRolePermission(role) != null;
+    }
+
+    @Override
+    public void setPermissionsEnabled(RoleModel role, boolean enable) {
+       if (enable) {
+           ResourceServer server = getResourceServer(role);
+           if (authz.getStoreFactory().getResourceStore().findByName(getRoleResourceName(role), server.getId()) != null) {
+               return;
+           }
+           createResource(role);
+       } else {
+           ResourceServer server = resourceServer(role);
+           if (server == null) return;
+           Resource resource = authz.getStoreFactory().getResourceStore().findByName(getRoleResourceName(role), server.getId());
+           if (resource != null) authz.getStoreFactory().getResourceStore().delete(resource.getId());
+           Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapRolePermissionName(role), server.getId());
+           if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId());
+       }
+    }
+
+    @Override
+    public Map<String, String> getPermissions(RoleModel role) {
+        Map<String, String> scopes = new HashMap<>();
+        scopes.put(RolePermissionManagement.MAP_ROLE_SCOPE, mapRolePermission(role).getId());
+        scopes.put(RolePermissionManagement.MAP_ROLE_CLIENT_SCOPE_SCOPE, mapClientScopePermission(role).getId());
+        scopes.put(RolePermissionManagement.MAP_ROLE_COMPOSITE_SCOPE, mapCompositePermission(role).getId());
+        return scopes;
+    }
+
+    @Override
+    public Policy mapRolePermission(RoleModel role) {
+        ResourceServer server = resourceServer(role);
+        if (server == null) return null;
+
+        Resource resource = authz.getStoreFactory().getResourceStore().findByName(getRoleResourceName(role), server.getId());
+        if (resource == null) return null;
+
+        return  authz.getStoreFactory().getPolicyStore().findByName(getMapRolePermissionName(role), server.getId());
+    }
+
+    @Override
+    public Policy mapCompositePermission(RoleModel role) {
+        ResourceServer server = resourceServer(role);
+        if (server == null) return null;
+
+        Resource resource = authz.getStoreFactory().getResourceStore().findByName(getRoleResourceName(role), server.getId());
+        if (resource == null) return null;
+
+        return  authz.getStoreFactory().getPolicyStore().findByName(getMapCompositePermissionName(role), server.getId());
+    }
+
+    @Override
+    public Policy mapClientScopePermission(RoleModel role) {
+        ResourceServer server = resourceServer(role);
+        if (server == null) return null;
+
+        Resource resource = authz.getStoreFactory().getResourceStore().findByName(getRoleResourceName(role), server.getId());
+        if (resource == null) return null;
+
+        return  authz.getStoreFactory().getPolicyStore().findByName(getMapClientScopePermissionName(role), server.getId());
+    }
+
+    @Override
+    public Resource resource(RoleModel role) {
+        ResourceStore resourceStore = authz.getStoreFactory().getResourceStore();
+        ResourceServer server = resourceServer(role);
+        if (server == null) return null;
+        return  resourceStore.findByName(getRoleResourceName(role), server.getId());
+    }
+
+    @Override
+    public ResourceServer resourceServer(RoleModel role) {
+        ClientModel client = getRoleClient(role);
+        return authz.getStoreFactory().getResourceServerStore().findByClient(client.getId());
+    }
+
+    /**
+     * Is admin allowed to map this role?
+     *
+     * @param role
+     * @return
+     */
+    @Override
+    public boolean canMapRole(RoleModel role) {
+        if (!root.isAdminSameRealm()) {
+            return root.users().canManage();
+        }
+        if (!isPermissionsEnabled(role)){
+            return root.users().canManage();
+        }
+
+        ResourceServer resourceServer = getResourceServer(role);
+        Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapRolePermissionName(role), resourceServer.getId());
+        if (policy.getAssociatedPolicies().isEmpty()) {
+            return root.users().canManage(); // if no policies applied, just do default
+        }
+
+        Resource roleResource = resource(role);
+        Scope mapRoleScope = getMapRoleScope(resourceServer);
+        return root.evaluatePermission(roleResource, mapRoleScope, resourceServer);
+    }
+
+    @Override
+    public void requireMapRole(RoleModel role) {
+        if (!canMapRole(role)) {
+            throw new ForbiddenException();
+        }
+
+    }
+
+    @Override
+    public boolean canList(RoleContainerModel container) {
+        return root.hasAnyAdminRole();
+    }
+
+    @Override
+    public void requireList(RoleContainerModel container) {
+        if (!canList(container)) {
+            throw new ForbiddenException();
+        }
+
+    }
+
+    @Override
+    public boolean canMapComposite(RoleModel role) {
+        if (!root.isAdminSameRealm()) {
+            return canManage(role);
+        }
+        if (!isPermissionsEnabled(role)){
+            return canManage(role);
+        }
+
+        ResourceServer resourceServer = getResourceServer(role);
+        Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapCompositePermissionName(role), resourceServer.getId());
+        if (policy.getAssociatedPolicies().isEmpty()) {
+            return canManage(role);
+        }
+
+        Resource roleResource = resource(role);
+        Scope scope = getMapCompositeScope(resourceServer);
+        return root.evaluatePermission(roleResource, scope, resourceServer);
+    }
+
+    @Override
+    public void requireMapComposite(RoleModel role) {
+        if (!canMapComposite(role)) {
+            throw new ForbiddenException();
+        }
+
+    }
+
+
+    @Override
+    public boolean canMapClientScope(RoleModel role) {
+        if (!root.isAdminSameRealm()) {
+            return root.clients().canManage();
+        }
+        if (!isPermissionsEnabled(role)){
+            return root.clients().canManage();
+        }
+
+        ResourceServer resourceServer = getResourceServer(role);
+        Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapClientScopePermissionName(role), resourceServer.getId());
+        if (policy.getAssociatedPolicies().isEmpty()) {
+            return root.clients().canManage();
+        }
+
+        Resource roleResource = resource(role);
+        Scope scope = getMapClientScope(resourceServer);
+        return root.evaluatePermission(roleResource, scope, resourceServer);
+    }
+
+    @Override
+    public void requireMapClientScope(RoleModel role) {
+        if (!canMapClientScope(role)) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+    @Override
+    public boolean canManage(RoleModel role) {
+        if (role.getContainer() instanceof RealmModel) {
+            return root.realm().canManageRealm();
+        } else if (role.getContainer() instanceof ClientModel) {
+            ClientModel client = (ClientModel)role.getContainer();
+            return root.clients().canManage(client);
+        }
+        return false;
+    }
+
+    @Override
+    public void requireManage(RoleModel role) {
+        if (!canManage(role)) {
+            throw new ForbiddenException();
+        }
+
+    }
+
+    @Override
+    public boolean canView(RoleModel role) {
+        if (role.getContainer() instanceof RealmModel) {
+            return root.realm().canViewRealm();
+        } else if (role.getContainer() instanceof ClientModel) {
+            ClientModel client = (ClientModel)role.getContainer();
+            return root.clients().canView(client);
+        }
+        return false;
+    }
+
+    @Override
+    public void requireView(RoleModel role) {
+        if (!canView(role)) {
+            throw new ForbiddenException();
+        }
+
+    }
+
+    private ClientModel getRoleClient(RoleModel role) {
+        ClientModel client = null;
+        if (role.getContainer() instanceof ClientModel) {
+            client = (ClientModel)role.getContainer();
+        } else {
+            client = root.getRealmManagementClient();
+        }
+        return client;
+    }
+
+    @Override
+    public Policy manageUsersPolicy(ResourceServer server) {
+        RoleModel role = root.getRealmManagementClient().getRole(AdminRoles.MANAGE_USERS);
+        return rolePolicy(server, role);
+    }
+
+    @Override
+    public Policy viewUsersPolicy(ResourceServer server) {
+        RoleModel role = root.getRealmManagementClient().getRole(AdminRoles.VIEW_USERS);
+        return rolePolicy(server, role);
+    }
+
+    @Override
+    public Policy rolePolicy(ResourceServer server, RoleModel role) {
+        String policyName = Helper.getRolePolicyName(role);
+        Policy policy = authz.getStoreFactory().getPolicyStore().findByName(policyName, server.getId());
+        if (policy != null) return policy;
+        return Helper.createRolePolicy(authz, server, role, policyName);
+    }
+
+    private Scope getMapRoleScope(ResourceServer server) {
+        Scope scope = authz.getStoreFactory().getScopeStore().findByName(MAP_ROLE_SCOPE, server.getId());
+        if (scope == null) {
+            scope = authz.getStoreFactory().getScopeStore().create(MAP_ROLE_SCOPE, server);
+        }
+        return scope;
+    }
+
+    private Scope getMapClientScope(ResourceServer server) {
+        Scope scope = authz.getStoreFactory().getScopeStore().findByName(MAP_ROLE_CLIENT_SCOPE_SCOPE, server.getId());
+        if (scope == null) {
+            scope = authz.getStoreFactory().getScopeStore().create(MAP_ROLE_CLIENT_SCOPE_SCOPE, server);
+        }
+        return scope;
+    }
+
+    private Scope getMapCompositeScope(ResourceServer server) {
+        Scope scope = authz.getStoreFactory().getScopeStore().findByName(MAP_ROLE_COMPOSITE_SCOPE, server.getId());
+        if (scope == null) {
+            scope = authz.getStoreFactory().getScopeStore().create(MAP_ROLE_COMPOSITE_SCOPE, server);
+        }
+        return scope;
+    }
+
+
+    private Resource createResource(RoleModel role) {
+        ResourceServer server = getResourceServer(role);
+        Resource resource =  authz.getStoreFactory().getResourceStore().create(getRoleResourceName(role), server, server.getClientId());
+        resource.setType("Role");
+        Scope mapRoleScope = getMapRoleScope(server);
+        Policy policy = manageUsersPolicy(server);
+        Helper.addScopePermission(authz, server, getMapRolePermissionName(role), resource, mapRoleScope, policy);
+
+        Scope mapClientScope = getMapClientScope(server);
+        RoleModel mngClients = root.getRealmManagementClient().getRole(AdminRoles.MANAGE_CLIENTS);
+        Policy mngClientsPolicy = rolePolicy(server, mngClients);
+        Helper.addScopePermission(authz, server, getMapClientScopePermissionName(role), resource, mapClientScope, mngClientsPolicy);
+
+        Scope mapCompositeScope = getMapCompositeScope(server);
+        if (role.getContainer() instanceof RealmModel) {
+            RoleModel mngRealm = root.getRealmManagementClient().getRole(AdminRoles.MANAGE_REALM);
+            policy = rolePolicy(server, mngRealm);
+        } else {
+            policy = mngClientsPolicy;
+
+        }
+        Helper.addScopePermission(authz, server, getMapCompositePermissionName(role), resource, mapCompositeScope, policy);
+        return resource;
+    }
+
+    private String getMapRolePermissionName(RoleModel role) {
+        return MAP_ROLE_SCOPE + ".permission." + role.getName();
+    }
+
+    private String getMapClientScopePermissionName(RoleModel role) {
+        return MAP_ROLE_CLIENT_SCOPE_SCOPE + ".permission." + role.getName();
+    }
+
+    private String getMapCompositePermissionName(RoleModel role) {
+        return MAP_ROLE_CLIENT_SCOPE_SCOPE + ".permission." + role.getName();
+    }
+
+    private ResourceServer getResourceServer(RoleModel role) {
+        ClientModel client = getRoleClient(role);
+        return root.findOrCreateResourceServer(client);
+    }
+
+    private static String getRoleResourceName(RoleModel role) {
+        return "role.resource." + role.getName();
+    }
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionEvaluator.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionEvaluator.java
new file mode 100644
index 0000000..488825b
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionEvaluator.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.models.UserModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface UserPermissionEvaluator {
+    boolean canManage();
+
+    void requireManage();
+
+    boolean canManage(UserModel user);
+    void requireManage(UserModel user);
+
+    boolean canQuery();
+
+    void requireQuery();
+
+    boolean canView();
+    boolean canView(UserModel user);
+    void requireView(UserModel user);
+
+    void requireView();
+
+    boolean canImpersonate(UserModel user);
+
+    void requireImpersonate(UserModel user);
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionManagement.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionManagement.java
new file mode 100644
index 0000000..b57b710
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissionManagement.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.keycloak.authorization.model.Policy;
+import org.keycloak.authorization.model.Resource;
+import org.keycloak.models.RoleModel;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface UserPermissionManagement {
+    boolean isPermissionsEnabled();
+
+    void setPermissionsEnabled(boolean enable);
+
+    Map<String, String> getPermissions();
+
+    Resource resource();
+
+    Policy managePermission();
+
+    Policy viewPermission();
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java
new file mode 100644
index 0000000..a0a7281
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.services.resources.admin.permissions;
+
+import org.jboss.logging.Logger;
+import org.keycloak.authorization.AuthorizationProvider;
+import org.keycloak.authorization.model.Policy;
+import org.keycloak.authorization.model.Resource;
+import org.keycloak.authorization.model.ResourceServer;
+import org.keycloak.authorization.model.Scope;
+import org.keycloak.models.AdminRoles;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.GroupModel;
+import org.keycloak.models.ImpersonationConstants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.services.ForbiddenException;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Manages default policies for all users.
+ *
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+class UserPermissions implements UserPermissionEvaluator, UserPermissionManagement {
+    private static final Logger logger = Logger.getLogger(UserPermissions.class);
+    public static final String MANAGE_PERMISSION_USERS = "manage.permission.users";
+    public static final String VIEW_PERMISSION_USERS = "view.permission.users";
+    public static final String USERS_RESOURCE = "Users";
+    protected final KeycloakSession session;
+    protected final RealmModel realm;
+    protected final AuthorizationProvider authz;
+    protected final MgmtPermissions root;
+
+    public UserPermissions(KeycloakSession session, RealmModel realm, AuthorizationProvider authz, MgmtPermissions root) {
+        this.session = session;
+        this.realm = realm;
+        this.authz = authz;
+        this.root = root;
+    }
+
+
+    private void initialize() {
+        root.initializeRealmResourceServer();
+        root.initializeRealmDefaultScopes();
+        ResourceServer server = root.realmResourceServer();
+        Scope manageScope = root.realmManageScope();
+        Scope viewScope = root.realmViewScope();
+
+        Resource usersResource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
+        if (usersResource == null) {
+            usersResource = authz.getStoreFactory().getResourceStore().create(USERS_RESOURCE, server, server.getClientId());
+            Set<Scope> scopeset = new HashSet<>();
+            scopeset.add(manageScope);
+            scopeset.add(viewScope);
+            usersResource.updateScopes(scopeset);
+        }
+        Policy managePermission = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
+        if (managePermission == null) {
+            Policy manageUsersPolicy = root.roles().manageUsersPolicy(server);
+            Helper.addScopePermission(authz, server, MANAGE_PERMISSION_USERS, usersResource, manageScope, manageUsersPolicy);
+        }
+        Policy viewPermission = authz.getStoreFactory().getPolicyStore().findByName(VIEW_PERMISSION_USERS, server.getId());
+        if (viewPermission == null) {
+            Policy viewUsersPolicy = root.roles().viewUsersPolicy(server);
+            Helper.addScopePermission(authz, server, VIEW_PERMISSION_USERS, usersResource, viewScope, viewUsersPolicy);
+        }
+    }
+
+    @Override
+    public Map<String, String> getPermissions() {
+        Map<String, String> scopes = new HashMap<>();
+        scopes.put(AdminPermissionManagement.MANAGE_SCOPE, managePermission().getId());
+        scopes.put(AdminPermissionManagement.VIEW_SCOPE, viewPermission().getId());
+        return scopes;
+    }
+
+    @Override
+    public boolean isPermissionsEnabled() {
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return false;
+
+        Resource resource =  authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
+        if (resource == null) return false;
+
+        Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
+
+        return policy != null;
+    }
+
+    @Override
+    public void setPermissionsEnabled(boolean enable) {
+        ClientModel client = root.getRealmManagementClient();
+        if (enable) {
+            initialize();
+        } else {
+            ResourceServer server = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId());
+            if (server == null) return;
+            Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
+            if (policy == null) {
+                authz.getStoreFactory().getPolicyStore().delete(policy.getId());
+
+            }
+            Resource usersResource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
+            if (usersResource == null) {
+                authz.getStoreFactory().getResourceStore().delete(usersResource.getId());
+            }
+        }
+    }
+
+    public boolean canManageDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_USERS);
+    }
+
+    @Override
+    public Resource resource() {
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return null;
+
+        return  authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
+    }
+
+    @Override
+    public Policy managePermission() {
+        ResourceServer server = root.realmResourceServer();
+        return authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
+    }
+
+    @Override
+    public Policy viewPermission() {
+        ResourceServer server = root.realmResourceServer();
+        return authz.getStoreFactory().getPolicyStore().findByName(VIEW_PERMISSION_USERS, server.getId());
+    }
+
+
+
+    /**
+     * Is admin allowed to manage all users?  In Authz terms, does the admin have the "manage" scope for the Users Authz resource?
+     *
+     * This method will follow the old default behavior (does the admin have the manage-users role) if any of these conditions
+     * are met.:
+     * - The admin is from the master realm managing a different realm
+     * - If the Authz objects are not set up correctly for the Users resource in Authz
+     * - The "manage" permission for the Users resource has an empty associatedPolicy list.
+     *
+     * Otherwise, it will use the Authz policy engine to resolve this answer.
+     *
+     * @return
+     */
+    @Override
+    public boolean canManage() {
+        if (!root.isAdminSameRealm()) {
+            return canManageDefault();
+        }
+
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return canManageDefault();
+
+        Resource resource =  authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
+        if (resource == null) return canManageDefault();
+
+        Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
+        if (policy == null) {
+            return canManageDefault();
+        }
+
+        Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+        // if no policies attached to permission then just do default behavior
+        if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+            return canManageDefault();
+        }
+
+        Scope scope = root.realmManageScope();
+        return root.evaluatePermission(resource, scope, server);
+
+    }
+
+    @Override
+    public void requireManage() {
+        if (!canManage()) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+    /**
+     * Does current admin have manage permissions for this particular user?
+     *
+     * @param user
+     * @return
+     */
+    @Override
+    public boolean canManage(UserModel user) {
+        return canManage() || canManageByGroup(user);
+    }
+
+    @Override
+    public void requireManage(UserModel user) {
+        if (!canManage(user)) {
+            throw new ForbiddenException();
+        }
+    }
+
+    private interface EvaluateGroup {
+        boolean evaluate(GroupModel group);
+    }
+
+    private boolean evaluateGroups(UserModel user, EvaluateGroup eval) {
+        for (GroupModel group : user.getGroups()) {
+            if (eval.evaluate(group)) return true;
+        }
+        return false;
+    }
+
+    private boolean evaluateHierarchy(UserModel user, EvaluateGroup eval) {
+        Set<GroupModel> visited = new HashSet<>();
+        for (GroupModel group : user.getGroups()) {
+            if (evaluateHierarchy(eval, group, visited)) return true;
+        }
+        return false;
+    }
+
+    private boolean evaluateHierarchy(EvaluateGroup eval, GroupModel group, Set<GroupModel> visited) {
+        if (visited.contains(group)) return false;
+        if (eval.evaluate(group)) {
+            return true;
+        }
+        visited.add(group);
+        if (group.getParent() == null) return false;
+        return evaluateHierarchy(eval, group.getParent(), visited);
+    }
+
+    private boolean canManageByGroup(UserModel user) {
+        /* no inheritance
+        return evaluateGroups(user,
+                (group) -> root.groups().canViewMembers(group)
+        );
+        */
+
+        /* inheritance
+        */
+        return evaluateHierarchy(user, (group) -> root.groups().canManageMembers(group));
+
+    }
+    private boolean canViewByGroup(UserModel user) {
+        /* no inheritance
+        return evaluateGroups(user,
+                (group) -> root.groups().canViewMembers(group)
+        );
+        */
+
+        /* inheritance
+        */
+        return evaluateHierarchy(user, (group) -> root.groups().canViewMembers(group));
+    }
+
+    public boolean canViewDefault() {
+        return root.hasOneAdminRole(AdminRoles.MANAGE_USERS, AdminRoles.VIEW_USERS);
+    }
+
+    @Override
+    public boolean canQuery() {
+        return canViewDefault();
+    }
+
+    @Override
+    public void requireQuery() {
+        if (!canQuery()) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+
+    /**
+     * Is admin allowed to view all users?  In Authz terms, does the admin have the "view" scope for the Users Authz resource?
+     *
+     * This method will follow the old default behavior (does the admin have the view-users role) if any of these conditions
+     * are met.:
+     * - The admin is from the master realm managing a different realm
+     * - If the Authz objects are not set up correctly for the Users resource in Authz
+     * - The "view" permission for the Users resource has an empty associatedPolicy list.
+     *
+     * Otherwise, it will use the Authz policy engine to resolve this answer.
+     *
+     * @return
+     */
+    @Override
+    public boolean canView() {
+        if (!root.isAdminSameRealm()) {
+            return canViewDefault();
+        }
+
+        ResourceServer server = root.realmResourceServer();
+        if (server == null) return canViewDefault();
+
+        Resource resource =  authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
+        if (resource == null) return canViewDefault();
+
+        Policy policy = authz.getStoreFactory().getPolicyStore().findByName(VIEW_PERMISSION_USERS, server.getId());
+        if (policy == null) {
+            return canViewDefault();
+        }
+
+        Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
+        // if no policies attached to permission then just do default behavior
+        if (associatedPolicies == null || associatedPolicies.isEmpty()) {
+            return canViewDefault();
+        }
+
+        Scope scope = root.realmViewScope();
+        return root.evaluatePermission(resource, scope, server);
+    }
+
+    /**
+     * Does current admin have view permissions for this particular user?
+     *
+     * Evaluates in this order. If any true, return true:
+     * - canViewUsers
+     * - canManageUsers
+     *
+     *
+     * @param user
+     * @return
+     */
+    @Override
+    public boolean canView(UserModel user) {
+        return canView() || canManage() || canViewByGroup(user) || canManageByGroup(user);
+    }
+
+    @Override
+    public void requireView(UserModel user) {
+        if (!canView(user)) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public void requireView() {
+        if (!(canView() || canManage())) {
+            throw new ForbiddenException();
+        }
+    }
+
+    @Override
+    public boolean canImpersonate(UserModel user) {
+        return root.hasOneAdminRole(ImpersonationConstants.IMPERSONATION_ROLE);
+    }
+
+    @Override
+    public void requireImpersonate(UserModel user) {
+        if (!canImpersonate(user)) {
+            throw new ForbiddenException();
+        }
+    }
+
+
+
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
index ad473b9..3aac331 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
@@ -33,7 +33,7 @@ import org.keycloak.protocol.ProtocolMapperConfigException;
 import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 import org.keycloak.services.ErrorResponse;
 import org.keycloak.services.ErrorResponseException;
-import org.keycloak.services.resources.admin.RealmAuth.Resource;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -66,7 +66,9 @@ public class ProtocolMappersResource {
 
     protected ProtocolMapperContainerModel client;
 
-    protected RealmAuth auth;
+    protected AdminPermissionEvaluator auth;
+    protected AdminPermissionEvaluator.RequirePermissionCheck managePermission;
+    protected AdminPermissionEvaluator.RequirePermissionCheck viewPermission;
 
     protected AdminEventBuilder adminEvent;
 
@@ -76,13 +78,17 @@ public class ProtocolMappersResource {
     @Context
     protected KeycloakSession session;
 
-    public ProtocolMappersResource(RealmModel realm, ProtocolMapperContainerModel client, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public ProtocolMappersResource(RealmModel realm, ProtocolMapperContainerModel client, AdminPermissionEvaluator auth,
+                                   AdminEventBuilder adminEvent,
+                                   AdminPermissionEvaluator.RequirePermissionCheck managePermission,
+                                   AdminPermissionEvaluator.RequirePermissionCheck viewPermission) {
         this.realm = realm;
         this.auth = auth;
         this.client = client;
         this.adminEvent = adminEvent.resource(ResourceType.PROTOCOL_MAPPER);
+        this.managePermission = managePermission;
+        this.viewPermission = viewPermission;
 
-        auth.init(Resource.CLIENT);
     }
 
     /**
@@ -96,11 +102,7 @@ public class ProtocolMappersResource {
     @Path("protocol/{protocol}")
     @Produces(MediaType.APPLICATION_JSON)
     public List<ProtocolMapperRepresentation> getMappersPerProtocol(@PathParam("protocol") String protocol) {
-        auth.requireAny();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        viewPermission.require();
 
         List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
         for (ProtocolMapperModel mapper : client.getProtocolMappers()) {
@@ -119,11 +121,7 @@ public class ProtocolMappersResource {
     @NoCache
     @Consumes(MediaType.APPLICATION_JSON)
     public Response createMapper(ProtocolMapperRepresentation rep) {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        managePermission.require();
 
         ProtocolMapperModel model = null;
         try {
@@ -147,11 +145,7 @@ public class ProtocolMappersResource {
     @NoCache
     @Consumes(MediaType.APPLICATION_JSON)
     public void createMapper(List<ProtocolMapperRepresentation> reps) {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        managePermission.require();
 
         ProtocolMapperModel model = null;
         for (ProtocolMapperRepresentation rep : reps) {
@@ -172,11 +166,7 @@ public class ProtocolMappersResource {
     @Path("models")
     @Produces(MediaType.APPLICATION_JSON)
     public List<ProtocolMapperRepresentation> getMappers() {
-        auth.requireAny();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        viewPermission.require();
 
         List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
         for (ProtocolMapperModel mapper : client.getProtocolMappers()) {
@@ -196,11 +186,7 @@ public class ProtocolMappersResource {
     @Path("models/{id}")
     @Produces(MediaType.APPLICATION_JSON)
     public ProtocolMapperRepresentation getMapperById(@PathParam("id") String id) {
-        auth.requireAny();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        viewPermission.require();
 
         ProtocolMapperModel model = client.getProtocolMapperById(id);
         if (model == null) throw new NotFoundException("Model not found");
@@ -218,11 +204,7 @@ public class ProtocolMappersResource {
     @Path("models/{id}")
     @Consumes(MediaType.APPLICATION_JSON)
     public void update(@PathParam("id") String id, ProtocolMapperRepresentation rep) {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        managePermission.require();
 
         ProtocolMapperModel model = client.getProtocolMapperById(id);
         if (model == null) throw new NotFoundException("Model not found");
@@ -243,11 +225,7 @@ public class ProtocolMappersResource {
     @NoCache
     @Path("models/{id}")
     public void delete(@PathParam("id") String id) {
-        auth.requireManage();
-
-        if (client == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        managePermission.require();
 
         ProtocolMapperModel model = client.getProtocolMapperById(id);
         if (model == null) throw new NotFoundException("Model not found");
@@ -264,7 +242,7 @@ public class ProtocolMappersResource {
             }
         } catch (ProtocolMapperConfigException ex) {
             logger.error(ex.getMessage());
-            Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale());
+            Properties messages = AdminRoot.getMessages(session, realm, auth.adminAuth().getToken().getLocale());
             throw new ErrorResponseException(ex.getMessage(), MessageFormat.format(messages.getProperty(ex.getMessageKey(), ex.getMessage()), ex.getParameters()),
                     Response.Status.BAD_REQUEST);
         }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index 510a605..0a84001 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -23,9 +23,9 @@ import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.Config;
 import org.keycloak.KeyPairVerifier;
-import org.keycloak.authorization.admin.permissions.MgmtPermissions;
-import org.keycloak.authorization.admin.permissions.RoleMgmtPermissions;
-import org.keycloak.authorization.admin.permissions.UsersPermissions;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement;
+import org.keycloak.services.resources.admin.permissions.AdminPermissions;
 import org.keycloak.common.ClientConnection;
 import org.keycloak.common.VerificationException;
 import org.keycloak.common.util.PemUtils;
@@ -48,7 +48,6 @@ import org.keycloak.models.LDAPConstants;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.ModelException;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.cache.CacheRealmProvider;
 import org.keycloak.models.cache.UserCache;
@@ -63,7 +62,6 @@ import org.keycloak.representations.adapters.action.GlobalRequestResult;
 import org.keycloak.representations.idm.AdminEventRepresentation;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.ComponentRepresentation;
-import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.EventRepresentation;
 import org.keycloak.representations.idm.GroupRepresentation;
 import org.keycloak.representations.idm.ManagementPermissionReference;
@@ -76,7 +74,6 @@ import org.keycloak.services.managers.LDAPConnectionTestManager;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.managers.UserStorageSyncManager;
-import org.keycloak.services.resources.admin.RealmAuth.Resource;
 import org.keycloak.storage.UserStorageProviderModel;
 
 import javax.ws.rs.Consumes;
@@ -114,7 +111,7 @@ import java.util.regex.PatternSyntaxException;
  */
 public class RealmAdminResource {
     protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
-    protected RealmAuth auth;
+    protected AdminPermissionEvaluator auth;
     protected RealmModel realm;
     private TokenManager tokenManager;
     private AdminEventBuilder adminEvent;
@@ -131,13 +128,11 @@ public class RealmAdminResource {
     @Context
     protected HttpHeaders headers;
 
-    public RealmAdminResource(RealmAuth auth, RealmModel realm, TokenManager tokenManager, AdminEventBuilder adminEvent) {
+    public RealmAdminResource(AdminPermissionEvaluator auth, RealmModel realm, TokenManager tokenManager, AdminEventBuilder adminEvent) {
         this.auth = auth;
         this.realm = realm;
         this.tokenManager = tokenManager;
         this.adminEvent = adminEvent.realm(realm).resource(ResourceType.REALM);
-
-        auth.init(RealmAuth.Resource.REALM);
     }
 
     /**
@@ -150,7 +145,7 @@ public class RealmAdminResource {
     @POST
     @Produces(MediaType.APPLICATION_JSON)
     public ClientRepresentation convertClientDescription(String description) {
-        auth.init(Resource.CLIENT).requireManage();
+        auth.clients().requireManage();
 
         if (realm == null) {
             throw new NotFoundException("Realm not found.");
@@ -239,7 +234,9 @@ public class RealmAdminResource {
      */
     @Path("roles")
     public RoleContainerResource getRoleContainerResource() {
-        return new RoleContainerResource(session, uriInfo, realm, auth, realm, adminEvent);
+        AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.realm().requireManageRealm();
+        AdminPermissionEvaluator.RequirePermissionCheck viewCheck = () -> auth.realm().requireViewRealm();
+        return new RoleContainerResource(session, uriInfo, realm, auth, realm, adminEvent, manageCheck, viewCheck);
     }
 
     /**
@@ -253,15 +250,15 @@ public class RealmAdminResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public RealmRepresentation getRealm() {
-        if (auth.hasView()) {
+        if (auth.realm().canViewRealm()) {
             return ModelToRepresentation.toRepresentation(realm, false);
         } else {
-            auth.requireAny();
+            auth.realm().requireViewRealmNameList();
 
             RealmRepresentation rep = new RealmRepresentation();
             rep.setRealm(realm.getName());
 
-            if (auth.init(Resource.IDENTITY_PROVIDER).hasView()) {
+            if (auth.realm().canViewIdentityProviders()) {
                 RealmRepresentation r = ModelToRepresentation.toRepresentation(realm, false);
                 rep.setIdentityProviders(r.getIdentityProviders());
                 rep.setIdentityProviderMappers(r.getIdentityProviderMappers());
@@ -283,7 +280,7 @@ public class RealmAdminResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public Response updateRealm(final RealmRepresentation rep) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         logger.debug("updating realm: " + realm.getName());
 
@@ -347,7 +344,7 @@ public class RealmAdminResource {
      */
     @DELETE
     public void deleteRealm() {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         if (!new RealmManager(session).removeRealm(realm)) {
             throw new NotFoundException("Realm doesn't exist");
@@ -372,9 +369,9 @@ public class RealmAdminResource {
     @Produces(MediaType.APPLICATION_JSON)
     @Path("users-management-permissions")
     public ManagementPermissionReference getUserMgmtPermissions() {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
-        MgmtPermissions permissions = new MgmtPermissions(session, realm);
+        AdminPermissionManagement permissions = AdminPermissions.management(session, realm);
         if (permissions.users().isPermissionsEnabled()) {
             return toUsersMgmtRef(permissions);
         } else {
@@ -389,9 +386,9 @@ public class RealmAdminResource {
     @NoCache
     @Path("users-management-permissions")
     public ManagementPermissionReference setUsersManagementPermissionsEnabled(ManagementPermissionReference ref) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
-        MgmtPermissions permissions = new MgmtPermissions(session, realm);
+        AdminPermissionManagement permissions = AdminPermissions.management(session, realm);
         permissions.users().setPermissionsEnabled(ref.isEnabled());
         if (ref.isEnabled()) {
             return toUsersMgmtRef(permissions);
@@ -401,12 +398,11 @@ public class RealmAdminResource {
     }
 
 
-    public static ManagementPermissionReference toUsersMgmtRef(MgmtPermissions permissions) {
+    public static ManagementPermissionReference toUsersMgmtRef(AdminPermissionManagement permissions) {
         ManagementPermissionReference ref = new ManagementPermissionReference();
         ref.setEnabled(true);
         ref.setResource(permissions.users().resource().getId());
-        Map<String, String> scopes = new HashMap<>();
-        scopes.put(MgmtPermissions.MANAGE_SCOPE, permissions.users().managePermission().getId());
+        Map<String, String> scopes = permissions.users().getPermissions();
         ref.setScopePermissions(scopes);
         return ref;
     }
@@ -436,7 +432,7 @@ public class RealmAdminResource {
      */
     @Path("roles-by-id")
     public RoleByIdResource rolesById() {
-        RoleByIdResource resource = new RoleByIdResource(realm, auth, adminEvent);
+         RoleByIdResource resource = new RoleByIdResource(realm, auth, adminEvent);
         ResteasyProviderFactory.getInstance().injectProperties(resource);
         //resourceContext.initResource(resource);
         return resource;
@@ -449,7 +445,7 @@ public class RealmAdminResource {
     @Path("push-revocation")
     @POST
     public GlobalRequestResult pushRevocation() {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         GlobalRequestResult result = new ResourceAdminManager(session).pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm);
         adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).representation(result).success();
@@ -464,7 +460,7 @@ public class RealmAdminResource {
     @Path("logout-all")
     @POST
     public GlobalRequestResult logoutAll() {
-        auth.init(RealmAuth.Resource.USER).requireManage();
+        auth.users().requireManage();
 
         session.sessions().removeUserSessions(realm);
         GlobalRequestResult result = new ResourceAdminManager(session).logoutAll(uriInfo.getRequestUri(), realm);
@@ -481,7 +477,7 @@ public class RealmAdminResource {
     @Path("sessions/{session}")
     @DELETE
     public void deleteSession(@PathParam("session") String sessionId) {
-        auth.init(RealmAuth.Resource.USER).requireManage();
+        auth.users().requireManage();
 
         UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
         if (userSession == null) throw new NotFoundException("Sesssion not found");
@@ -503,7 +499,7 @@ public class RealmAdminResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<Map<String, String>> getClientSessionStats() {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         List<Map<String, String>> data = new LinkedList<Map<String, String>>();
         for (ClientModel client : realm.getClients()) {
@@ -530,7 +526,7 @@ public class RealmAdminResource {
     @Path("events/config")
     @Produces(MediaType.APPLICATION_JSON)
     public RealmEventsConfigRepresentation getRealmEventsConfig() {
-        auth.init(RealmAuth.Resource.EVENTS).requireView();
+        auth.realm().requireViewEvents();
 
         RealmEventsConfigRepresentation config = ModelToRepresentation.toEventsConfigReprensetation(realm);
         if (config.getEnabledEventTypes() == null || config.getEnabledEventTypes().isEmpty()) {
@@ -555,7 +551,7 @@ public class RealmAdminResource {
     @Path("events/config")
     @Consumes(MediaType.APPLICATION_JSON)
     public void updateRealmEventsConfig(final RealmEventsConfigRepresentation rep) {
-        auth.init(RealmAuth.Resource.EVENTS).requireManage();
+        auth.realm().requireManageEvents();
 
         logger.debug("updating realm events config: " + realm.getName());
         new RealmManager(session).updateRealmEventsConfig(rep, realm);
@@ -584,7 +580,7 @@ public class RealmAdminResource {
                                                @QueryParam("user") String user, @QueryParam("dateFrom") String dateFrom, @QueryParam("dateTo") String dateTo,
                                                @QueryParam("ipAddress") String ipAddress, @QueryParam("first") Integer firstResult,
                                                @QueryParam("max") Integer maxResults) {
-        auth.init(RealmAuth.Resource.EVENTS).requireView();
+        auth.realm().requireViewEvents();
 
         EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
 
@@ -677,7 +673,7 @@ public class RealmAdminResource {
                                                     @QueryParam("dateTo") String dateTo, @QueryParam("first") Integer firstResult,
                                                     @QueryParam("max") Integer maxResults,
                                                     @QueryParam("resourceTypes") List<String> resourceTypes) {
-        auth.init(RealmAuth.Resource.EVENTS).requireView();
+        auth.realm().requireViewEvents();
 
         EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
         AdminEventQuery query = eventStore.createAdminQuery().realm(realm.getId());;
@@ -770,7 +766,7 @@ public class RealmAdminResource {
     @Path("events")
     @DELETE
     public void clearEvents() {
-        auth.init(RealmAuth.Resource.EVENTS).requireManage();
+        auth.realm().requireManageEvents();
 
         EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
         eventStore.clear(realm.getId());
@@ -783,7 +779,7 @@ public class RealmAdminResource {
     @Path("admin-events")
     @DELETE
     public void clearAdminEvents() {
-        auth.init(RealmAuth.Resource.EVENTS).requireManage();
+        auth.realm().requireManageEvents();
 
         EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
         eventStore.clearAdmin(realm.getId());
@@ -805,7 +801,7 @@ public class RealmAdminResource {
                                        @QueryParam("bindDn") String bindDn, @QueryParam("bindCredential") String bindCredential,
                                        @QueryParam("useTruststoreSpi") String useTruststoreSpi, @QueryParam("connectionTimeout") String connectionTimeout,
                                        @QueryParam("componentId") String componentId) {
-        auth.init(RealmAuth.Resource.REALM).requireManage();
+        auth.realm().requireManageRealm();
 
         if (componentId != null && bindCredential.equals(ComponentRepresentation.SECRET_VALUE)) {
             bindCredential = realm.getComponent(componentId).getConfig().getFirst(LDAPConstants.BIND_CREDENTIAL);
@@ -830,7 +826,7 @@ public class RealmAdminResource {
     @Produces(MediaType.APPLICATION_JSON)
     @Path("default-groups")
     public List<GroupRepresentation> getDefaultGroups() {
-        auth.requireView();
+        auth.realm().requireViewRealm();
 
         List<GroupRepresentation> defaults = new LinkedList<>();
         for (GroupModel group : realm.getDefaultGroups()) {
@@ -842,7 +838,7 @@ public class RealmAdminResource {
     @NoCache
     @Path("default-groups/{groupId}")
     public void addDefaultGroup(@PathParam("groupId") String groupId) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         GroupModel group = realm.getGroupById(groupId);
         if (group == null) {
@@ -857,7 +853,7 @@ public class RealmAdminResource {
     @NoCache
     @Path("default-groups/{groupId}")
     public void removeDefaultGroup(@PathParam("groupId") String groupId) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         GroupModel group = realm.getGroupById(groupId);
         if (group == null) {
@@ -882,13 +878,12 @@ public class RealmAdminResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public GroupRepresentation getGroupByPath(@PathParam("path") String path) {
-        auth.requireView();
-
         GroupModel found = KeycloakModelUtils.findGroupByPath(realm, path);
         if (found == null) {
             throw new NotFoundException("Group path does not exist");
 
         }
+        auth.groups().requireView(found);
         return ModelToRepresentation.toGroupHierarchy(found, true);
     }
 
@@ -902,7 +897,7 @@ public class RealmAdminResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response partialImport(PartialImportRepresentation rep) {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         PartialImportManager partialImport = new PartialImportManager(rep, session, realm, adminEvent);
         return partialImport.saveResources();
@@ -915,7 +910,7 @@ public class RealmAdminResource {
     @Path("clear-realm-cache")
     @POST
     public void clearRealmCache() {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         CacheRealmProvider cache = session.getProvider(CacheRealmProvider.class);
         if (cache != null) {
@@ -932,7 +927,7 @@ public class RealmAdminResource {
     @Path("clear-user-cache")
     @POST
     public void clearUserCache() {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         UserCache cache = session.getProvider(UserCache.class);
         if (cache != null) {
@@ -949,7 +944,7 @@ public class RealmAdminResource {
     @Path("clear-keys-cache")
     @POST
     public void clearKeysCache() {
-        auth.requireManage();
+        auth.realm().requireManageRealm();
 
         PublicKeyStorageProvider cache = session.getProvider(PublicKeyStorageProvider.class);
         if (cache != null) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
index 7a948d9..9e0a89e 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
@@ -34,6 +34,8 @@ import org.keycloak.services.ErrorResponse;
 import org.keycloak.services.ForbiddenException;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.KeycloakApplication;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
+import org.keycloak.services.resources.admin.permissions.AdminPermissions;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
@@ -191,13 +193,7 @@ public class RealmsAdminResource {
                 && !auth.getRealm().equals(realm)) {
             throw new ForbiddenException();
         }
-        RealmAuth realmAuth;
-
-        if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
-            realmAuth = new RealmAuth(auth, realm.getMasterAdminClient());
-        } else {
-            realmAuth = new RealmAuth(auth, realm.getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm())));
-        }
+        AdminPermissionEvaluator realmAuth = AdminPermissions.evaluator(session, realm, auth);
 
         AdminEventBuilder adminEvent = new AdminEventBuilder(realm, auth, session, clientConnection);
         session.getContext().setRealm(realm);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
index 9d3e100..b2ae6ad 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
@@ -19,8 +19,10 @@ package org.keycloak.services.resources.admin;
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.authorization.admin.permissions.MgmtPermissions;
-import org.keycloak.authorization.admin.permissions.RoleMgmtPermissions;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement;
+import org.keycloak.services.resources.admin.permissions.AdminPermissions;
+import org.keycloak.services.resources.admin.permissions.RolePermissionManagement;
 import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.admin.ResourceType;
 import org.keycloak.models.ClientModel;
@@ -57,7 +59,7 @@ import java.util.Set;
 public class RoleByIdResource extends RoleResource {
     protected static final Logger logger = Logger.getLogger(RoleByIdResource.class);
     private final RealmModel realm;
-    private final RealmAuth auth;
+    private AdminPermissionEvaluator auth;
     private AdminEventBuilder adminEvent;
 
     @Context
@@ -66,7 +68,7 @@ public class RoleByIdResource extends RoleResource {
     @Context
     private UriInfo uriInfo;
 
-    public RoleByIdResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public RoleByIdResource(RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         super(realm);
 
         this.realm = realm;
@@ -85,9 +87,9 @@ public class RoleByIdResource extends RoleResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public RoleRepresentation getRole(final @PathParam("role-id") String id) {
-        auth.requireAny();
 
         RoleModel roleModel = getRoleModel(id);
+        auth.roles().requireView(roleModel);
         return getRole(roleModel);
     }
 
@@ -96,17 +98,7 @@ public class RoleByIdResource extends RoleResource {
         if (roleModel == null) {
             throw new NotFoundException("Could not find role with id");
         }
-
-        RealmAuth.Resource r = null;
-        if (roleModel.getContainer() instanceof RealmModel) {
-            r = RealmAuth.Resource.REALM;
-        } else if (roleModel.getContainer() instanceof ClientModel) {
-            r = RealmAuth.Resource.CLIENT;
-        } else if (roleModel.getContainer() instanceof UserModel) {
-            r = RealmAuth.Resource.USER;
-        }
-        auth.init(r);
-        return roleModel;
+       return roleModel;
     }
 
     /**
@@ -118,9 +110,8 @@ public class RoleByIdResource extends RoleResource {
     @DELETE
     @NoCache
     public void deleteRole(final @PathParam("role-id") String id) {
-        auth.requireManage();
-
         RoleModel role = getRoleModel(id);
+        auth.roles().requireManage(role);
         deleteRole(role);
 
         if (role.isClientRole()) {
@@ -142,9 +133,8 @@ public class RoleByIdResource extends RoleResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public void updateRole(final @PathParam("role-id") String id, final RoleRepresentation rep) {
-        auth.requireManage();
-
         RoleModel role = getRoleModel(id);
+        auth.roles().requireManage(role);
         updateRole(rep, role);
 
         if (role.isClientRole()) {
@@ -166,10 +156,9 @@ public class RoleByIdResource extends RoleResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public void addComposites(final @PathParam("role-id") String id, List<RoleRepresentation> roles) {
-        auth.requireManage();
-
         RoleModel role = getRoleModel(id);
-        addComposites(adminEvent, uriInfo, roles, role);
+        auth.roles().requireManage(role);
+        addComposites(auth, adminEvent, uriInfo, roles, role);
     }
 
     /**
@@ -185,11 +174,10 @@ public class RoleByIdResource extends RoleResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-id") String id) {
-        auth.requireAny();
 
         if (logger.isDebugEnabled()) logger.debug("*** getRoleComposites: '" + id + "'");
         RoleModel role = getRoleModel(id);
-        auth.requireView();
+        auth.roles().requireView(role);
         return getRoleComposites(role);
     }
 
@@ -204,9 +192,9 @@ public class RoleByIdResource extends RoleResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Set<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-id") String id) {
-        auth.requireAny();
-
         RoleModel role = getRoleModel(id);
+        auth.roles().requireView(role);
+        auth.roles().requireView(role);
         return getRealmRoleComposites(role);
     }
 
@@ -223,9 +211,9 @@ public class RoleByIdResource extends RoleResource {
     @Produces(MediaType.APPLICATION_JSON)
     public Set<RoleRepresentation> getClientRoleComposites(final @PathParam("role-id") String id,
                                                                 final @PathParam("client") String client) {
-        auth.requireAny();
 
         RoleModel role = getRoleModel(id);
+        auth.roles().requireView(role);
         ClientModel clientModel = realm.getClientById(client);
         if (clientModel == null) {
             throw new NotFoundException("Could not find client");
@@ -243,9 +231,8 @@ public class RoleByIdResource extends RoleResource {
     @DELETE
     @Consumes(MediaType.APPLICATION_JSON)
     public void deleteComposites(final @PathParam("role-id") String id, List<RoleRepresentation> roles) {
-        auth.requireManage();
-
         RoleModel role = getRoleModel(id);
+        auth.roles().requireManage(role);
         deleteComposites(adminEvent, uriInfo, roles, role);
     }
 
@@ -261,24 +248,21 @@ public class RoleByIdResource extends RoleResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public ManagementPermissionReference getManagementPermissions(final @PathParam("role-id") String id) {
-        auth.requireView();
-
         RoleModel role = getRoleModel(id);
+        auth.roles().requireView(role);
 
-        MgmtPermissions permissions = new MgmtPermissions(session, realm);
+        AdminPermissionManagement permissions = AdminPermissions.management(session, realm);
         if (!permissions.roles().isPermissionsEnabled(role)) {
             return new ManagementPermissionReference();
         }
         return toMgmtRef(role, permissions);
     }
 
-    public static ManagementPermissionReference toMgmtRef(RoleModel role, MgmtPermissions permissions) {
+    public static ManagementPermissionReference toMgmtRef(RoleModel role, AdminPermissionManagement permissions) {
         ManagementPermissionReference ref = new ManagementPermissionReference();
         ref.setEnabled(true);
         ref.setResource(permissions.roles().resource(role).getId());
-        Map<String, String> scopes = new HashMap<>();
-        scopes.put(RoleMgmtPermissions.MAP_ROLE_SCOPE, permissions.roles().mapRolePermission(role).getId());
-        ref.setScopePermissions(scopes);
+        ref.setScopePermissions(permissions.roles().getPermissions(role));
         return ref;
     }
 
@@ -295,11 +279,10 @@ public class RoleByIdResource extends RoleResource {
     @Consumes(MediaType.APPLICATION_JSON)
     @NoCache
     public ManagementPermissionReference setManagementPermissionsEnabled(final @PathParam("role-id") String id, ManagementPermissionReference ref) {
-        auth.requireManage();
-
         RoleModel role = getRoleModel(id);
+        auth.roles().requireManage(role);
 
-        MgmtPermissions permissions = new MgmtPermissions(session, realm);
+        AdminPermissionManagement permissions = AdminPermissions.management(session, realm);
         permissions.roles().setPermissionsEnabled(role, ref.isEnabled());
         if (ref.isEnabled()) {
             return toMgmtRef(role, permissions);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
index 94e4def..7f4d495 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
@@ -19,8 +19,9 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.authorization.admin.permissions.MgmtPermissions;
-import org.keycloak.authorization.admin.permissions.RoleMgmtPermissions;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement;
+import org.keycloak.services.resources.admin.permissions.AdminPermissions;
 import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.admin.ResourceType;
 import org.keycloak.models.ClientModel;
@@ -37,20 +38,20 @@ import org.keycloak.services.ErrorResponse;
 import javax.ws.rs.BadRequestException;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -60,13 +61,19 @@ import java.util.Set;
  */
 public class RoleContainerResource extends RoleResource {
     private final RealmModel realm;
-    private final RealmAuth auth;
+    protected AdminPermissionEvaluator auth;
+    protected AdminPermissionEvaluator.RequirePermissionCheck managePermission;
+    protected AdminPermissionEvaluator.RequirePermissionCheck viewPermission;
+
     protected RoleContainerModel roleContainer;
     private AdminEventBuilder adminEvent;
     private UriInfo uriInfo;
     private KeycloakSession session;
 
-    public RoleContainerResource(KeycloakSession session, UriInfo uriInfo, RealmModel realm, RealmAuth auth, RoleContainerModel roleContainer, AdminEventBuilder adminEvent) {
+    public RoleContainerResource(KeycloakSession session, UriInfo uriInfo, RealmModel realm,
+                                 AdminPermissionEvaluator auth, RoleContainerModel roleContainer, AdminEventBuilder adminEvent,
+                                 AdminPermissionEvaluator.RequirePermissionCheck managePermission,
+                                 AdminPermissionEvaluator.RequirePermissionCheck viewPermission) {
         super(realm);
         this.uriInfo = uriInfo;
         this.realm = realm;
@@ -74,6 +81,8 @@ public class RoleContainerResource extends RoleResource {
         this.roleContainer = roleContainer;
         this.adminEvent = adminEvent;
         this.session = session;
+        this.managePermission = managePermission;
+        this.viewPermission = viewPermission;
     }
 
     /**
@@ -85,11 +94,7 @@ public class RoleContainerResource extends RoleResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<RoleRepresentation> getRoles() {
-        auth.requireAny();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        auth.roles().requireList(roleContainer);
 
         Set<RoleModel> roleModels = roleContainer.getRoles();
         List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
@@ -108,11 +113,7 @@ public class RoleContainerResource extends RoleResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response createRole(final RoleRepresentation rep) {
-        auth.requireManage();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        managePermission.require();
 
         if (rep.getName() == null) {
             throw new BadRequestException();
@@ -151,16 +152,12 @@ public class RoleContainerResource extends RoleResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public RoleRepresentation getRole(final @PathParam("role-name") String roleName) {
-        auth.requireView();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
 
         RoleModel roleModel = roleContainer.getRole(roleName);
         if (roleModel == null) {
             throw new NotFoundException("Could not find role");
         }
+        auth.roles().requireView(roleModel);
 
         return getRole(roleModel);
     }
@@ -174,16 +171,11 @@ public class RoleContainerResource extends RoleResource {
     @DELETE
     @NoCache
     public void deleteRole(final @PathParam("role-name") String roleName) {
-        auth.requireManage();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
-
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role");
         }
+        auth.roles().requireManage(role);
         deleteRole(role);
 
         if (role.isClientRole()) {
@@ -207,16 +199,11 @@ public class RoleContainerResource extends RoleResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public Response updateRole(final @PathParam("role-name") String roleName, final RoleRepresentation rep) {
-        auth.requireManage();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
-
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role");
         }
+        auth.roles().requireManage(role);
         try {
             updateRole(rep, role);
 
@@ -244,17 +231,12 @@ public class RoleContainerResource extends RoleResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public void addComposites(final @PathParam("role-name") String roleName, List<RoleRepresentation> roles) {
-        auth.requireManage();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
-
-        RoleModel role = roleContainer.getRole(roleName);
+       RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role");
         }
-        addComposites(adminEvent, uriInfo, roles, role);
+        auth.roles().requireManage(role);
+        addComposites(auth, adminEvent, uriInfo, roles, role);
     }
 
     /**
@@ -268,16 +250,11 @@ public class RoleContainerResource extends RoleResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-name") String roleName) {
-        auth.requireView();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
-
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role");
         }
+        auth.roles().requireView(role);
         return getRoleComposites(role);
     }
 
@@ -292,16 +269,11 @@ public class RoleContainerResource extends RoleResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Set<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-name") String roleName) {
-        auth.requireView();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
-
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role");
         }
+        auth.roles().requireView(role);
         return getRealmRoleComposites(role);
     }
 
@@ -319,16 +291,11 @@ public class RoleContainerResource extends RoleResource {
     public Set<RoleRepresentation> getClientRoleComposites(@Context final UriInfo uriInfo,
                                                                 final @PathParam("role-name") String roleName,
                                                                 final @PathParam("client") String client) {
-        auth.requireView();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
-
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role");
         }
+        auth.roles().requireView(role);
         ClientModel clientModel = realm.getClientById(client);
         if (client == null) {
             throw new NotFoundException("Could not find client");
@@ -350,16 +317,12 @@ public class RoleContainerResource extends RoleResource {
     public void deleteComposites(
                                    final @PathParam("role-name") String roleName,
                                    List<RoleRepresentation> roles) {
-        auth.requireManage();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
 
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role");
         }
+        auth.roles().requireManage(role);
         deleteComposites(adminEvent, uriInfo, roles, role);
     }
 
@@ -375,18 +338,13 @@ public class RoleContainerResource extends RoleResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public ManagementPermissionReference getManagementPermissions(final @PathParam("role-name") String roleName) {
-        auth.requireView();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
-
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role");
         }
+        auth.roles().requireView(role);
 
-        MgmtPermissions permissions = new MgmtPermissions(session, realm);
+        AdminPermissionManagement permissions = AdminPermissions.management(session, realm);
         if (!permissions.roles().isPermissionsEnabled(role)) {
             return new ManagementPermissionReference();
         }
@@ -406,19 +364,14 @@ public class RoleContainerResource extends RoleResource {
     @Consumes(MediaType.APPLICATION_JSON)
     @NoCache
     public ManagementPermissionReference setManagementPermissionsEnabled(final @PathParam("role-name") String roleName, ManagementPermissionReference ref) {
-        auth.requireManage();
-
-        if (roleContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
-
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role");
         }
+        auth.roles().requireManage(role);
 
         if (ref.isEnabled()) {
-            MgmtPermissions permissions = new MgmtPermissions(session, realm);
+            AdminPermissionManagement permissions = AdminPermissions.management(session, realm);
             permissions.roles().setPermissionsEnabled(role, ref.isEnabled());
             return RoleByIdResource.toMgmtRef(role, permissions);
         } else {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
index 93d4cb6..8db0591 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
@@ -19,7 +19,7 @@ package org.keycloak.services.resources.admin;
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.authorization.admin.permissions.MgmtPermissions;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.common.ClientConnection;
 import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.admin.ResourceType;
@@ -52,7 +52,6 @@ import javax.ws.rs.core.UriInfo;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -69,27 +68,17 @@ import java.util.stream.Collectors;
  */
 public class RoleMapperResource {
 
-    /**
-     * RoleMapperResource is reused bewteen GroupResource and UserResource to manage role mappings.
-     * We don't know what type of resource we're managing here (user or group), so we don't know how to query the policy engine to determine
-     * if an action is allowed.
-     *
-     */
-    public interface ManageResourcePermissionCheck {
-        boolean canManage();
-    }
-
     protected static final Logger logger = Logger.getLogger(RoleMapperResource.class);
 
     protected RealmModel realm;
 
-    private RealmAuth auth;
-
     private RoleMapperModel roleMapper;
 
     private AdminEventBuilder adminEvent;
 
-    private ManageResourcePermissionCheck manageResourcePermissionCheck;
+    protected AdminPermissionEvaluator.RequirePermissionCheck managePermission;
+    protected AdminPermissionEvaluator.RequirePermissionCheck viewPermission;
+    private AdminPermissionEvaluator auth;
 
     @Context
     protected ClientConnection clientConnection;
@@ -103,18 +92,21 @@ public class RoleMapperResource {
     @Context
     protected HttpHeaders headers;
 
-    public RoleMapperResource(RealmModel realm, RealmAuth auth,  RoleMapperModel roleMapper, AdminEventBuilder adminEvent) {
+    public RoleMapperResource(RealmModel realm,
+                              AdminPermissionEvaluator auth,
+                              RoleMapperModel roleMapper,
+                              AdminEventBuilder adminEvent,
+                              AdminPermissionEvaluator.RequirePermissionCheck manageCheck,
+                              AdminPermissionEvaluator.RequirePermissionCheck viewCheck) {
         this.auth = auth;
         this.realm = realm;
         this.adminEvent = adminEvent.resource(ResourceType.REALM_ROLE_MAPPING);
         this.roleMapper = roleMapper;
+        this.managePermission = manageCheck;
+        this.viewPermission = viewCheck;
 
     }
 
-    public void setManageCheck(ManageResourcePermissionCheck mapperPermissions) {
-        this.manageResourcePermissionCheck = mapperPermissions;
-    }
-
     /**
      * Get role mappings
      *
@@ -124,11 +116,7 @@ public class RoleMapperResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public MappingsRepresentation getRoleMappings() {
-        auth.requireView();
-
-        if (roleMapper == null) {
-            throw new NotFoundException("User not found");
-        }
+        viewPermission.require();
 
         MappingsRepresentation all = new MappingsRepresentation();
         Set<RoleModel> realmMappings = roleMapper.getRealmRoleMappings();
@@ -173,11 +161,7 @@ public class RoleMapperResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getRealmRoleMappings() {
-        auth.requireView();
-
-        if (roleMapper == null) {
-            throw new NotFoundException("User not found");
-        }
+        viewPermission.require();
 
         Set<RoleModel> realmMappings = roleMapper.getRealmRoleMappings();
         List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
@@ -199,11 +183,7 @@ public class RoleMapperResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getCompositeRealmRoleMappings() {
-        auth.requireView();
-
-        if (roleMapper == null) {
-            throw new NotFoundException("User not found");
-        }
+        viewPermission.require();
 
         Set<RoleModel> roles = realm.getRoles();
         List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
@@ -225,11 +205,7 @@ public class RoleMapperResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getAvailableRealmRoleMappings() {
-        auth.requireView();
-
-        if (roleMapper == null) {
-            throw new NotFoundException("User not found");
-        }
+        viewPermission.require();
 
         Set<RoleModel> available = realm.getRoles();
         Set<RoleModel> set = available.stream().filter(r ->
@@ -247,11 +223,7 @@ public class RoleMapperResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public void addRealmRoleMappings(List<RoleRepresentation> roles) {
-        checkManagePermission();
-
-        if (roleMapper == null) {
-            throw new NotFoundException("User not found");
-        }
+        managePermission.require();
 
         logger.debugv("** addRealmRoleMappings: {0}", roles);
 
@@ -267,16 +239,6 @@ public class RoleMapperResource {
         adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
     }
 
-    private void checkManagePermission() {
-        if (manageResourcePermissionCheck == null) {
-            auth.requireManage();
-        } else {
-            if (!manageResourcePermissionCheck.canManage()) {
-                throw new ForbiddenException();
-            }
-        }
-    }
-
     /**
      * Delete realm-level role mappings
      *
@@ -286,11 +248,7 @@ public class RoleMapperResource {
     @DELETE
     @Consumes(MediaType.APPLICATION_JSON)
     public void deleteRealmRoleMappings(List<RoleRepresentation> roles) {
-        checkManagePermission();
-
-        if (roleMapper == null) {
-            throw new NotFoundException("User not found");
-        }
+        managePermission.require();
 
         logger.debug("deleteRealmRoleMappings");
         if (roles == null) {
@@ -313,7 +271,7 @@ public class RoleMapperResource {
                 try {
                     roleMapper.deleteRoleMapping(roleModel);
                 } catch (ModelException me) {
-                    Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale());
+                    Properties messages = AdminRoot.getMessages(session, realm, auth.adminAuth().getToken().getLocale());
                     throw new ErrorResponseException(me.getMessage(), MessageFormat.format(messages.getProperty(me.getMessage(), me.getMessage()), me.getParameters()),
                             Response.Status.BAD_REQUEST);
                 }
@@ -332,16 +290,18 @@ public class RoleMapperResource {
     }
 
     private boolean canMapRole(RoleModel roleModel) {
-        return new MgmtPermissions(session, realm, auth.getAuth()).roles().canMapRole(roleModel);
+        return auth.roles().canMapRole(roleModel);
     }
 
     @Path("clients/{client}")
     public ClientRoleMappingsResource getUserClientRoleMappingsResource(@PathParam("client") String client) {
         ClientModel clientModel = realm.getClientById(client);
-        ClientRoleMappingsResource resource = new ClientRoleMappingsResource(uriInfo, session, realm, auth, roleMapper, clientModel, adminEvent);
-        resource.setManageCheck(() -> {
-            return new MgmtPermissions(session, realm, auth.getAuth()).users().canManage();
-        });
+        if (clientModel == null) {
+            throw new NotFoundException("Client not found");
+        }
+        ClientRoleMappingsResource resource = new ClientRoleMappingsResource(uriInfo, session, realm, auth, roleMapper,
+                clientModel, adminEvent,
+                managePermission, viewPermission);
         return resource;
 
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
index 5fb1d34..cdd9cd7 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
@@ -25,6 +25,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.core.UriInfo;
 import java.util.Collections;
@@ -60,12 +61,13 @@ public abstract class RoleResource {
         if (rep.isScopeParamRequired() != null) role.setScopeParamRequired(rep.isScopeParamRequired());
     }
 
-    protected void addComposites(AdminEventBuilder adminEvent, UriInfo uriInfo, List<RoleRepresentation> roles, RoleModel role) {
+    protected void addComposites(AdminPermissionEvaluator auth, AdminEventBuilder adminEvent, UriInfo uriInfo, List<RoleRepresentation> roles, RoleModel role) {
         for (RoleRepresentation rep : roles) {
             RoleModel composite = realm.getRoleById(rep.getId());
             if (composite == null) {
                 throw new NotFoundException("Could not find composite role");
             }
+            auth.roles().requireManage(composite);
             role.addCompositeRole(composite);
         }
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java
index 431e97c..4f7b5dc 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java
@@ -29,6 +29,7 @@ import org.keycloak.models.ScopeContainerModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -49,19 +50,25 @@ import java.util.Set;
  */
 public class ScopeMappedClientResource {
     protected RealmModel realm;
-    private RealmAuth auth;
+    protected AdminPermissionEvaluator auth;
+    protected AdminPermissionEvaluator.RequirePermissionCheck managePermission;
+    protected AdminPermissionEvaluator.RequirePermissionCheck viewPermission;
     protected ScopeContainerModel scopeContainer;
     protected KeycloakSession session;
     protected ClientModel scopedClient;
     protected AdminEventBuilder adminEvent;
     
-    public ScopeMappedClientResource(RealmModel realm, RealmAuth auth, ScopeContainerModel scopeContainer, KeycloakSession session, ClientModel scopedClient, AdminEventBuilder adminEvent) {
+    public ScopeMappedClientResource(RealmModel realm, AdminPermissionEvaluator auth, ScopeContainerModel scopeContainer, KeycloakSession session, ClientModel scopedClient, AdminEventBuilder adminEvent,
+                                     AdminPermissionEvaluator.RequirePermissionCheck managePermission,
+                                     AdminPermissionEvaluator.RequirePermissionCheck viewPermission) {
         this.realm = realm;
         this.auth = auth;
         this.scopeContainer = scopeContainer;
         this.session = session;
         this.scopedClient = scopedClient;
         this.adminEvent = adminEvent.resource(ResourceType.CLIENT_SCOPE_MAPPING);
+        this.managePermission = managePermission;
+        this.viewPermission = viewPermission;
     }
 
     /**
@@ -75,11 +82,7 @@ public class ScopeMappedClientResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getClientScopeMappings() {
-        auth.requireView();
-
-        if (scopeContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        viewPermission.require();
 
         Set<RoleModel> mappings = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer); //scopedClient.getClientScopeMappings(client);
         List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>();
@@ -101,14 +104,10 @@ public class ScopeMappedClientResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getAvailableClientScopeMappings() {
-        auth.requireView();
-
-        if (scopeContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        viewPermission.require();
 
         Set<RoleModel> roles = scopedClient.getRoles();
-        return ScopeMappedResource.getAvailable(scopeContainer, roles);
+        return ScopeMappedResource.getAvailable(auth, scopeContainer, roles);
     }
 
     /**
@@ -123,11 +122,7 @@ public class ScopeMappedClientResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getCompositeClientScopeMappings() {
-        auth.requireView();
-
-        if (scopeContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        viewPermission.require();
 
         Set<RoleModel> roles = scopedClient.getRoles();
         return ScopeMappedResource.getComposite(scopeContainer, roles);
@@ -141,11 +136,7 @@ public class ScopeMappedClientResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public void addClientScopeMapping(List<RoleRepresentation> roles) {
-        auth.requireManage();
-
-        if (scopeContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        managePermission.require();
 
         for (RoleRepresentation role : roles) {
             RoleModel roleModel = scopedClient.getRole(role.getName());
@@ -166,11 +157,7 @@ public class ScopeMappedClientResource {
     @DELETE
     @Consumes(MediaType.APPLICATION_JSON)
     public void deleteClientScopeMapping(List<RoleRepresentation> roles) {
-        auth.requireManage();
-
-        if (scopeContainer == null) {
-            throw new NotFoundException("Could not find client");
-        }
+        managePermission.require();
 
         if (roles == null) {
             Set<RoleModel> roleModels = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer);//scopedClient.getClientScopeMappings(client);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
index 19a32f9..286e22b 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
@@ -31,6 +31,7 @@ import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.ClientMappingsRepresentation;
 import org.keycloak.representations.idm.MappingsRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -56,17 +57,25 @@ import java.util.Set;
  */
 public class ScopeMappedResource {
     protected RealmModel realm;
-    private RealmAuth auth;
+    protected AdminPermissionEvaluator auth;
+    protected AdminPermissionEvaluator.RequirePermissionCheck managePermission;
+    protected AdminPermissionEvaluator.RequirePermissionCheck viewPermission;
+
     protected ScopeContainerModel scopeContainer;
     protected KeycloakSession session;
     protected AdminEventBuilder adminEvent;
 
-    public ScopeMappedResource(RealmModel realm, RealmAuth auth, ScopeContainerModel scopeContainer, KeycloakSession session, AdminEventBuilder adminEvent) {
+    public ScopeMappedResource(RealmModel realm, AdminPermissionEvaluator auth, ScopeContainerModel scopeContainer,
+                               KeycloakSession session, AdminEventBuilder adminEvent,
+                               AdminPermissionEvaluator.RequirePermissionCheck managePermission,
+                               AdminPermissionEvaluator.RequirePermissionCheck viewPermission) {
         this.realm = realm;
         this.auth = auth;
         this.scopeContainer = scopeContainer;
         this.session = session;
         this.adminEvent = adminEvent.resource(ResourceType.REALM_SCOPE_MAPPING);
+        this.managePermission = managePermission;
+        this.viewPermission = viewPermission;
     }
 
     /**
@@ -78,7 +87,7 @@ public class ScopeMappedResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public MappingsRepresentation getScopeMappings() {
-        auth.requireView();
+        viewPermission.require();
 
         if (scopeContainer == null) {
             throw new NotFoundException("Could not find client");
@@ -126,7 +135,7 @@ public class ScopeMappedResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getRealmScopeMappings() {
-        auth.requireView();
+        viewPermission.require();
 
         if (scopeContainer == null) {
             throw new NotFoundException("Could not find client");
@@ -150,20 +159,21 @@ public class ScopeMappedResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getAvailableRealmScopeMappings() {
-        auth.requireView();
+        viewPermission.require();
 
         if (scopeContainer == null) {
             throw new NotFoundException("Could not find client");
         }
 
         Set<RoleModel> roles = realm.getRoles();
-        return getAvailable(scopeContainer, roles);
+        return getAvailable(auth, scopeContainer, roles);
     }
 
-    public static List<RoleRepresentation> getAvailable(ScopeContainerModel client, Set<RoleModel> roles) {
+    public static List<RoleRepresentation> getAvailable(AdminPermissionEvaluator auth, ScopeContainerModel client, Set<RoleModel> roles) {
         List<RoleRepresentation> available = new ArrayList<RoleRepresentation>();
         for (RoleModel roleModel : roles) {
             if (client.hasScope(roleModel)) continue;
+            if (!auth.roles().canMapClientScope(roleModel)) continue;
             available.add(ModelToRepresentation.toRepresentation(roleModel));
         }
         return available;
@@ -183,7 +193,7 @@ public class ScopeMappedResource {
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<RoleRepresentation> getCompositeRealmScopeMappings() {
-        auth.requireView();
+        viewPermission.require();
 
         if (scopeContainer == null) {
             throw new NotFoundException("Could not find client");
@@ -210,7 +220,7 @@ public class ScopeMappedResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public void addRealmScopeMappings(List<RoleRepresentation> roles) {
-        auth.requireManage();
+        managePermission.require();
 
         if (scopeContainer == null) {
             throw new NotFoundException("Could not find client");
@@ -236,7 +246,7 @@ public class ScopeMappedResource {
     @DELETE
     @Consumes(MediaType.APPLICATION_JSON)
     public void deleteRealmScopeMappings(List<RoleRepresentation> roles) {
-        auth.requireManage();
+        managePermission.require();
 
         if (scopeContainer == null) {
             throw new NotFoundException("Could not find client");
@@ -268,6 +278,9 @@ public class ScopeMappedResource {
     @Path("clients/{client}")
     public ScopeMappedClientResource getClientByIdScopeMappings(@PathParam("client") String client) {
         ClientModel clientModel = realm.getClientById(client);
-        return new ScopeMappedClientResource(realm, auth, this.scopeContainer, session, clientModel, adminEvent);
+        if (clientModel == null) {
+            throw new NotFoundException("Could not find client");
+        }
+        return new ScopeMappedClientResource(realm, auth, this.scopeContainer, session, clientModel, adminEvent, managePermission, viewPermission);
     }
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index 2685e8e..502fbe3 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -22,8 +22,8 @@ import org.jboss.resteasy.spi.BadRequestException;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.authentication.RequiredActionProvider;
-import org.keycloak.authorization.admin.permissions.MgmtPermissions;
 import org.keycloak.authentication.actiontoken.execactions.ExecuteActionsActionToken;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.common.ClientConnection;
 import org.keycloak.common.Profile;
 import org.keycloak.common.util.Time;
@@ -36,7 +36,6 @@ import org.keycloak.events.EventType;
 import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.admin.ResourceType;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.FederatedIdentityModel;
 import org.keycloak.models.GroupModel;
@@ -116,7 +115,7 @@ public class UsersResource {
 
     protected RealmModel realm;
 
-    private RealmAuth auth;
+    private AdminPermissionEvaluator auth;
 
     private AdminEventBuilder adminEvent;
 
@@ -132,12 +131,10 @@ public class UsersResource {
     @Context
     protected HttpHeaders headers;
 
-    public UsersResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public UsersResource(RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.auth = auth;
         this.realm = realm;
         this.adminEvent = adminEvent.resource(ResourceType.USER);
-
-        auth.init(RealmAuth.Resource.USER);
     }
 
     /**
@@ -151,13 +148,13 @@ public class UsersResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public Response updateUser(final @PathParam("id") String id, final UserRepresentation rep) {
-        auth.requireManage();
 
         try {
             UserModel user = session.users().getUserById(id, realm);
             if (user == null) {
                 return Response.status(Status.NOT_FOUND).build();
             }
+            auth.users().requireManage(user);
 
             Set<String> attrsToRemove;
             if (rep.getAttributes() != null) {
@@ -188,6 +185,8 @@ public class UsersResource {
         } catch (ModelException me) {
             logger.warn("Could not update user!", me);
             return ErrorResponse.exists("Could not update user!");
+        } catch (ForbiddenException fe) {
+            throw fe;
         } catch (Exception me) { // JPA
             logger.warn("Could not update user!", me);// may be committed by JTA which can't
             return ErrorResponse.exists("Could not update user!");
@@ -206,7 +205,7 @@ public class UsersResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response createUser(final @Context UriInfo uriInfo, final UserRepresentation rep) {
-        auth.requireManage();
+        auth.users().requireManage();
 
         // Double-check duplicated username and email here due to federation
         if (session.users().getUserByUsername(rep.getUsername(), realm) != null) {
@@ -291,13 +290,13 @@ public class UsersResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public UserRepresentation getUser(final @PathParam("id") String id) {
-        auth.requireView();
-
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
 
+        auth.users().requireView(user);
+
         UserRepresentation rep = ModelToRepresentation.toRepresentation(session, realm, user);
 
         if (realm.isIdentityFederationEnabled()) {
@@ -325,19 +324,17 @@ public class UsersResource {
     public Map<String, Object> impersonate(final @PathParam("id") String id) {
         ProfileHelper.requireFeature(Profile.Feature.IMPERSONATION);
 
-        auth.init(RealmAuth.Resource.IMPERSONATION);
-        auth.requireManage();
-
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
-        RealmModel authenticatedRealm = auth.getAuth().getRealm();
+        auth.users().requireImpersonate(user);
+        RealmModel authenticatedRealm = auth.adminAuth().getRealm();
         // if same realm logout before impersonation
         boolean sameRealm = false;
         if (authenticatedRealm.getId().equals(realm.getId())) {
             sameRealm = true;
-            UserSessionModel userSession = session.sessions().getUserSession(authenticatedRealm, auth.getAuth().getToken().getSessionState());
+            UserSessionModel userSession = session.sessions().getUserSession(authenticatedRealm, auth.adminAuth().getToken().getSessionState());
             AuthenticationManager.expireIdentityCookie(realm, uriInfo, clientConnection);
             AuthenticationManager.expireRememberMeCookie(realm, uriInfo, clientConnection);
             AuthenticationManager.backchannelLogout(session, authenticatedRealm, userSession, uriInfo, clientConnection, headers, true);
@@ -355,7 +352,7 @@ public class UsersResource {
              .session(userSession)
              .user(user)
              .detail(Details.IMPERSONATOR_REALM,authenticatedRealm.getName())
-             .detail(Details.IMPERSONATOR, auth.getAuth().getUser().getUsername()).success();
+             .detail(Details.IMPERSONATOR, auth.adminAuth().getUser().getUsername()).success();
 
         return result;
     }
@@ -372,12 +369,11 @@ public class UsersResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<UserSessionRepresentation> getSessions(final @PathParam("id") String id) {
-        auth.requireView();
-
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireView(user);
         List<UserSessionModel> sessions = session.sessions().getUserSessions(realm, user);
         List<UserSessionRepresentation> reps = new ArrayList<UserSessionRepresentation>();
         for (UserSessionModel session : sessions) {
@@ -398,12 +394,11 @@ public class UsersResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<UserSessionRepresentation> getOfflineSessions(final @PathParam("id") String id, final @PathParam("clientId") String clientId) {
-        auth.requireView();
-
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireView(user);
         ClientModel client = realm.getClientById(clientId);
         if (client == null) {
             throw new NotFoundException("Client not found");
@@ -439,12 +434,11 @@ public class UsersResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<FederatedIdentityRepresentation> getFederatedIdentity(final @PathParam("id") String id) {
-        auth.requireView();
-
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireView(user);
 
         return getFederatedIdentities(user);
     }
@@ -476,12 +470,12 @@ public class UsersResource {
     @POST
     @NoCache
     public Response addFederatedIdentity(final @PathParam("id") String id, final @PathParam("provider") String provider, FederatedIdentityRepresentation rep) {
-        auth.requireManage();
 
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireManage(user);
         if (session.users().getFederatedIdentity(user, provider, realm) != null) {
             return ErrorResponse.exists("User is already linked with provider");
         }
@@ -502,12 +496,11 @@ public class UsersResource {
     @DELETE
     @NoCache
     public void removeFederatedIdentity(final @PathParam("id") String id, final @PathParam("provider") String provider) {
-        auth.requireManage();
-
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireManage(user);
         if (!session.users().removeFederatedIdentity(realm, user, provider)) {
             throw new NotFoundException("Link not found");
         }
@@ -525,13 +518,11 @@ public class UsersResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<Map<String, Object>> getConsents(final @PathParam("id") String id) {
-        auth.requireView();
-
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
-
+        auth.users().requireView(user);
         List<Map<String, Object>> result = new LinkedList<>();
 
         Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user);
@@ -580,14 +571,16 @@ public class UsersResource {
     @DELETE
     @NoCache
     public void revokeConsent(final @PathParam("id") String id, final @PathParam("client") String clientId) {
-        auth.requireManage();
-
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireManage(user);
 
         ClientModel client = realm.getClientByClientId(clientId);
+        if (client == null) {
+            throw new NotFoundException("Client not found");
+        }
         boolean revokedConsent = session.users().revokeConsentForClient(realm, user.getId(), client.getId());
         boolean revokedOfflineToken = new UserSessionManager(session).revokeOfflineToken(user, client);
 
@@ -612,12 +605,11 @@ public class UsersResource {
     @Path("{id}/logout")
     @POST
     public void logout(final @PathParam("id") String id) {
-        auth.requireManage();
-
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireManage(user);
 
         List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, user);
         for (UserSessionModel userSession : userSessions) {
@@ -635,12 +627,11 @@ public class UsersResource {
     @DELETE
     @NoCache
     public Response deleteUser(final @PathParam("id") String id) {
-        auth.requireManage();
-
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireManage(user);
 
         boolean removed = new UserManager(session).removeUser(realm, user);
         if (removed) {
@@ -675,7 +666,7 @@ public class UsersResource {
                                              @QueryParam("username") String username,
                                              @QueryParam("first") Integer firstResult,
                                              @QueryParam("max") Integer maxResults) {
-        auth.requireView();
+        auth.users().requireQuery();
 
         firstResult = firstResult != null ? firstResult : -1;
         maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS;
@@ -703,7 +694,9 @@ public class UsersResource {
             userModels = session.users().getUsers(realm, firstResult, maxResults, false);
         }
 
+        boolean canViewGlobal = auth.users().canView();
         for (UserModel user : userModels) {
+            if (!canViewGlobal  && !auth.users().canView(user)) continue;
             results.add(ModelToRepresentation.toRepresentation(session, realm, user));
         }
         return results;
@@ -714,21 +707,23 @@ public class UsersResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public Integer getUsersCount() {
-        auth.requireView();
+        auth.users().requireView();
 
         return session.users().getUsersCount(realm);
     }
 
     @Path("{id}/role-mappings")
     public RoleMapperResource getRoleMappings(@PathParam("id") String id) {
-        auth.init(RealmAuth.Resource.USER);
 
         UserModel user = session.users().getUserById(id, realm);
 
-        RoleMapperResource resource =  new RoleMapperResource(realm, auth, user, adminEvent);
-        resource.setManageCheck(() -> {
-            return new MgmtPermissions(session, realm, auth.getAuth()).users().canManage();
-        });
+        if (user == null) {
+            throw new NotFoundException("User not found");
+        }
+
+        AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.users().requireManage(user);
+        AdminPermissionEvaluator.RequirePermissionCheck viewCheck = () -> auth.users().requireView(user);
+        RoleMapperResource resource =  new RoleMapperResource(realm, auth, user, adminEvent, manageCheck, viewCheck);
         ResteasyProviderFactory.getInstance().injectProperties(resource);
         return resource;
 
@@ -744,12 +739,12 @@ public class UsersResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public void disableCredentialType(@PathParam("id") String id, List<String> credentialTypes) {
-        auth.requireManage();
 
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireManage(user);
         if (credentialTypes == null) return;
         for (String type : credentialTypes) {
             session.userCredentialManager().disableCredentialType(realm, user, type);
@@ -771,12 +766,12 @@ public class UsersResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public void resetPassword(@PathParam("id") String id, CredentialRepresentation pass) {
-        auth.requireManage();
 
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireManage(user);
         if (pass == null || pass.getValue() == null || !CredentialRepresentation.PASSWORD.equals(pass.getType())) {
             throw new BadRequestException("No password provided");
         }
@@ -792,7 +787,7 @@ public class UsersResource {
         } catch (ReadOnlyException mre) {
             throw new BadRequestException("Can't reset password as account is read only");
         } catch (ModelException e) {
-            Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale());
+            Properties messages = AdminRoot.getMessages(session, realm, auth.adminAuth().getToken().getLocale());
             throw new ErrorResponseException(e.getMessage(), MessageFormat.format(messages.getProperty(e.getMessage(), e.getMessage()), e.getParameters()),
                     Status.BAD_REQUEST);
         }
@@ -810,13 +805,15 @@ public class UsersResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public void removeTotp(@PathParam("id") String id) {
-        auth.requireManage();
 
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
 
+        auth.users().requireManage(user);
+
+
         session.userCredentialManager().disableCredentialType(realm, user, CredentialModel.OTP);
         adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
     }
@@ -870,12 +867,12 @@ public class UsersResource {
                                         @QueryParam(OIDCLoginProtocol.CLIENT_ID_PARAM) String clientId,
                                         @QueryParam("lifespan") Integer lifespan,
                                         List<String> actions) {
-        auth.requireManage();
 
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             return ErrorResponse.error("User not found", Response.Status.NOT_FOUND);
         }
+        auth.users().requireManage(user);
 
         if (user.getEmail() == null) {
             return ErrorResponse.error("User email missing", Response.Status.BAD_REQUEST);
@@ -964,12 +961,12 @@ public class UsersResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public List<GroupRepresentation> groupMembership(@PathParam("id") String id) {
-        auth.requireView();
 
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireView(user);
         List<GroupRepresentation> memberships = new LinkedList<>();
         for (GroupModel group : user.getGroups()) {
             memberships.add(ModelToRepresentation.toRepresentation(group, false));
@@ -981,12 +978,13 @@ public class UsersResource {
     @Path("{id}/groups/{groupId}")
     @NoCache
     public void removeMembership(@PathParam("id") String id, @PathParam("groupId") String groupId) {
-        auth.requireManage();
 
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireManage(user);
+
         GroupModel group = session.realms().getGroupById(groupId, realm);
         if (group == null) {
             throw new NotFoundException("Group not found");
@@ -998,7 +996,7 @@ public class UsersResource {
                 adminEvent.operation(OperationType.DELETE).resource(ResourceType.GROUP_MEMBERSHIP).representation(ModelToRepresentation.toRepresentation(group, true)).resourcePath(uriInfo).success();
             }
         } catch (ModelException me) {
-            Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale());
+            Properties messages = AdminRoot.getMessages(session, realm, auth.adminAuth().getToken().getLocale());
             throw new ErrorResponseException(me.getMessage(), MessageFormat.format(messages.getProperty(me.getMessage(), me.getMessage()), me.getParameters()),
                     Response.Status.BAD_REQUEST);
         }
@@ -1008,12 +1006,12 @@ public class UsersResource {
     @Path("{id}/groups/{groupId}")
     @NoCache
     public void joinGroup(@PathParam("id") String id, @PathParam("groupId") String groupId) {
-        auth.requireManage();
 
         UserModel user = session.users().getUserById(id, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
+        auth.users().requireManage(user);
         GroupModel group = session.realms().getGroupById(groupId, realm);
         if (group == null) {
             throw new NotFoundException("Group not found");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserStorageProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserStorageProviderResource.java
index 4ffcf86..638f57b 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/UserStorageProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UserStorageProviderResource.java
@@ -26,6 +26,7 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.services.ServicesLogger;
 import org.keycloak.services.managers.UserStorageSyncManager;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
 import org.keycloak.storage.UserStorageProvider;
 import org.keycloak.storage.UserStorageProviderModel;
 import org.keycloak.storage.ldap.LDAPStorageProvider;
@@ -55,7 +56,7 @@ public class UserStorageProviderResource {
 
     protected RealmModel realm;
 
-    protected RealmAuth auth;
+    protected AdminPermissionEvaluator auth;
 
     protected AdminEventBuilder adminEvent;
 
@@ -71,12 +72,10 @@ public class UserStorageProviderResource {
     @Context
     protected HttpHeaders headers;
 
-    public UserStorageProviderResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
+    public UserStorageProviderResource(RealmModel realm, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
         this.auth = auth;
         this.realm = realm;
         this.adminEvent = adminEvent;
-
-        auth.init(RealmAuth.Resource.USER);
     }
 
     /**
@@ -94,7 +93,7 @@ public class UserStorageProviderResource {
     @Produces(MediaType.APPLICATION_JSON)
     public SynchronizationResult syncUsers(@PathParam("id") String id,
                                            @QueryParam("action") String action) {
-        auth.requireManage();
+        auth.users().requireManage();
 
         ComponentModel model = realm.getComponent(id);
         if (model == null) {
@@ -139,7 +138,7 @@ public class UserStorageProviderResource {
     @Path("{id}/remove-imported-users")
     @NoCache
     public void removeImportedUsers(@PathParam("id") String id) {
-        auth.requireManage();
+        auth.users().requireManage();
 
         ComponentModel model = realm.getComponent(id);
         if (model == null) {
@@ -162,7 +161,7 @@ public class UserStorageProviderResource {
     @Path("{id}/unlink-users")
     @NoCache
     public void unlinkUsers(@PathParam("id") String id) {
-        auth.requireManage();
+        auth.users().requireManage();
 
         ComponentModel model = realm.getComponent(id);
         if (model == null) {
@@ -187,7 +186,7 @@ public class UserStorageProviderResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public SynchronizationResult syncMapperData(@PathParam("parentId") String parentId, @PathParam("id") String mapperId, @QueryParam("direction") String direction) {
-        auth.requireManage();
+        auth.users().requireManage();
 
         ComponentModel parentModel = realm.getComponent(parentId);
         if (parentModel == null) throw new NotFoundException("Parent model not found");
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java
index e001f60..b6bdc4c 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java
@@ -19,8 +19,9 @@ package org.keycloak.testsuite.admin;
 import org.junit.Assert;
 import org.junit.Test;
 import org.keycloak.admin.client.Keycloak;
-import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.authorization.admin.permissions.MgmtPermissions;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement;
+import org.keycloak.services.resources.admin.permissions.AdminPermissions;
 import org.keycloak.authorization.model.Policy;
 import org.keycloak.authorization.model.ResourceServer;
 import org.keycloak.models.AdminRoles;
@@ -35,24 +36,14 @@ import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.representations.idm.authorization.DecisionEffect;
 import org.keycloak.representations.idm.authorization.DecisionStrategy;
-import org.keycloak.representations.idm.authorization.PolicyEvaluationRequest;
-import org.keycloak.representations.idm.authorization.PolicyEvaluationResponse;
 import org.keycloak.testsuite.AbstractKeycloakTest;
-import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
 import org.keycloak.testsuite.util.AdminClientUtil;
 
 import javax.ws.rs.ClientErrorException;
-import javax.ws.rs.ForbiddenException;
-import javax.ws.rs.core.Response;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
 
-import static org.keycloak.testsuite.auth.page.AuthRealm.ADMIN;
-import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
 import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
 
 /**
@@ -73,7 +64,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
 
     public static void setupPolices(KeycloakSession session) {
         RealmModel realm = session.realms().getRealmByName(TEST);
-        MgmtPermissions permissions = new MgmtPermissions(session, realm);
+        AdminPermissionManagement permissions = AdminPermissions.management(session, realm);
         RoleModel realmRole = realm.addRole("realm-role");
         RoleModel realmRole2 = realm.addRole("realm-role2");
         ClientModel client1 = realm.addClient("role-namespace");
@@ -110,7 +101,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
         // setup Users manage policies
         {
             permissions.users().setPermissionsEnabled(true);
-            ResourceServer server = permissions.users().resourceServer();
+            ResourceServer server = permissions.realmResourceServer();
             Policy managerPolicy = permissions.roles().rolePolicy(server, managerRole);
             Policy permission = permissions.users().managePermission();
             permission.addAssociatedPolicy(managerPolicy);
@@ -177,9 +168,8 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
         // test authorized
         {
             UserModel user = session.users().getUserByUsername("authorized", realm);
-            MgmtPermissions permissionsForAdmin = new MgmtPermissions(session, realm);
-            permissionsForAdmin.setIdentity(user);
-            Assert.assertTrue(permissionsForAdmin.users().canManage(user));
+            AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
+            Assert.assertTrue(permissionsForAdmin.users().canManage());
             Assert.assertTrue(permissionsForAdmin.roles().canMapRole(realmRole));
             Assert.assertTrue(permissionsForAdmin.roles().canMapRole(realmRole2));
             Assert.assertTrue(permissionsForAdmin.roles().canMapRole(clientRole));
@@ -187,9 +177,8 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
         // test composite role
         {
             UserModel user = session.users().getUserByUsername("authorizedComposite", realm);
-            MgmtPermissions permissionsForAdmin = new MgmtPermissions(session, realm);
-            permissionsForAdmin.setIdentity(user);
-            Assert.assertTrue(permissionsForAdmin.users().canManage(user));
+            AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
+            Assert.assertTrue(permissionsForAdmin.users().canManage());
             Assert.assertTrue(permissionsForAdmin.roles().canMapRole(realmRole));
             Assert.assertTrue(permissionsForAdmin.roles().canMapRole(realmRole2));
             Assert.assertTrue(permissionsForAdmin.roles().canMapRole(clientRole));
@@ -198,9 +187,8 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
         // test unauthorized
         {
             UserModel user = session.users().getUserByUsername("unauthorized", realm);
-            MgmtPermissions permissionsForAdmin = new MgmtPermissions(session, realm);
-            permissionsForAdmin.setIdentity(user);
-            Assert.assertFalse(permissionsForAdmin.users().canManage(user));
+            AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
+            Assert.assertFalse(permissionsForAdmin.users().canManage());
             Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
             Assert.assertFalse(permissionsForAdmin.roles().canMapRole(clientRole));
 
@@ -210,9 +198,8 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
         // test unauthorized mapper
         {
             UserModel user = session.users().getUserByUsername("unauthorizedMapper", realm);
-            MgmtPermissions permissionsForAdmin = new MgmtPermissions(session, realm);
-            permissionsForAdmin.setIdentity(user);
-            Assert.assertTrue(permissionsForAdmin.users().canManage(user));
+            AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
+            Assert.assertTrue(permissionsForAdmin.users().canManage());
             Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
             Assert.assertFalse(permissionsForAdmin.roles().canMapRole(clientRole));
             // will result to true because realmRole2 does not have any policies attached to this permission
@@ -391,6 +378,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
     }
     // testRestEvaluationMasterRealm
     // testRestEvaluationMasterAdminTestRealm
+    // test role deletion that it cleans up authz objects
 
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
index 531157d..e502ffa 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
@@ -51,7 +51,7 @@ import org.keycloak.representations.idm.authorization.PolicyRepresentation;
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
 import org.keycloak.representations.idm.authorization.ScopeRepresentation;
-import org.keycloak.services.resources.admin.RealmAuth.Resource;
+import org.keycloak.services.resources.admin.AdminAuth.Resource;
 import org.keycloak.testsuite.AbstractKeycloakTest;
 import org.keycloak.testsuite.Assert;
 import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
@@ -77,8 +77,8 @@ import java.util.concurrent.atomic.AtomicReference;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
-import static org.keycloak.services.resources.admin.RealmAuth.Resource.AUTHORIZATION;
-import static org.keycloak.services.resources.admin.RealmAuth.Resource.CLIENT;
+import static org.keycloak.services.resources.admin.AdminAuth.Resource.AUTHORIZATION;
+import static org.keycloak.services.resources.admin.AdminAuth.Resource.CLIENT;
 import org.keycloak.testsuite.ProfileAssume;
 
 /**
@@ -313,11 +313,18 @@ public class PermissionsTest extends AbstractKeycloakTest {
                 realm.removeDefaultGroup("nosuch");
             }
         }, Resource.REALM, true);
+        GroupRepresentation newGroup = new GroupRepresentation();
+        newGroup.setName("sample");
+        adminClient.realm(REALM_NAME).groups().add(newGroup);
+        GroupRepresentation group = adminClient.realms().realm(REALM_NAME).getGroupByPath("sample");
+
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.getGroupByPath("nosuch");
+                realm.getGroupByPath("sample");
             }
-        }, Resource.REALM, false);
+        }, Resource.USER, false);
+
+        adminClient.realms().realm(REALM_NAME).groups().group(group.getId()).remove();
 
         invoke(new InvocationWithResponse() {
             public void invoke(RealmResource realm, AtomicReference<Response> response) {
@@ -954,6 +961,10 @@ public class PermissionsTest extends AbstractKeycloakTest {
 
     @Test
     public void roles() {
+        RoleRepresentation newRole = new RoleRepresentation();
+        newRole.setName("sample-role");
+        adminClient.realm(REALM_NAME).roles().create(newRole);
+
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
                 realm.roles().list();
@@ -961,12 +972,12 @@ public class PermissionsTest extends AbstractKeycloakTest {
         }, Resource.REALM, false, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.roles().get("nosuch").toRepresentation();
+                realm.roles().get("sample-role").toRepresentation();
             }
         }, Resource.REALM, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.roles().get("nosuch").update(new RoleRepresentation());
+                realm.roles().get("sample-role").update(newRole);
             }
         }, Resource.REALM, true);
         invoke(new Invocation() {
@@ -976,39 +987,42 @@ public class PermissionsTest extends AbstractKeycloakTest {
         }, Resource.REALM, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.roles().deleteRole("nosuch");
+                realm.roles().deleteRole("sample-role");
+                // need to recreate for other tests
+                realm.roles().create(newRole);
             }
         }, Resource.REALM, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.roles().get("nosuch").getRoleComposites();
+                realm.roles().get("sample-role").getRoleComposites();
             }
         }, Resource.REALM, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.roles().get("nosuch").addComposites(Collections.<RoleRepresentation>emptyList());
+                realm.roles().get("sample-role").addComposites(Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.REALM, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.roles().get("nosuch").deleteComposites(Collections.<RoleRepresentation>emptyList());
+                realm.roles().get("sample-role").deleteComposites(Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.REALM, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.roles().get("nosuch").getRoleComposites();
+                realm.roles().get("sample-role").getRoleComposites();
             }
         }, Resource.REALM, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.roles().get("nosuch").getRealmRoleComposites();
+                realm.roles().get("sample-role").getRealmRoleComposites();
             }
         }, Resource.REALM, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.roles().get("nosuch").getClientRoleComposites("nosuch");
+                realm.roles().get("sample-role").getClientRoleComposites("nosuch");
             }
         }, Resource.REALM, false);
+        adminClient.realms().realm(REALM_NAME).roles().deleteRole("sample-role");
     }
 
     @Test
@@ -1175,51 +1189,61 @@ public class PermissionsTest extends AbstractKeycloakTest {
 
     @Test
     public void rolesById() {
+        RoleRepresentation newRole = new RoleRepresentation();
+        newRole.setName("role-by-id");
+        adminClient.realm(REALM_NAME).roles().create(newRole);
+        RoleRepresentation role = adminClient.realm(REALM_NAME).roles().get("role-by-id").toRepresentation();
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.rolesById().getRole("nosuch");
+                realm.rolesById().getRole(role.getId());
             }
         }, Resource.REALM, false, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.rolesById().updateRole("nosuch", new RoleRepresentation());
+                realm.rolesById().updateRole(role.getId(), role);
             }
         }, Resource.REALM, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.rolesById().deleteRole("nosuch");
+                realm.rolesById().deleteRole(role.getId());
+                // need to recreate for other tests
+                realm.roles().create(newRole);
+                RoleRepresentation temp = realm.roles().get("role-by-id").toRepresentation();
+                role.setId(temp.getId());
             }
         }, Resource.REALM, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.rolesById().getRoleComposites("nosuch");
+                realm.rolesById().getRoleComposites(role.getId());
             }
         }, Resource.REALM, false, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.rolesById().addComposites("nosuch", Collections.<RoleRepresentation>emptyList());
+                realm.rolesById().addComposites(role.getId(), Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.REALM, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.rolesById().deleteComposites("nosuch", Collections.<RoleRepresentation>emptyList());
+                realm.rolesById().deleteComposites(role.getId(), Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.REALM, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.rolesById().getRoleComposites("nosuch");
+                realm.rolesById().getRoleComposites(role.getId());
             }
         }, Resource.REALM, false, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.rolesById().getRealmRoleComposites("nosuch");
+                realm.rolesById().getRealmRoleComposites(role.getId());
             }
         }, Resource.REALM, false, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.rolesById().getClientRoleComposites("nosuch", "nosuch");
+                realm.rolesById().getClientRoleComposites(role.getId(), "nosuch");
             }
         }, Resource.REALM, false, true);
+
+        adminClient.realm(REALM_NAME).roles().deleteRole("role-by-id");
     }
 
     @Test
@@ -1237,85 +1261,95 @@ public class PermissionsTest extends AbstractKeycloakTest {
             }
         }, Resource.USER, true);
 
+        GroupRepresentation group = adminClient.realms().realm(REALM_NAME).getGroupByPath("mygroup");
+        ClientRepresentation realmAccessClient = adminClient.realms().realm(REALM_NAME).clients().findByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID).get(0);
+
+
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").toRepresentation();
+                realm.groups().group(group.getId()).toRepresentation();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").update(new GroupRepresentation());
+                realm.groups().group(group.getId()).update(group);
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").remove();
-            }
-        }, Resource.USER, true);
-        invoke(new Invocation() {
-            public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").members(0, 100);
+                realm.groups().group(group.getId()).members(0, 100);
             }
         }, Resource.USER, false);
         invoke(new InvocationWithResponse() {
             public void invoke(RealmResource realm, AtomicReference<Response> response) {
-                response.set(realm.groups().group("nosuch").subGroup(new GroupRepresentation()));
+                GroupRepresentation subgroup = new GroupRepresentation();
+                subgroup.setName("sub");
+                response.set(realm.groups().group(group.getId()).subGroup(subgroup));
             }
         }, Resource.USER, true);
 
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().getAll();
+                realm.groups().group(group.getId()).roles().getAll();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().realmLevel().listAll();
+                realm.groups().group(group.getId()).roles().realmLevel().listAll();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().realmLevel().listEffective();
+                realm.groups().group(group.getId()).roles().realmLevel().listEffective();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().realmLevel().listAvailable();
+                realm.groups().group(group.getId()).roles().realmLevel().listAvailable();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().realmLevel().add(Collections.<RoleRepresentation>emptyList());
+                realm.groups().group(group.getId()).roles().realmLevel().add(Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().realmLevel().remove(Collections.<RoleRepresentation>emptyList());
+                realm.groups().group(group.getId()).roles().realmLevel().remove(Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().clientLevel("nosuch").listAll();
+                realm.groups().group(group.getId()).roles().clientLevel(realmAccessClient.getId()).listAll();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().clientLevel("nosuch").listEffective();
+                realm.groups().group(group.getId()).roles().clientLevel(realmAccessClient.getId()).listEffective();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().clientLevel("nosuch").listAvailable();
+                realm.groups().group(group.getId()).roles().clientLevel(realmAccessClient.getId()).listAvailable();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().clientLevel("nosuch").add(Collections.<RoleRepresentation>emptyList());
+                realm.groups().group(group.getId()).roles().clientLevel(realmAccessClient.getId()).add(Collections.<RoleRepresentation>emptyList());
+            }
+        }, Resource.USER, true);
+        invoke(new Invocation() {
+            public void invoke(RealmResource realm) {
+                realm.groups().group(group.getId()).roles().clientLevel(realmAccessClient.getId()).remove(Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.groups().group("nosuch").roles().clientLevel("nosuch").remove(Collections.<RoleRepresentation>emptyList());
+                realm.groups().group(group.getId()).remove();
+                group.setId(null);
+                realm.groups().add(group);
+                GroupRepresentation temp = realm.getGroupByPath("mygroup");
+                group.setId(temp.getId());
             }
         }, Resource.USER, true);
     }
@@ -1323,176 +1357,181 @@ public class PermissionsTest extends AbstractKeycloakTest {
     // Permissions for impersonation tested in ImpersonationTest
     @Test
     public void users() {
-        invoke(new Invocation() {
-            public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").toRepresentation();
-            }
-        }, Resource.USER, false);
         invoke(new InvocationWithResponse() {
             public void invoke(RealmResource realm, AtomicReference<Response> response) {
                 response.set(realm.users().create(UserBuilder.create().username("testuser").build()));
             }
         }, Resource.USER, true);
+        UserRepresentation user = adminClient.realms().realm(REALM_NAME).users().search("testUser").get(0);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").update(UserBuilder.create().enabled(true).build());
+                realm.users().get(user.getId()).remove();
+                realm.users().create(user);
+                UserRepresentation temp = realm.users().search("testUser").get(0);
+                user.setId(temp.getId());
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().search("foo", 0, 1);
+                realm.users().get(user.getId()).toRepresentation();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
+                realm.users().get(user.getId()).update(user);
+            }
+        }, Resource.USER, true);
+        invoke(new Invocation() {
+            public void invoke(RealmResource realm) {
                 realm.users().count();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").getUserSessions();
+                realm.users().get(user.getId()).getUserSessions();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").getOfflineSessions("nosuch");
+                realm.users().get(user.getId()).getOfflineSessions("nosuch");
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").getFederatedIdentity();
+                realm.users().get(user.getId()).getFederatedIdentity();
             }
         }, Resource.USER, false);
         invoke(new InvocationWithResponse() {
             public void invoke(RealmResource realm, AtomicReference<Response> response) {
                 response.set(realm.users()
-                        .get("nosuch")
+                        .get(user.getId())
                         .addFederatedIdentity("nosuch",
                                 FederatedIdentityBuilder.create().identityProvider("nosuch").userId("nosuch").userName("nosuch").build()));
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").removeFederatedIdentity("nosuch");
+                realm.users().get(user.getId()).removeFederatedIdentity("nosuch");
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").getConsents();
+                realm.users().get(user.getId()).getConsents();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").revokeConsent("testclient");
+                realm.users().get(user.getId()).revokeConsent("testclient");
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").logout();
+                realm.users().get(user.getId()).logout();
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").remove();
+                realm.users().get(user.getId()).resetPassword(CredentialBuilder.create().password("password").build());
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").resetPassword(CredentialBuilder.create().password("password").build());
+                realm.users().get(user.getId()).removeTotp();
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").removeTotp();
+                realm.users().get(user.getId()).resetPasswordEmail();
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").resetPasswordEmail();
+                realm.users().get(user.getId()).executeActionsEmail(Collections.<String>emptyList());
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").executeActionsEmail(Collections.<String>emptyList());
+                realm.users().get(user.getId()).sendVerifyEmail();
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").sendVerifyEmail();
-            }
-        }, Resource.USER, true);
-        invoke(new Invocation() {
-            public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").groups();
+                realm.users().get(user.getId()).groups();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").leaveGroup("nosuch");
+                realm.users().get(user.getId()).leaveGroup("nosuch");
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").joinGroup("nosuch");
+                realm.users().get(user.getId()).joinGroup("nosuch");
             }
         }, Resource.USER, true);
 
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().getAll();
+                realm.users().get(user.getId()).roles().getAll();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().realmLevel().listAll();
+                realm.users().get(user.getId()).roles().realmLevel().listAll();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().realmLevel().listAvailable();
+                realm.users().get(user.getId()).roles().realmLevel().listAvailable();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().realmLevel().listEffective();
+                realm.users().get(user.getId()).roles().realmLevel().listEffective();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().realmLevel().add(Collections.<RoleRepresentation>emptyList());
+                realm.users().get(user.getId()).roles().realmLevel().add(Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().realmLevel().remove(Collections.<RoleRepresentation>emptyList());
+                realm.users().get(user.getId()).roles().realmLevel().remove(Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.USER, true);
 
+        ClientRepresentation realmAccessClient = adminClient.realms().realm(REALM_NAME).clients().findByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID).get(0);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().clientLevel("nosuch").listAll();
+                realm.users().get(user.getId()).roles().clientLevel(realmAccessClient.getId()).listAll();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().clientLevel("nosuch").listAvailable();
+                realm.users().get(user.getId()).roles().clientLevel(realmAccessClient.getId()).listAvailable();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().clientLevel("nosuch").listEffective();
+                realm.users().get(user.getId()).roles().clientLevel(realmAccessClient.getId()).listEffective();
             }
         }, Resource.USER, false);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().clientLevel("nosuch").add(Collections.<RoleRepresentation>emptyList());
+                realm.users().get(user.getId()).roles().clientLevel(realmAccessClient.getId()).add(Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.USER, true);
         invoke(new Invocation() {
             public void invoke(RealmResource realm) {
-                realm.users().get("nosuch").roles().clientLevel("nosuch").remove(Collections.<RoleRepresentation>emptyList());
+                realm.users().get(user.getId()).roles().clientLevel(realmAccessClient.getId()).remove(Collections.<RoleRepresentation>emptyList());
             }
         }, Resource.USER, true);
+        invoke(new Invocation() {
+            public void invoke(RealmResource realm) {
+                realm.users().search("foo", 0, 1);
+            }
+        }, Resource.USER, false);
     }
 
     @Test