You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2020/02/17 15:10:36 UTC

[atlas] branch master updated: ATLAS-3622: added authorization for add/remove of labels, update of namespace attributes

This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/master by this push:
     new 8fe3edd  ATLAS-3622: added authorization for add/remove of labels, update of namespace attributes
8fe3edd is described below

commit 8fe3edd2a7d480408ec3d43762cfb43887d5fa19
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Sun Feb 16 17:15:34 2020 -0800

    ATLAS-3622: added authorization for add/remove of labels, update of namespace attributes
---
 .../atlas/authorize/AtlasEntityAccessRequest.java  | 101 +++++++++++++++++--
 .../org/apache/atlas/authorize/AtlasPrivilege.java |   7 +-
 .../authorize/simple/AtlasSimpleAuthorizer.java    |  13 ++-
 .../authorize/simple/AtlasSimpleAuthzPolicy.java   |  24 +++++
 .../main/resources/atlas-simple-authz-policy.json  |  14 ++-
 .../simple/AtlasSimpleAuthorizerTest.java          |  67 ++++++++++++
 .../test/resources/atlas-simple-authz-policy.json  |  14 ++-
 .../store/graph/v2/AtlasEntityStoreV2.java         | 112 ++++++++++++++++++++-
 .../store/graph/v2/EntityGraphMapper.java          |   2 +-
 .../store/graph/v2/EntityGraphRetriever.java       |  53 ++++++----
 10 files changed, 366 insertions(+), 41 deletions(-)

diff --git a/authorization/src/main/java/org/apache/atlas/authorize/AtlasEntityAccessRequest.java b/authorization/src/main/java/org/apache/atlas/authorize/AtlasEntityAccessRequest.java
index 951e5c9..f2e4838 100644
--- a/authorization/src/main/java/org/apache/atlas/authorize/AtlasEntityAccessRequest.java
+++ b/authorization/src/main/java/org/apache/atlas/authorize/AtlasEntityAccessRequest.java
@@ -28,45 +28,53 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest {
     private final AtlasEntityHeader   entity;
     private final String              entityId;
     private final AtlasClassification classification;
+    private final String              label;
+    private final String              namespaceName;
     private final String              attributeName;
     private final AtlasTypeRegistry   typeRegistry;
     private final Set<String>         entityClassifications;
 
 
     public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action) {
-        this(typeRegistry, action, null, null, null, null, null);
+        this(typeRegistry, action, null, null, null, null, null, null, null);
     }
 
     public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity) {
-        this(typeRegistry, action, entity, null, null, null, null);
+        this(typeRegistry, action, entity, null, null, null, null, null, null);
     }
 
     public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification) {
-        this(typeRegistry, action, entity, classification, null, null, null);
+        this(typeRegistry, action, entity, classification, null, null, null, null, null);
     }
 
     public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String attributeName) {
-        this(typeRegistry, action, entity, null, attributeName, null, null);
+        this(typeRegistry, action, entity, null, attributeName, null, null, null, null);
     }
 
     public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String userName, Set<String> userGroups) {
-        this(typeRegistry, action, entity, null, null, userName, userGroups);
+        this(typeRegistry, action, entity, null, null, null, null, userName, userGroups);
     }
 
     public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String userName, Set<String> userGroups) {
-        this(typeRegistry, action, entity, classification, null, userName, userGroups);
+        this(typeRegistry, action, entity, classification, null, null, null, userName, userGroups);
     }
 
     public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String attributeName, String userName, Set<String> userGroups) {
-        this(typeRegistry, action, entity, null, attributeName, userName, userGroups);
+        this(typeRegistry, action, entity, null, attributeName, null, null, userName, userGroups);
     }
 
     public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String attributeName, String userName, Set<String> userGroups) {
+        this(typeRegistry, action, entity, classification, attributeName, null, null, userName, userGroups);
+    }
+
+    public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String attributeName, String label, String namespaceName, String userName, Set<String> userGroups) {
         super(action, userName, userGroups);
 
         this.entity                = entity;
         this.entityId              = super.getEntityId(entity, typeRegistry);
         this.classification        = classification;
+        this.label                 = label;
+        this.namespaceName         = namespaceName;
         this.attributeName         = attributeName;
         this.typeRegistry          = typeRegistry;
         this.entityClassifications = super.getClassificationNames(entity);
@@ -84,6 +92,14 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest {
         return classification;
     }
 
+    public String getLabel() {
+        return label;
+    }
+
+    public String getNamespaceName() {
+        return namespaceName;
+    }
+
     public String getAttributeName() {
         return attributeName;
     }
@@ -106,11 +122,80 @@ public class AtlasEntityAccessRequest extends AtlasAccessRequest {
 
     @Override
     public String toString() {
-        return "AtlasEntityAccessRequest[entity=" + entity + ", classification=" + classification + ", attributeName=" + attributeName +
+        return "AtlasEntityAccessRequest[entity=" + entity + ", classification=" + classification + ", label=" + label + ", namespaceName=" + namespaceName + ", attributeName=" + attributeName +
                 ", action=" + getAction() + ", accessTime=" + getAccessTime() + ", user=" + getUser() +
                 ", userGroups=" + getUserGroups() + ", clientIPAddress=" + getClientIPAddress() +
                 ", forwardedAddresses=" + getForwardedAddresses() + ", remoteIPAddress=" + getRemoteIPAddress() + "]";
     }
+
+    public static class AtlasEntityAccessRequestBuilder {
+        private final AtlasTypeRegistry   typeRegistry;
+        private final AtlasPrivilege      action;
+        private       String              userName;
+        private       Set<String>         userGroups;
+        private       AtlasEntityHeader   entity;
+        private       AtlasClassification classification;
+        private       String              label;
+        private       String              namespaceName;
+        private       String              attributeName;
+
+        public AtlasEntityAccessRequestBuilder(AtlasTypeRegistry typeRegistry, AtlasPrivilege action) {
+            this.typeRegistry = typeRegistry;
+            this.action       = action;
+        }
+
+        public AtlasEntityAccessRequestBuilder(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity) {
+            this.typeRegistry = typeRegistry;
+            this.action       = action;
+            this.entity       = entity;
+        }
+
+        public AtlasEntityAccessRequestBuilder setUserName(String userName) {
+            this.userName = userName;
+
+            return this;
+        }
+
+        public AtlasEntityAccessRequestBuilder setUserGroups(Set<String> userGroups) {
+            this.userGroups = userGroups;
+
+            return this;
+        }
+
+        public AtlasEntityAccessRequestBuilder setEntity(AtlasEntityHeader entity) {
+            this.entity = entity;
+
+            return this;
+        }
+
+        public AtlasEntityAccessRequestBuilder setClassification(AtlasClassification classification) {
+            this.classification = classification;
+
+            return this;
+        }
+
+        public AtlasEntityAccessRequestBuilder setLabel(String label) {
+            this.label = label;
+
+            return this;
+        }
+
+        public AtlasEntityAccessRequestBuilder setNamespaceName(String namespaceName) {
+            this.namespaceName = namespaceName;
+
+            return this;
+        }
+
+        public AtlasEntityAccessRequestBuilder setAttributeName(String attributeName) {
+            this.attributeName = attributeName;
+
+            return this;
+        }
+
+        public AtlasEntityAccessRequest build() {
+            return new AtlasEntityAccessRequest(typeRegistry, action, entity, classification, attributeName, label, namespaceName, userName, userGroups);
+        }
+    }
 }
 
 
diff --git a/authorization/src/main/java/org/apache/atlas/authorize/AtlasPrivilege.java b/authorization/src/main/java/org/apache/atlas/authorize/AtlasPrivilege.java
index 38b68fa..7d81e22 100644
--- a/authorization/src/main/java/org/apache/atlas/authorize/AtlasPrivilege.java
+++ b/authorization/src/main/java/org/apache/atlas/authorize/AtlasPrivilege.java
@@ -37,7 +37,12 @@ public enum AtlasPrivilege {
      RELATIONSHIP_ADD("add-relationship"),
      RELATIONSHIP_UPDATE("update-relationship"),
      RELATIONSHIP_REMOVE("remove-relationship"),
-     ADMIN_PURGE("admin-purge");
+
+     ADMIN_PURGE("admin-purge"),
+
+     ENTITY_ADD_LABEL("entity-add-label"),
+     ENTITY_REMOVE_LABEL("entity-remove-label"),
+     ENTITY_UPDATE_NAMESPACE("entity-update-namespace");
 
      private final String type;
 
diff --git a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizer.java b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizer.java
index e210958..5f0c7b2 100644
--- a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizer.java
+++ b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizer.java
@@ -238,8 +238,9 @@ public final class AtlasSimpleAuthorizer implements AtlasAuthorizer {
 
             if (permissions != null) {
                 for (AtlasEntityPermission permission : permissions) {
-                    // match entity-type/entity-id/attribute
-                    if (isMatchAny(entityTypes, permission.getEntityTypes()) && isMatch(entityId, permission.getEntityIds()) && isMatch(attribute, permission.getAttributes())) {
+                    // match entity-type/entity-id/lable/namespace/attribute
+                    if (isMatchAny(entityTypes, permission.getEntityTypes()) && isMatch(entityId, permission.getEntityIds()) && isMatch(attribute, permission.getAttributes())
+                         && isLabelMatch(request, permission) && isNamespaceMatch(request, permission)) {
                         // match permission/classification
                         if (!hasEntityAccess) {
                             if (isMatch(action, permission.getPrivileges()) && isMatch(classification, permission.getClassifications())) {
@@ -458,6 +459,14 @@ public final class AtlasSimpleAuthorizer implements AtlasAuthorizer {
             }
         }
     }
+
+    private boolean isLabelMatch(AtlasEntityAccessRequest request, AtlasEntityPermission permission) {
+        return (AtlasPrivilege.ENTITY_ADD_LABEL.equals(request.getAction()) || AtlasPrivilege.ENTITY_REMOVE_LABEL.equals(request.getAction())) ? isMatch(request.getLabel(), permission.getLabels()) : true;
+    }
+
+    private boolean isNamespaceMatch(AtlasEntityAccessRequest request, AtlasEntityPermission permission) {
+        return AtlasPrivilege.ENTITY_UPDATE_NAMESPACE.equals(request.getAction()) ? isMatch(request.getNamespaceName(), permission.getNamespaces()) : true;
+    }
 }
 
 
diff --git a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthzPolicy.java b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthzPolicy.java
index 485d4e8..899e386 100644
--- a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthzPolicy.java
+++ b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthzPolicy.java
@@ -209,16 +209,24 @@ public class AtlasSimpleAuthzPolicy implements Serializable {
         private List<String> entityTypes;     // name of entity-type, wildcards supported
         private List<String> entityIds;       // value of entity-unique attribute, wildcards supported
         private List<String> classifications; // name of classification-type, wildcards supported
+        private List<String> labels;          // labels, wildcards supported
+        private List<String> namespaces;      // name of namespace-type, wildcards supported
         private List<String> attributes;      // name of entity-attribute, wildcards supported
 
         public AtlasEntityPermission() {
         }
 
         public AtlasEntityPermission(List<String> privileges, List<String> entityTypes, List<String> entityIds, List<String> classifications, List<String> attributes) {
+            this(privileges, entityTypes, entityIds, classifications, attributes, null, null);
+        }
+
+        public AtlasEntityPermission(List<String> privileges, List<String> entityTypes, List<String> entityIds, List<String> classifications, List<String> labels, List<String> namespaces, List<String> attributes) {
             this.privileges      = privileges;
             this.entityTypes     = entityTypes;
             this.entityIds       = entityIds;
             this.classifications = classifications;
+            this.labels          = labels;
+            this.namespaces      = namespaces;
             this.attributes      = attributes;
         }
 
@@ -254,6 +262,22 @@ public class AtlasSimpleAuthzPolicy implements Serializable {
             this.classifications = classifications;
         }
 
+        public List<String> getLabels() {
+            return labels;
+        }
+
+        public void setLabels(List<String> labels) {
+            this.namespaces = labels;
+        }
+
+        public List<String> getNamespaces() {
+            return namespaces;
+        }
+
+        public void setNamespaces(List<String> namespaces) {
+            this.namespaces = namespaces;
+        }
+
         public List<String> getAttributes() {
             return attributes;
         }
diff --git a/authorization/src/main/resources/atlas-simple-authz-policy.json b/authorization/src/main/resources/atlas-simple-authz-policy.json
index 0a5f0fa..bd08a6f 100644
--- a/authorization/src/main/resources/atlas-simple-authz-policy.json
+++ b/authorization/src/main/resources/atlas-simple-authz-policy.json
@@ -18,7 +18,9 @@
           "privileges":      [ ".*" ],
           "entityTypes":     [ ".*" ],
           "entityIds":       [ ".*" ],
-          "classifications": [ ".*" ]
+          "classifications": [ ".*" ],
+          "labels":          [ ".*" ],
+          "namespaces":      [ ".*" ]
         }
       ],
       "relationshipPermissions": [
@@ -41,7 +43,9 @@
           "privileges":      [ "entity-read", "entity-read-classification" ],
           "entityTypes":     [ ".*" ],
           "entityIds":       [ ".*" ],
-          "classifications": [ ".*" ]
+          "classifications": [ ".*" ],
+          "labels":          [ ".*" ],
+          "namespaces":      [ ".*" ]
         }
       ]
     },
@@ -49,10 +53,12 @@
     "DATA_STEWARD": {
       "entityPermissions": [
         {
-          "privileges":      [ "entity-read", "entity-create", "entity-update", "entity-read-classification", "entity-add-classification", "entity-update-classification", "entity-remove-classification" ],
+          "privileges":      [ "entity-read", "entity-create", "entity-update", "entity-read-classification", "entity-add-classification", "entity-update-classification", "entity-remove-classification", "entity-add-label", "entity-remove-label", "entity-update-namespace" ],
           "entityTypes":     [ ".*" ],
           "entityIds":       [ ".*" ],
-          "classifications": [ ".*" ]
+          "classifications": [ ".*" ],
+          "labels":          [ ".*" ],
+          "namespaces":      [ ".*" ]
         }
       ],
       "relationshipPermissions": [
diff --git a/authorization/src/test/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizerTest.java b/authorization/src/test/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizerTest.java
index 16c8c8c..e585e93 100644
--- a/authorization/src/test/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizerTest.java
+++ b/authorization/src/test/java/org/apache/atlas/authorize/simple/AtlasSimpleAuthorizerTest.java
@@ -29,6 +29,10 @@ import java.util.Collections;
 public class AtlasSimpleAuthorizerTest {
     private static Logger LOG = LoggerFactory.getLogger(AtlasSimpleAuthorizerTest.class);
 
+    private static final String USER_DATA_SCIENTIST = "dataScientist1";
+    private static final String USER_DATA_STEWARD   = "dataSteward1";
+
+
     private String          originalConf;
     private AtlasAuthorizer authorizer;
 
@@ -104,4 +108,67 @@ public class AtlasSimpleAuthorizerTest {
             AssertJUnit.fail();
         }
     }
+
+    @Test(enabled = true)
+    public void testLabels() {
+        try {
+            AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(null, AtlasPrivilege.ENTITY_ADD_LABEL);
+
+            request.setUser(USER_DATA_SCIENTIST, Collections.emptySet());
+
+            boolean isAccessAllowed = authorizer.isAccessAllowed(request);
+
+            AssertJUnit.assertEquals("user " + USER_DATA_SCIENTIST + " shouldn't be allowed to add label", false, isAccessAllowed);
+
+
+            request.setUser(USER_DATA_STEWARD, Collections.emptySet());
+
+            isAccessAllowed = authorizer.isAccessAllowed(request);
+
+            AssertJUnit.assertEquals("user " + USER_DATA_STEWARD + " should be allowed to add label", true, isAccessAllowed);
+
+
+            request = new AtlasEntityAccessRequest(null, AtlasPrivilege.ENTITY_REMOVE_LABEL);
+
+            request.setUser(USER_DATA_SCIENTIST, Collections.emptySet());
+
+            isAccessAllowed = authorizer.isAccessAllowed(request);
+
+            AssertJUnit.assertEquals("user " + USER_DATA_SCIENTIST + " shouldn't be allowed to remove label", false, isAccessAllowed);
+
+
+            request.setUser(USER_DATA_STEWARD, Collections.emptySet());
+
+            isAccessAllowed = authorizer.isAccessAllowed(request);
+
+            AssertJUnit.assertEquals("user " + USER_DATA_STEWARD + " should be allowed to remove label", true, isAccessAllowed);
+        } catch (AtlasAuthorizationException e) {
+            LOG.error("Exception in AtlasSimpleAuthorizerTest", e);
+
+            AssertJUnit.fail();
+        }
+    }
+
+    @Test(enabled = true)
+    public void testNamespaces() {
+        try {
+            AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(null, AtlasPrivilege.ENTITY_UPDATE_NAMESPACE);
+
+            request.setUser(USER_DATA_SCIENTIST, Collections.emptySet());
+
+            boolean isAccessAllowed = authorizer.isAccessAllowed(request);
+
+            AssertJUnit.assertEquals("user " + USER_DATA_SCIENTIST + " shouldn't be allowed to update namespace", false, isAccessAllowed);
+
+            request.setUser(USER_DATA_STEWARD, Collections.emptySet());
+
+            isAccessAllowed = authorizer.isAccessAllowed(request);
+
+            AssertJUnit.assertEquals("user " + USER_DATA_STEWARD + " should be allowed to update namespace", true, isAccessAllowed);
+        } catch (AtlasAuthorizationException e) {
+            LOG.error("Exception in AtlasSimpleAuthorizerTest", e);
+
+            AssertJUnit.fail();
+        }
+    }
 }
diff --git a/authorization/src/test/resources/atlas-simple-authz-policy.json b/authorization/src/test/resources/atlas-simple-authz-policy.json
index 5743de1..379d42b 100644
--- a/authorization/src/test/resources/atlas-simple-authz-policy.json
+++ b/authorization/src/test/resources/atlas-simple-authz-policy.json
@@ -43,7 +43,9 @@
           "privileges":      [ "entity-read", "entity-read-classification" ],
           "entityTypes":     [ ".*" ],
           "entityIds":       [ ".*" ],
-          "classifications": [ ".*" ]
+          "classifications": [ ".*" ],
+          "labels":          [ ".*" ],
+          "namespaces":      [ ".*" ]
         }
       ]
     },
@@ -51,10 +53,12 @@
     "DATA_STEWARD": {
       "entityPermissions": [
         {
-          "privileges":      [ "entity-read", "entity-create", "entity-update", "entity-read-classification", "entity-add-classification", "entity-update-classification", "entity-remove-classification" ],
+          "privileges":      [ "entity-read", "entity-create", "entity-update", "entity-read-classification", "entity-add-classification", "entity-update-classification", "entity-remove-classification", "entity-add-label", "entity-remove-label", "entity-update-namespace" ],
           "entityTypes":     [ ".*" ],
           "entityIds":       [ ".*" ],
-          "classifications": [ ".*" ]
+          "classifications": [ ".*" ],
+          "labels":          [ ".*" ],
+          "namespaces":      [ ".*" ]
         }
       ]
     }
@@ -62,7 +66,9 @@
 
   "userRoles": {
     "admin": [ "ROLE_ADMIN" ],
-    "rangertagsync": [ "DATA_SCIENTIST" ]
+    "rangertagsync": [ "DATA_SCIENTIST" ],
+    "dataScientist1": [ "DATA_SCIENTIST"],
+    "dataSteward1": [ "DATA_STEWARD"]
   },
 
   "groupRoles": {
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
index c536f3b..30f5e5a 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
@@ -25,6 +25,7 @@ import org.apache.atlas.annotation.GraphTransaction;
 import org.apache.atlas.authorize.AtlasAdminAccessRequest;
 import org.apache.atlas.authorize.AtlasAuthorizationUtils;
 import org.apache.atlas.authorize.AtlasEntityAccessRequest;
+import org.apache.atlas.authorize.AtlasEntityAccessRequest.AtlasEntityAccessRequestBuilder;
 import org.apache.atlas.authorize.AtlasPrivilege;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.TypeCategory;
@@ -66,6 +67,7 @@ import javax.inject.Inject;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -834,14 +836,44 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
             throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty");
         }
 
+        if (MapUtils.isEmpty(entityNamespaces)) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "entityNamespaces is null/empty");
+        }
+
         AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid);
 
         if (entityVertex == null) {
             throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
         }
 
-        String          typeName   = getTypeName(entityVertex);
-        AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName);
+        String                           typeName       = getTypeName(entityVertex);
+        AtlasEntityType                  entityType     = typeRegistry.getEntityTypeByName(typeName);
+        AtlasEntityHeader                entityHeader   = entityRetriever.toAtlasEntityHeaderWithClassifications(entityVertex);
+        Map<String, Map<String, Object>> currNamespaces = entityRetriever.getEntityNamespaces(entityVertex);
+        Set<String>                      updatedNsNames = new HashSet<>();
+
+        for (String nsName : entityType.getNamespaceAttributes().keySet()) {
+            Map<String, Object> nsAttrs     = entityNamespaces.get(nsName);
+            Map<String, Object> currNsAttrs = currNamespaces != null ? currNamespaces.get(nsName) : null;
+
+            if (nsAttrs == null && !isOverwrite) {
+                continue;
+            } else if (MapUtils.isEmpty(nsAttrs) && MapUtils.isEmpty(currNsAttrs)) { // no change
+                continue;
+            } else if (Objects.equals(nsAttrs, currNsAttrs)) { // no change
+                continue;
+            }
+
+            updatedNsNames.add(nsName);
+        }
+
+        AtlasEntityAccessRequestBuilder  requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_UPDATE_NAMESPACE, entityHeader);
+
+        for (String nsName : updatedNsNames) {
+            requestBuilder.setNamespaceName(nsName);
+
+            AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "add/update namespace: guid=", guid, ", namespace=", nsName);
+        }
 
         validateNamespaceAttributes(entityVertex, entityType, entityNamespaces, isOverwrite);
 
@@ -867,14 +899,27 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
             throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty");
         }
 
+        if (MapUtils.isEmpty(entityNamespaces)) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "entityNamespaces is null/empty");
+        }
+
         AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid);
 
         if (entityVertex == null) {
             throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
         }
 
-        String          typeName   = getTypeName(entityVertex);
-        AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName);
+        String                          typeName       = getTypeName(entityVertex);
+        AtlasEntityType                 entityType     = typeRegistry.getEntityTypeByName(typeName);
+        AtlasEntityHeader               entityHeader   = entityRetriever.toAtlasEntityHeaderWithClassifications(entityVertex);
+
+        AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_UPDATE_NAMESPACE, entityHeader);
+
+        for (String nsName : entityNamespaces.keySet()) {
+            requestBuilder.setNamespaceName(nsName);
+
+            AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "remove namespace: guid=", guid, ", namespace=", nsName);
+        }
 
         entityGraphMapper.removeNamespaceAttributes(entityVertex, entityType, entityNamespaces);
 
@@ -902,6 +947,39 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
 
         validateLabels(labels);
 
+        AtlasEntityHeader entityHeader  = entityRetriever.toAtlasEntityHeaderWithClassifications(entityVertex);
+        Set<String>       addedLabels   = Collections.emptySet();
+        Set<String>       removedLabels = Collections.emptySet();
+
+        if (CollectionUtils.isEmpty(entityHeader.getLabels())) {
+            addedLabels = labels;
+        } else if (CollectionUtils.isEmpty(labels)) {
+            removedLabels = entityHeader.getLabels();
+        } else {
+            addedLabels   = new HashSet<String>(CollectionUtils.subtract(labels, entityHeader.getLabels()));
+            removedLabels = new HashSet<String>(CollectionUtils.subtract(entityHeader.getLabels(), labels));
+        }
+
+        if (addedLabels != null) {
+            AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_ADD_LABEL, entityHeader);
+
+            for (String label : addedLabels) {
+                requestBuilder.setLabel(label);
+
+                AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "add label: guid=", guid, ", label=", label);
+            }
+        }
+
+        if (removedLabels != null) {
+            AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_REMOVE_LABEL, entityHeader);
+
+            for (String label : removedLabels) {
+                requestBuilder.setLabel(label);
+
+                AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "remove label: guid=", guid, ", label=", label);
+            }
+        }
+
         entityGraphMapper.setLabels(entityVertex, labels);
 
         if (LOG.isDebugEnabled()) {
@@ -920,12 +998,25 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
             throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty");
         }
 
+        if (CollectionUtils.isEmpty(labels)) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "labels is null/empty");
+        }
+
         AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid);
 
         if (entityVertex == null) {
             throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
         }
 
+        AtlasEntityHeader               entityHeader   = entityRetriever.toAtlasEntityHeaderWithClassifications(entityVertex);
+        AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_REMOVE_LABEL, entityHeader);
+
+        for (String label : labels) {
+            requestBuilder.setLabel(label);
+
+            AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "remove label: guid=", guid, ", label=", label);
+        }
+
         validateLabels(labels);
 
         entityGraphMapper.removeLabels(entityVertex, labels);
@@ -946,12 +1037,25 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
             throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid is null/empty");
         }
 
+        if (CollectionUtils.isEmpty(labels)) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "labels is null/empty");
+        }
+
         AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid);
 
         if (entityVertex == null) {
             throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
         }
 
+        AtlasEntityHeader               entityHeader   = entityRetriever.toAtlasEntityHeaderWithClassifications(entityVertex);
+        AtlasEntityAccessRequestBuilder requestBuilder = new AtlasEntityAccessRequestBuilder(typeRegistry, AtlasPrivilege.ENTITY_ADD_LABEL, entityHeader);
+
+        for (String label : labels) {
+            requestBuilder.setLabel(label);
+
+            AtlasAuthorizationUtils.verifyAccess(requestBuilder.build(), "add/update label: guid=", guid, ", label=", label);
+        }
+
         validateLabels(labels);
 
         entityGraphMapper.addLabels(entityVertex, labels);
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
index 7461931..2f3aad0 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
@@ -353,7 +353,7 @@ public class EntityGraphMapper {
             removedLabels = null;
         } else if (CollectionUtils.isEmpty(labels)) {
             addedLabels   = null;
-            removedLabels = labels;
+            removedLabels = currentLabels;
         } else {
             addedLabels   = new HashSet<String>(CollectionUtils.subtract(labels, currentLabels));
             removedLabels = new HashSet<String>(CollectionUtils.subtract(currentLabels, labels));
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
index 3c22d9a..7533ebc 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
@@ -221,6 +221,41 @@ public class EntityGraphRetriever {
         return ret;
     }
 
+    public Map<String, Map<String, Object>> getEntityNamespaces(AtlasVertex entityVertex) throws AtlasBaseException {
+        Map<String, Map<String, Object>>                  ret                  = null;
+        String                                            entityTypeName       = getTypeName(entityVertex);
+        AtlasEntityType                                   entityType           = typeRegistry.getEntityTypeByName(entityTypeName);
+        Map<String, Map<String, AtlasNamespaceAttribute>> entityTypeNamespaces = entityType != null ? entityType.getNamespaceAttributes() : null;
+
+        if (MapUtils.isNotEmpty(entityTypeNamespaces)) {
+            for (Map.Entry<String, Map<String, AtlasNamespaceAttribute>> entry : entityTypeNamespaces.entrySet()) {
+                String                               nsName        = entry.getKey();
+                Map<String, AtlasNamespaceAttribute> nsAttributes  = entry.getValue();
+                Map<String, Object>                  entityNsAttrs = null;
+
+                for (AtlasNamespaceAttribute nsAttribute : nsAttributes.values()) {
+                    Object nsAttrValue = mapVertexToAttribute(entityVertex, nsAttribute, null, false, false);
+
+                    if (nsAttrValue != null) {
+                        if (ret == null) {
+                            ret = new HashMap<>();
+                        }
+
+                        if (entityNsAttrs == null) {
+                            entityNsAttrs = new HashMap<>();
+
+                            ret.put(nsName, entityNsAttrs);
+                        }
+
+                        entityNsAttrs.put(nsAttribute.getName(), nsAttrValue);
+                    }
+                }
+            }
+        }
+
+        return ret;
+    }
+
     public Object getEntityAttribute(AtlasVertex entityVertex, AtlasAttribute attribute) {
         Object ret = null;
 
@@ -770,23 +805,7 @@ public class EntityGraphRetriever {
     }
 
     private void mapNamespaceAttributes(AtlasVertex entityVertex, AtlasEntity entity) throws AtlasBaseException {
-        AtlasEntityType                                   entityType           = typeRegistry.getEntityTypeByName(entity.getTypeName());
-        Map<String, Map<String, AtlasNamespaceAttribute>> entityTypeNamespaces = entityType != null ? entityType.getNamespaceAttributes() : null;
-
-        if (MapUtils.isNotEmpty(entityTypeNamespaces)) {
-            for (Map.Entry<String, Map<String, AtlasNamespaceAttribute>> entry : entityTypeNamespaces.entrySet()) {
-                String                               nsName       = entry.getKey();
-                Map<String, AtlasNamespaceAttribute> nsAttributes = entry.getValue();
-
-                for (AtlasNamespaceAttribute nsAttribute : nsAttributes.values()) {
-                    Object nsAttrValue = mapVertexToAttribute(entityVertex, nsAttribute, null, false, false);
-
-                    if (nsAttrValue != null) {
-                        entity.setNamespaceAttribute(nsName, nsAttribute.getName(), nsAttrValue);
-                    }
-                }
-            }
-        }
+        entity.setNamespaceAttributes(getEntityNamespaces(entityVertex));
     }
 
     public List<AtlasClassification> getAllClassifications(AtlasVertex entityVertex) throws AtlasBaseException {