You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2023/03/30 00:54:29 UTC

[ranger] 01/02: RANGER-4035: added catagory to access-types; added marker access-types.patch

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

madhan pushed a commit to branch RANGER-3923
in repository https://gitbox.apache.org/repos/asf/ranger.git

commit e11431f8cc9fb643754f95e467f10331e32bcf5e
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Thu Mar 9 02:15:07 2023 -0800

    RANGER-4035: added catagory to access-types; added marker access-types.patch
---
 .../ranger/plugin/model/RangerServiceDef.java      |  63 ++-
 .../model/validation/RangerPolicyValidator.java    |  24 ++
 .../model/validation/RangerServiceDefHelper.java   |  48 +++
 .../plugin/model/validation/RangerValidator.java   |   8 +
 .../RangerAuditPolicyEvaluator.java                |   6 +-
 .../RangerDefaultPolicyEvaluator.java              |  33 +-
 .../apache/ranger/plugin/util/ServiceDefUtil.java  | 174 ++++++--
 .../model/validation/TestRangerValidator.java      |   2 +
 .../plugin/policyengine/TestPolicyEngine.java      |   7 +
 .../ranger/plugin/util/ServiceDefUtilTest.java     | 147 +++++++
 .../test_policyengine_marker_access_types.json     | 435 +++++++++++++++++++
 .../test/resources/test_servicedef-normalize.json  | 478 +++++++++++++++++++++
 .../apache_ranger/model/ranger_service_def.py      |  50 +--
 .../org/apache/ranger/biz/PolicyRefUpdater.java    |   5 +
 .../java/org/apache/ranger/biz/ServiceDBStore.java |   3 +
 .../service/RangerServiceDefServiceBase.java       |   2 +
 16 files changed, 1388 insertions(+), 97 deletions(-)

diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
index e70a16592..375c6f335 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
@@ -65,6 +65,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 	private List<RangerEnumDef>            enums;
 	private RangerDataMaskDef              dataMaskDef;
 	private RangerRowFilterDef             rowFilterDef;
+	private List<RangerAccessTypeDef>      markerAccessTypes; // read-only
 
 	public RangerServiceDef() {
 		this(null, null, null, null, null, null, null, null, null, null, null, null, null);
@@ -104,6 +105,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		setEnums(enums);
 		setDataMaskDef(dataMaskDef);
 		setRowFilterDef(rowFilterDef);
+		setMarkerAccessTypes(null);
 	}
 
 	public RangerServiceDef(String name, String displayName, String implClass, String label, String description,
@@ -137,6 +139,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		setEnums(other.getEnums());
 		setDataMaskDef(other.getDataMaskDef());
 		setRowFilterDef(other.getRowFilterDef());
+		setMarkerAccessTypes(other.getMarkerAccessTypes());
 	}
 
 	/**
@@ -421,6 +424,26 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		this.rowFilterDef = rowFilterDef == null ? new RangerRowFilterDef() : rowFilterDef;
 	}
 
+	public List<RangerAccessTypeDef> getMarkerAccessTypes() {
+		return markerAccessTypes;
+	}
+
+	public void setMarkerAccessTypes(List<RangerAccessTypeDef> markerAccessTypes) {
+		if (this.markerAccessTypes == null) {
+			this.markerAccessTypes = new ArrayList<>();
+		}
+
+		if (this.markerAccessTypes == markerAccessTypes) {
+			return;
+		}
+
+		this.markerAccessTypes.clear();
+
+		if(markerAccessTypes != null) {
+			this.markerAccessTypes.addAll(markerAccessTypes);
+		}
+	}
+
 	public String getDisplayName() {
 		return displayName;
 	}
@@ -481,6 +504,12 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		if (rowFilterDef != null) {
 			rowFilterDef.dedupStrings(strTbl);
 		}
+
+		if (markerAccessTypes != null) {
+			for (RangerAccessTypeDef accessType : markerAccessTypes) {
+				accessType.dedupStrings(strTbl);
+			}
+		}
 	}
 
 	@Override
@@ -585,6 +614,16 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		}
 		sb.append("} ");
 
+		sb.append("markerAccessTypes={");
+		if(markerAccessTypes != null) {
+			for(RangerAccessTypeDef accessType : markerAccessTypes) {
+				if(accessType != null) {
+					accessType.toString(sb);
+				}
+			}
+		}
+		sb.append("} ");
+
 		sb.append("}");
 
 		return sb;
@@ -1925,22 +1964,34 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 	public static class RangerAccessTypeDef implements java.io.Serializable {
 		private static final long serialVersionUID = 1L;
 
+		public enum AccessTypeCategory { CREATE, READ, UPDATE, DELETE, MANAGE }
+
 		private Long               itemId;
 		private String             name;
 		private String             label;
 		private String             rbKeyLabel;
 		private Collection<String> impliedGrants;
+		private AccessTypeCategory category;
 
 		public RangerAccessTypeDef() {
-			this(null, null, null, null, null);
+			this(null, null, null, null, null, null);
+		}
+
+		public RangerAccessTypeDef(String name) {
+			this(null, name, name, null, null, null);
 		}
 
 		public RangerAccessTypeDef(Long itemId, String name, String label, String rbKeyLabel, Collection<String> impliedGrants) {
+			this(itemId, name, label, rbKeyLabel, impliedGrants, null);
+		}
+
+		public RangerAccessTypeDef(Long itemId, String name, String label, String rbKeyLabel, Collection<String> impliedGrants, AccessTypeCategory category) {
 			setItemId(itemId);
 			setName(name);
 			setLabel(label);
 			setRbKeyLabel(rbKeyLabel);
 			setImpliedGrants(impliedGrants);
+			setCategory(category);
 		}
 
 		public RangerAccessTypeDef(RangerAccessTypeDef other) {
@@ -1949,6 +2000,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 			setLabel(other.getLabel());
 			setRbKeyLabel(other.getRbKeyLabel());
 			setImpliedGrants(other.getImpliedGrants());
+			setCategory((other.getCategory()));
 		}
 
 		/**
@@ -2033,6 +2085,14 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 			}
 		}
 
+		public AccessTypeCategory getCategory() {
+			return category;
+		}
+
+		public void setCategory(AccessTypeCategory category) {
+			this.category = category;
+		}
+
 		public void dedupStrings(Map<String, String> strTbl) {
 			name          = StringUtil.dedupString(name, strTbl);
 			label         = StringUtil.dedupString(label, strTbl);
@@ -2065,6 +2125,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 				}
 			}
 			sb.append("} ");
+			sb.append("category={").append(category).append("} ");
 
 			sb.append("}");
 
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
index e1b5fe8f1..30d8ed0fe 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
@@ -415,6 +415,18 @@ public class RangerPolicyValidator extends RangerValidator {
 					for(RangerAccessTypeDef rangerAccessTypeDef:serviceDef.getRowFilterDef().getAccessTypes()){
 						rowFilterAccessTypeDefNames.add(rangerAccessTypeDef.getName().toLowerCase());
 					}
+
+					if (serviceDef.getMarkerAccessTypes() != null) {
+						for (RangerAccessTypeDef accessTypeDef : serviceDef.getMarkerAccessTypes()) {
+							if (accessTypeDef == null || accessTypeDef.getImpliedGrants() == null) {
+								continue;
+							}
+
+							if (CollectionUtils.containsAny(accessTypeDef.getImpliedGrants(), rowFilterAccessTypeDefNames)) {
+								rowFilterAccessTypeDefNames.add(accessTypeDef.getName());
+							}
+						}
+					}
 				}
 			}
 
@@ -445,6 +457,18 @@ public class RangerPolicyValidator extends RangerValidator {
 					for(RangerAccessTypeDef rangerAccessTypeDef:serviceDef.getDataMaskDef().getAccessTypes()){
 						dataMaskAccessTypeDefNames.add(rangerAccessTypeDef.getName().toLowerCase());
 					}
+
+					if (serviceDef.getMarkerAccessTypes() != null) {
+						for (RangerAccessTypeDef accessTypeDef : serviceDef.getMarkerAccessTypes()) {
+							if (accessTypeDef == null || accessTypeDef.getImpliedGrants() == null) {
+								continue;
+							}
+
+							if (CollectionUtils.containsAny(accessTypeDef.getImpliedGrants(), dataMaskAccessTypeDefNames)) {
+								dataMaskAccessTypeDefNames.add(accessTypeDef.getName());
+							}
+						}
+					}
 				}
 			}
 
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
index 4e287f9a4..025ea2ea4 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
@@ -36,6 +36,7 @@ import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -311,6 +312,10 @@ public class RangerServiceDefHelper {
 		return _delegate.getWildcardEnabledResourceDef(resourceName, policyType);
 	}
 
+	public Map<String, Collection<String>> getImpliedAccessGrants() {
+		return _delegate.getImpliedAccessGrants();
+	}
+
 	/**
 	 * Not designed for public access.  Package level only for testability.
 	 */
@@ -323,6 +328,7 @@ public class RangerServiceDefHelper {
 		final boolean _checkForCycles;
 		final boolean _valid;
 		final List<String> _orderedResourceNames;
+		final Map<String, Collection<String>> _impliedGrants;
 		final static Set<List<RangerResourceDef>> EMPTY_RESOURCE_HIERARCHY = Collections.unmodifiableSet(new HashSet<List<RangerResourceDef>>());
 
 
@@ -352,6 +358,8 @@ public class RangerServiceDefHelper {
 				}
 			}
 
+			_impliedGrants = computeImpliedGrants();
+
 			if (isValid) {
 				_orderedResourceNames = buildSortedResourceNames();
 			} else {
@@ -611,6 +619,46 @@ public class RangerServiceDefHelper {
 			return this._orderedResourceNames;
 		}
 
+		Map<String, Collection<String>> getImpliedAccessGrants() { return _impliedGrants; }
+
+		private Map<String, Collection<String>> computeImpliedGrants() {
+			Map<String, Collection<String>> ret = new HashMap<>();
+
+			if (_serviceDef != null && CollectionUtils.isNotEmpty(_serviceDef.getAccessTypes())) {
+				for(RangerAccessTypeDef accessTypeDef : _serviceDef.getAccessTypes()) {
+					if(CollectionUtils.isNotEmpty(accessTypeDef.getImpliedGrants())) {
+						Collection<String> impliedAccessGrants = ret.get(accessTypeDef.getName());
+
+						if(impliedAccessGrants == null) {
+							impliedAccessGrants = new HashSet<>();
+
+							ret.put(accessTypeDef.getName(), impliedAccessGrants);
+						}
+
+						impliedAccessGrants.addAll(accessTypeDef.getImpliedGrants());
+					}
+				}
+
+				if (_serviceDef.getMarkerAccessTypes() != null) {
+					for (RangerAccessTypeDef accessTypeDef : _serviceDef.getMarkerAccessTypes()) {
+						if(CollectionUtils.isNotEmpty(accessTypeDef.getImpliedGrants())) {
+							Collection<String> impliedAccessGrants = ret.get(accessTypeDef.getName());
+
+							if(impliedAccessGrants == null) {
+								impliedAccessGrants = new HashSet<>();
+
+								ret.put(accessTypeDef.getName(), impliedAccessGrants);
+							}
+
+							impliedAccessGrants.addAll(accessTypeDef.getImpliedGrants());
+						}
+					}
+				}
+			}
+
+			return ret;
+		}
+
 		private static class ResourceNameLevel implements Comparable<ResourceNameLevel> {
 			private String resourceName;
 			private int    level;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java
index d47be1404..73f822836 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java
@@ -434,6 +434,14 @@ public abstract class RangerValidator {
 					}
 				}
 			}
+
+			if (serviceDef.getMarkerAccessTypes() != null) {
+				for (RangerAccessTypeDef accessTypeDef : serviceDef.getMarkerAccessTypes()) {
+					if (accessTypeDef != null) {
+						accessTypes.add(accessTypeDef.getName());
+					}
+				}
+			}
 		}
 
 		if(LOG.isDebugEnabled()) {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
index 1c46f184c..44ba838b4 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
@@ -100,10 +100,10 @@ public class RangerAuditPolicyEvaluator extends RangerDefaultPolicyEvaluator {
     }
 
     @Override
-    protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
-        super.preprocessPolicy(policy, serviceDef);
+    protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options) {
+        super.preprocessPolicy(policy, serviceDef, options);
 
-        Map<String, Collection<String>> impliedAccessGrants = getImpliedAccessGrants(serviceDef);
+        Map<String, Collection<String>> impliedAccessGrants = options.getServiceDefHelper().getImpliedAccessGrants();
 
         if (impliedAccessGrants == null || impliedAccessGrants.isEmpty()) {
             return;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
index 2f9c1b019..855d52942 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -113,7 +112,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 
 		policy = getPolicy();
 
-		preprocessPolicy(policy, serviceDef);
+		preprocessPolicy(policy, serviceDef, options);
 
 		if(policy != null) {
 			validityScheduleEvaluators = createValidityScheduleEvaluators(policy);
@@ -1145,12 +1144,12 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		return sb;
 	}
 
-	protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
+	protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options) {
 		if(policy == null || (!hasAllow() && !hasDeny()) || serviceDef == null) {
 			return;
 		}
 
-		Map<String, Collection<String>> impliedAccessGrants = getImpliedAccessGrants(serviceDef);
+		Map<String, Collection<String>> impliedAccessGrants = options.getServiceDefHelper().getImpliedAccessGrants();
 
 		if(impliedAccessGrants == null || impliedAccessGrants.isEmpty()) {
 			return;
@@ -1199,32 +1198,6 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		}
 	}
 
-	protected Map<String, Collection<String>> getImpliedAccessGrants(RangerServiceDef serviceDef) {
-		Map<String, Collection<String>> ret = null;
-
-		if(serviceDef != null && !CollectionUtils.isEmpty(serviceDef.getAccessTypes())) {
-			for(RangerAccessTypeDef accessTypeDef : serviceDef.getAccessTypes()) {
-				if(!CollectionUtils.isEmpty(accessTypeDef.getImpliedGrants())) {
-					if(ret == null) {
-						ret = new HashMap<>();
-					}
-
-					Collection<String> impliedAccessGrants = ret.get(accessTypeDef.getName());
-
-					if(impliedAccessGrants == null) {
-						impliedAccessGrants = new HashSet<>();
-
-						ret.put(accessTypeDef.getName(), impliedAccessGrants);
-					}
-
-					impliedAccessGrants.addAll(accessTypeDef.getImpliedGrants());
-				}
-			}
-		}
-
-		return ret;
-	}
-
 	private RangerPolicyItemAccess getAccess(RangerPolicyItem policyItem, String accessType) {
 		RangerPolicyItemAccess ret = null;
 
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
index 4808dfd83..db63c936a 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
@@ -48,15 +48,39 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
 public class ServiceDefUtil {
     private static final Logger LOG = LoggerFactory.getLogger(ServiceDefUtil.class);
 
     private static final String USER_STORE_ENRICHER = RangerUserStoreEnricher.class.getCanonicalName();
 
+
+    public static final String ACCESS_TYPE_MARKER_CREATE = "_CREATE";
+    public static final String ACCESS_TYPE_MARKER_READ   = "_READ";
+    public static final String ACCESS_TYPE_MARKER_UPDATE = "_UPDATE";
+    public static final String ACCESS_TYPE_MARKER_DELETE = "_DELETE";
+    public static final String ACCESS_TYPE_MARKER_MANAGE = "_MANAGE";
+    public static final String ACCESS_TYPE_MARKER_ALL    = "_ALL";
+    public static final Set<String> ACCESS_TYPE_MARKERS;
+
+    static {
+        Set<String> typeMarkers = new LinkedHashSet<>();
+
+        typeMarkers.add(ACCESS_TYPE_MARKER_CREATE);
+        typeMarkers.add(ACCESS_TYPE_MARKER_READ);
+        typeMarkers.add(ACCESS_TYPE_MARKER_UPDATE);
+        typeMarkers.add(ACCESS_TYPE_MARKER_DELETE);
+        typeMarkers.add(ACCESS_TYPE_MARKER_MANAGE);
+        typeMarkers.add(ACCESS_TYPE_MARKER_ALL);
+
+        ACCESS_TYPE_MARKERS = Collections.unmodifiableSet(typeMarkers);
+    }
+
     public static boolean getOption_enableDenyAndExceptionsInPolicies(RangerServiceDef serviceDef, RangerPluginContext pluginContext) {
         boolean ret = false;
 
@@ -204,65 +228,67 @@ public class ServiceDefUtil {
     }
 
     public static RangerServiceDef normalizeAccessTypeDefs(RangerServiceDef serviceDef, final String componentType) {
-
         if (serviceDef != null && StringUtils.isNotBlank(componentType)) {
+            normalizeAccessTypeDefs(serviceDef.getAccessTypes(), componentType);
+            normalizeAccessTypeDefs(serviceDef.getMarkerAccessTypes(), componentType);
 
-            List<RangerServiceDef.RangerAccessTypeDef> accessTypeDefs = serviceDef.getAccessTypes();
-
-            if (CollectionUtils.isNotEmpty(accessTypeDefs)) {
-
-                String prefix = componentType + AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR;
-
-                List<RangerServiceDef.RangerAccessTypeDef> unneededAccessTypeDefs = null;
-
-                for (RangerServiceDef.RangerAccessTypeDef accessTypeDef : accessTypeDefs) {
-
-                    String accessType = accessTypeDef.getName();
+            if (serviceDef.getDataMaskDef() != null) {
+                normalizeAccessTypeDefs(serviceDef.getDataMaskDef().getAccessTypes(), componentType);
+            }
 
-                    if (StringUtils.startsWith(accessType, prefix)) {
+            if (serviceDef.getRowFilterDef() != null) {
+                normalizeAccessTypeDefs(serviceDef.getRowFilterDef().getAccessTypes(), componentType);
+            }
+        }
 
-                        String newAccessType = StringUtils.removeStart(accessType, prefix);
+        return serviceDef;
+    }
 
-                        accessTypeDef.setName(newAccessType);
+    private static void normalizeAccessTypeDefs(List<RangerAccessTypeDef> accessTypeDefs, String componentType) {
+        if (CollectionUtils.isNotEmpty(accessTypeDefs)) {
+            String                    prefix                 = componentType + AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR;
+            List<RangerAccessTypeDef> unneededAccessTypeDefs = null;
 
-                        Collection<String> impliedGrants = accessTypeDef.getImpliedGrants();
+            for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) {
+                String accessType = accessTypeDef.getName();
 
-                        if (CollectionUtils.isNotEmpty(impliedGrants)) {
+                if (StringUtils.startsWith(accessType, prefix)) {
+                    String newAccessType = StringUtils.removeStart(accessType, prefix);
 
-                            Collection<String> newImpliedGrants = null;
+                    accessTypeDef.setName(newAccessType);
+                } else if (StringUtils.contains(accessType, AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR)) {
+                    if (unneededAccessTypeDefs == null) {
+                        unneededAccessTypeDefs = new ArrayList<>();
+                    }
 
-                            for (String impliedGrant : impliedGrants) {
+                    unneededAccessTypeDefs.add(accessTypeDef);
 
-                                if (StringUtils.startsWith(impliedGrant, prefix)) {
+                    continue;
+                }
 
-                                    String newImpliedGrant = StringUtils.removeStart(impliedGrant, prefix);
+                Collection<String> impliedGrants = accessTypeDef.getImpliedGrants();
 
-                                    if (newImpliedGrants == null) {
-                                        newImpliedGrants = new ArrayList<>();
-                                    }
+                if (CollectionUtils.isNotEmpty(impliedGrants)) {
+                    Set<String> newImpliedGrants = new HashSet<>();
 
-                                    newImpliedGrants.add(newImpliedGrant);
-                                }
-                            }
-                            accessTypeDef.setImpliedGrants(newImpliedGrants);
+                    for (String impliedGrant : impliedGrants) {
+                        if (StringUtils.startsWith(impliedGrant, prefix)) {
+                            String newImpliedGrant = StringUtils.removeStart(impliedGrant, prefix);
 
+                            newImpliedGrants.add(newImpliedGrant);
+                        } else if (!StringUtils.contains(impliedGrant, AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR)) {
+                            newImpliedGrants.add(impliedGrant);
                         }
-                    } else if (StringUtils.contains(accessType, AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR)) {
-                        if(unneededAccessTypeDefs == null) {
-                            unneededAccessTypeDefs = new ArrayList<>();
-                        }
-
-                        unneededAccessTypeDefs.add(accessTypeDef);
                     }
-                }
 
-                if(unneededAccessTypeDefs != null) {
-                    accessTypeDefs.removeAll(unneededAccessTypeDefs);
+                    accessTypeDef.setImpliedGrants(newImpliedGrants);
                 }
             }
-        }
 
-        return serviceDef;
+            if (unneededAccessTypeDefs != null) {
+                accessTypeDefs.removeAll(unneededAccessTypeDefs);
+            }
+        }
     }
 
     private static void normalizeDataMaskDef(RangerServiceDef serviceDef) {
@@ -585,6 +611,76 @@ public class ServiceDefUtil {
         return ret;
     }
 
+    public static List<RangerAccessTypeDef> getMarkerAccessTypes(List<RangerAccessTypeDef> accessTypeDefs) {
+        List<RangerAccessTypeDef> ret              = new ArrayList<>();
+        Map<String, Set<String>>  markerTypeGrants = getMarkerAccessTypeGrants(accessTypeDefs);
+        long                      maxItemId        = getMaxItemId(accessTypeDefs);
+
+        for (String accessTypeMarker : ACCESS_TYPE_MARKERS) {
+            RangerAccessTypeDef accessTypeDef = new RangerAccessTypeDef(++maxItemId, accessTypeMarker, accessTypeMarker, null, markerTypeGrants.get(accessTypeMarker));
+
+            ret.add(accessTypeDef);
+        }
+
+        return ret;
+    }
+
+    private static Map<String, Set<String>> getMarkerAccessTypeGrants(List<RangerAccessTypeDef> accessTypeDefs) {
+        Map<String, Set<String>> ret = new HashMap<>();
+
+        for (String accessTypeMarker : ACCESS_TYPE_MARKERS) {
+            ret.put(accessTypeMarker, new HashSet<>());
+        }
+
+        if (CollectionUtils.isNotEmpty(accessTypeDefs)) {
+            for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) {
+                if (accessTypeDef == null || StringUtils.isBlank(accessTypeDef.getName()) || ACCESS_TYPE_MARKERS.contains(accessTypeDef.getName())) {
+                    continue;
+                }
+
+                addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_ALL));
+
+                if (accessTypeDef.getCategory() == null) {
+                    continue;
+                } else if (accessTypeDef.getCategory() == RangerAccessTypeDef.AccessTypeCategory.CREATE) {
+                    addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_CREATE));
+                } else if (accessTypeDef.getCategory() == RangerAccessTypeDef.AccessTypeCategory.READ) {
+                    addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_READ));
+                } else if (accessTypeDef.getCategory() == RangerAccessTypeDef.AccessTypeCategory.UPDATE) {
+                    addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_UPDATE));
+                } else if (accessTypeDef.getCategory() == RangerAccessTypeDef.AccessTypeCategory.DELETE) {
+                    addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_DELETE));
+                } else if (accessTypeDef.getCategory() == RangerAccessTypeDef.AccessTypeCategory.MANAGE) {
+                    addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_MANAGE));
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    private static void addToMarkerGrants(RangerAccessTypeDef accessTypeDef, Set<String> markerGrants) {
+        markerGrants.add(accessTypeDef.getName());
+
+        if (CollectionUtils.isNotEmpty(accessTypeDef.getImpliedGrants())) {
+            markerGrants.addAll(accessTypeDef.getImpliedGrants());
+        }
+    }
+
+    private static long getMaxItemId(List<RangerAccessTypeDef> accessTypeDefs) {
+        long ret = -1;
+
+        if (CollectionUtils.isNotEmpty(accessTypeDefs)) {
+            for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) {
+                if (accessTypeDef.getItemId() != null && ret < accessTypeDef.getItemId()) {
+                    ret = accessTypeDef.getItemId();
+                }
+            }
+        }
+
+        return ret;
+    }
+
     private static boolean anyPolicyHasUserGroupAttributeExpression(List<RangerPolicy> policies) {
         boolean ret = false;
 
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerValidator.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerValidator.java
index 6114225ca..3d5248ad6 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerValidator.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerValidator.java
@@ -41,6 +41,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef;
 import org.apache.ranger.plugin.model.validation.RangerValidator.Action;
 import org.apache.ranger.plugin.store.ServiceStore;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -258,6 +259,7 @@ public class TestRangerValidator {
 		String[] names = new String[] { null, "", "a", "  ", "b ", "		", " C", "	D	" };
 		accessTypeDefs.addAll(_utils.createAccessTypeDefs(names));
 		accessTypes = _validator.getAccessTypes(serviceDef);
+		accessTypes.removeAll(ServiceDefUtil.ACCESS_TYPE_MARKERS);
 		Assert.assertEquals(4, accessTypes.size());
 		Assert.assertTrue(accessTypes.contains("a"));
 		Assert.assertTrue(accessTypes.contains("b "));
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
index b2a5151e5..776b58480 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
@@ -482,6 +482,13 @@ public class TestPolicyEngine {
 		runTestsFromResourceFiles(resourceFiles);
 	}
 
+	@Test
+	public void testPolicyEngin_markerAccessTypes() {
+		String[] resourceFiles = {"/policyengine/test_policyengine_marker_access_types.json"};
+
+		runTestsFromResourceFiles(resourceFiles);
+	}
+
 	private void runTestsFromResourceFiles(String[] resourceNames) {
 		for(String resourceName : resourceNames) {
 			InputStream inStream = this.getClass().getResourceAsStream(resourceName);
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/ServiceDefUtilTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/ServiceDefUtilTest.java
index 3cd42f44f..147cdaf2b 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/util/ServiceDefUtilTest.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/ServiceDefUtilTest.java
@@ -17,6 +17,9 @@
 
 package org.apache.ranger.plugin.util;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.commons.lang.StringUtils;
 import org.apache.ranger.plugin.contextenricher.RangerAdminUserStoreRetriever;
 import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
@@ -28,17 +31,28 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.model.RangerPolicyDelta;
 import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef.AccessTypeCategory;
 import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
 import org.apache.ranger.plugin.util.ServicePolicies.SecurityZoneInfo;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
+import static org.apache.ranger.plugin.util.ServiceDefUtil.*;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
 public class ServiceDefUtilTest {
@@ -68,6 +82,13 @@ public class ServiceDefUtilTest {
 			REF_USER_ATTR_NAMES_CSV_F, REF_USER_ATTR_NAMES_Q_CSV_F
 	};
 
+	static Gson gsonBuilder;
+
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSSZ").setPrettyPrinting().create();
+	}
+
 	@Test
 	public void testNoUserGroupAttrRef() {
 		ServicePolicies svcPolicies = getServicePolicies();
@@ -252,6 +273,132 @@ public class ServiceDefUtilTest {
 		}
 	}
 
+	@Test
+	public void testNormalizeAccessTypeDefs() throws Exception {
+		try (InputStream inStream = this.getClass().getResourceAsStream("/test_servicedef-normalize.json")) {
+			InputStreamReader reader   = new InputStreamReader(inStream);
+			ServicePolicies   policies = gsonBuilder.fromJson(reader, ServicePolicies.class);
+
+			RangerAccessTypeDef serviceMarkerAll = getAccessType(policies.getServiceDef().getMarkerAccessTypes(), ACCESS_TYPE_MARKER_ALL);
+			RangerAccessTypeDef tagMarkerAll     = getAccessType(policies.getTagPolicies().getServiceDef().getMarkerAccessTypes(), ACCESS_TYPE_MARKER_ALL);
+
+			assertNotEquals("accessType count", policies.getServiceDef().getAccessTypes().size(), policies.getTagPolicies().getServiceDef().getAccessTypes().size());
+			assertNotEquals("impliedGrants: _ALL", new HashSet<>(serviceMarkerAll.getImpliedGrants()), new HashSet<>(tagMarkerAll.getImpliedGrants()));
+			assertNotEquals("dataMask.accessType count", policies.getServiceDef().getDataMaskDef().getAccessTypes().size(), policies.getTagPolicies().getServiceDef().getDataMaskDef().getAccessTypes().size());
+			assertNotEquals("rowFilter.accessType count", policies.getServiceDef().getRowFilterDef().getAccessTypes().size(), policies.getTagPolicies().getServiceDef().getRowFilterDef().getAccessTypes().size());
+
+			ServiceDefUtil.normalizeAccessTypeDefs(policies.getTagPolicies().getServiceDef(), policies.getServiceDef().getName());
+
+			serviceMarkerAll = getAccessType(policies.getServiceDef().getMarkerAccessTypes(), ACCESS_TYPE_MARKER_ALL);
+			tagMarkerAll     = getAccessType(policies.getTagPolicies().getServiceDef().getMarkerAccessTypes(), ACCESS_TYPE_MARKER_ALL);
+
+			assertEquals("accessType count", policies.getServiceDef().getAccessTypes().size(), policies.getTagPolicies().getServiceDef().getAccessTypes().size());
+			assertEquals("impliedGrants: _ALL", new HashSet<>(serviceMarkerAll.getImpliedGrants()), new HashSet<>(tagMarkerAll.getImpliedGrants()));
+			assertEquals("dataMask.accessType count", policies.getServiceDef().getDataMaskDef().getAccessTypes().size(), policies.getTagPolicies().getServiceDef().getDataMaskDef().getAccessTypes().size());
+			assertEquals("rowFilter.accessType count", 0, policies.getTagPolicies().getServiceDef().getRowFilterDef().getAccessTypes().size());
+		}
+	}
+
+	private RangerAccessTypeDef getAccessType(List<RangerAccessTypeDef> accessTypeDefs, String accessType) {
+		RangerAccessTypeDef ret = null;
+
+		if (accessTypeDefs != null) {
+			for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) {
+				if (StringUtils.equals(accessTypeDef.getName(), accessType)) {
+					ret = accessTypeDef;
+
+					break;
+				}
+			}
+		}
+
+		return ret;
+	}
+
+	@Test
+	public void testAccessTypeMarkers() {
+		RangerAccessTypeDef create   = new RangerAccessTypeDef(1L, "create",  "create",  null, null, AccessTypeCategory.CREATE);
+		RangerAccessTypeDef select   = new RangerAccessTypeDef(2L, "select",  "select",  null, null, AccessTypeCategory.READ);
+		RangerAccessTypeDef update   = new RangerAccessTypeDef(3L, "update",  "update",  null, null, AccessTypeCategory.UPDATE);
+		RangerAccessTypeDef delete   = new RangerAccessTypeDef(4L, "delete",  "delete",  null, null, AccessTypeCategory.DELETE);
+		RangerAccessTypeDef manage   = new RangerAccessTypeDef(5L, "manage",  "manage",  null, null, AccessTypeCategory.MANAGE);
+		RangerAccessTypeDef read     = new RangerAccessTypeDef(6L, "read",    "read",    null, null, AccessTypeCategory.READ);
+		RangerAccessTypeDef write    = new RangerAccessTypeDef(7L, "write",   "write",   null, null, AccessTypeCategory.UPDATE);
+		RangerAccessTypeDef execute  = new RangerAccessTypeDef(8L, "execute", "execute", null, null, null);
+		Set<String>         allNames = toSet(create.getName(), select.getName(), update.getName(), delete.getName(), manage.getName(), read.getName(), write.getName(), execute.getName());
+
+		// 6 marker access-types should be populated with impliedGrants
+		List<RangerAccessTypeDef> accessTypeDefs = Arrays.asList(create, select, update, delete, manage, read, write, execute);
+		List<RangerAccessTypeDef> markerTypeDefs = ServiceDefUtil.getMarkerAccessTypes(accessTypeDefs);
+		assertEquals("markerTypeDefs count", 6, markerTypeDefs.size());
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_CREATE, toSet(create.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_CREATE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_READ,   toSet(select.getName(), read.getName()),  getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_READ));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_UPDATE, toSet(update.getName(), write.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_UPDATE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_DELETE, toSet(delete.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_DELETE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_MANAGE, toSet(manage.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_MANAGE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_ALL,    allNames, getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_ALL));
+
+		// 2 marker access-types should be populated with impliedGrants: _CREATE, _ALL
+		accessTypeDefs = new ArrayList<>(Collections.singleton(create));
+		markerTypeDefs = ServiceDefUtil.getMarkerAccessTypes(accessTypeDefs);
+		assertEquals("markerTypeDefs count", 6, markerTypeDefs.size());
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_CREATE, toSet(create.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_CREATE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_READ,   Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_READ));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_UPDATE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_UPDATE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_DELETE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_DELETE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_MANAGE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_MANAGE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_ALL,    toSet(create.getName()),  getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_ALL));
+
+		// 2 marker access-types should be populated with impliedGrants: _READ, _ALL
+		accessTypeDefs = new ArrayList<>(Arrays.asList(select, read));
+		markerTypeDefs = ServiceDefUtil.getMarkerAccessTypes(accessTypeDefs);
+		assertEquals("markerTypeDefs count", 6, markerTypeDefs.size());
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_CREATE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_CREATE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_READ,   toSet(select.getName(), read.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_READ));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_UPDATE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_UPDATE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_DELETE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_DELETE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_MANAGE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_MANAGE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_ALL,  toSet(select.getName(), read.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_ALL));
+
+		// accessTypes with no category should be added to _ALL
+		accessTypeDefs = new ArrayList<>(Collections.singleton(execute));
+		markerTypeDefs = ServiceDefUtil.getMarkerAccessTypes(accessTypeDefs);
+		assertEquals("markerTypeDefs count", 6, markerTypeDefs.size()); // 1 marker access-types should be added: _ALL
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_CREATE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_CREATE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_READ,   Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_READ));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_UPDATE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_UPDATE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_DELETE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_DELETE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_MANAGE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_MANAGE));
+		assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_ALL, toSet(execute.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_ALL));
+	}
+
+	private Set<String> getImpliedGrants(List<RangerAccessTypeDef> accessTypeDefs, String accessType) {
+		Set<String> ret = null;
+
+		if (accessTypeDefs != null) {
+			for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) {
+				if (StringUtils.equals(accessTypeDef.getName(), accessType)) {
+					ret = new HashSet<>(accessTypeDef.getImpliedGrants());
+
+					break;
+				}
+			}
+		}
+
+		return ret;
+	}
+
+	private Set<String> toSet(String...values) {
+		Set<String> ret = new HashSet<>();
+
+		if (values != null) {
+			for (String value : values) {
+				ret.add(value);
+			}
+		}
+
+		return ret;
+	}
 
 	private ServicePolicies getServicePolicies() {
 		ServicePolicies ret = new ServicePolicies();
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_marker_access_types.json b/agents-common/src/test/resources/policyengine/test_policyengine_marker_access_types.json
new file mode 100644
index 000000000..a18523b60
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_marker_access_types.json
@@ -0,0 +1,435 @@
+{
+  "serviceName": "hivedev",
+
+  "serviceDef": {
+    "name": "hive", "id": 3,
+    "resources": [
+      { "name": "database",    "level": 1, "parent": "",        "mandatory": true, "lookupSupported": true,  "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Hive Database", "description": "Hive Database" },
+      { "name": "url",         "level": 1, "parent": "",        "mandatory": true, "lookupSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerURLResourceMatcher",     "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "URL",           "description": "URL", "recursiveSupported": true },
+      { "name": "hiveservice", "level": 1, "parent": "",        "mandatory": true, "lookupSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "HiveService",   "description": "HiveService" },
+      { "name": "table",       "level": 2, "parent": "database", "mandatory": true, "lookupSupported": true,  "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Hive Table",    "description": "Hive Table" },
+      { "name": "udf",         "level": 2, "parent": "database", "mandatory": true, "lookupSupported": true,  "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Hive UDF",      "description": "Hive UDF" },
+      { "name": "column",      "level": 3, "parent": "table",    "mandatory": true, "lookupSupported": true,  "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Hive Column",   "description": "Hive Column" }
+    ],
+    "accessTypes": [
+      { "name": "select",       "label": "Select",       "category": "READ" },
+      { "name": "update",       "label": "Update" ,      "category": "UPDATE" },
+      { "name": "create",       "label": "Create",       "category": "CREATE" },
+      { "name": "drop",         "label": "Drop",         "category": "DELETE" },
+      { "name": "alter",        "label": "Alter",        "category": "CREATE" },
+      { "name": "index",        "label": "Index",        "category": "MANAGE" },
+      { "name": "lock",         "label": "Lock",         "category": "MANAGE" },
+      { "name": "read",         "label": "Read",         "category": "READ" },
+      { "name": "write",        "label": "Write",        "category": "UPDATE" },
+      { "name": "repladmin",    "label": "ReplAdmin",    "category": "MANAGE" },
+      { "name": "serviceadmin", "label": "ServiceAdmin", "category": "MANAGE" }
+    ],
+    "markerAccessTypes": [
+      { "name": "_CREATE", "label": "_CREATE", "impliedGrants": [ "create", "alter" ]  },
+      { "name": "_READ",   "label": "_READ",   "impliedGrants": [ "select", "read" ]  },
+      { "name": "_UPDATE", "label": "_UPDATE", "impliedGrants": [ "update", "write" ]  },
+      { "name": "_DELETE", "label": "_DELETE", "impliedGrants": [ "drop", "alter" ]  },
+      { "name": "_MANAGE", "label": "_MANAGE", "impliedGrants": [ "index", "lock", "repladmin", "serviceadmin" ]  },
+      { "name": "_ALL",    "label": "_ALL",    "impliedGrants": [ "select", "update", "create", "drop", "alter", "index", "lock", "read", "write", "repladmin", "serviceadmin" ]  }
+    ]
+  },
+
+  "policies": [
+    { "id": 1, "name": "db=default: audit-all-access", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "database": { "values": [ "default" ] }, "table": { "values": [ "*" ] }, "column": { "values": [ "*" ] } }
+    },
+    { "id": 2, "name": "db=default; table=test*; column=*", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "database": { "values": [ "default" ] }, "table": { "values": [ "test*" ] }, "column": { "values": [ "*" ] } },
+      "policyItems": [
+        { "accesses": [ { "type": "_READ", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ], "delegateAdmin": false },
+        { "accesses": [ { "type": "_CREATE", "isAllowed": true }, { "type": "_DELETE", "isAllowed": true } ], "users": [ "admin" ], "groups": [ "admin" ], "delegateAdmin": true }
+      ]
+    },
+    { "id": 3, "name": "db=db1; table=tbl*; column=*", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "database": { "values": [ "db1" ] }, "table": { "values": [ "tbl*" ] }, "column": { "values": [ "*" ] } },
+      "policyItems": [
+        { "accesses": [ { "type": "_READ", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ], "delegateAdmin": false }
+      ]
+    },
+    { "id": 4, "name": "db=db1; table=tmp; column=tmp*", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "database": { "values": [ "db1" ] }, "table": { "values": [ "tmp" ] }, "column": { "values": [ "tmp*" ], "isExcludes": true } },
+      "policyItems": [
+        { "accesses": [ { "type": "_READ", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ], "delegateAdmin": false }
+      ]
+    },
+    { "id": 5, "name": "hiveservice=*", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "hiveservice": { "values": [ "*" ] } },
+      "policyItems": [
+        { "accesses": [ { "type": "_MANAGE", "isAllowed": true } ], "users": [ "user1" ], "groups": [], "delegateAdmin": false }
+      ]
+    },
+    { "id": 6, "name": "db=demo1,demo2", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "database": { "values": [ "demo1", "demo2" ] } },
+      "policyItems": [
+        { "accesses": [ { "type": "_READ", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ], "delegateAdmin": false }
+      ]
+    },
+    { "id": 7, "name": "db=demo1; table=demo1_tbl1,demo1_tbl2; column=*", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "database": { "values": [ "demo1" ] }, "table": { "values": [ "demo1_tbl1", "demo1_tbl2" ] }, "column": { "values": [ "*" ] } },
+      "policyItems": [
+        { "accesses": [ { "type": "_CREATE", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ], "delegateAdmin": false }
+      ]
+    },
+    { "id": 8, "name": "db=dummy; table=*; column=*", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "database": { "values": [ "dummy" ] }, "table": { "values": [ "*" ] }, "column": { "values": [ "*" ] } },
+      "policyItems": [
+        { "accesses": [ { "type": "_CREATE", "isAllowed": true }, { "type": "_UPDATE", "isAllowed": true }, { "type": "_DELETE", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [], "delegateAdmin": false }
+      ],
+      "allowExceptions": [
+        { "accesses": [ { "type": "_CREATE", "isAllowed": true }, { "type": "_UPDATE", "isAllowed": true } ], "users": [ "user1" ], "groups": [], "delegateAdmin": false },
+        { "accesses": [ { "type": "_CREATE", "isAllowed": true }, { "type": "_UPDATE", "isAllowed": true }, { "type": "_DELETE", "isAllowed": true } ], "users": [ "user2" ], "groups": [], "delegateAdmin": false }
+      ]
+    },
+    { "id": 9, "name": "db=db1", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "database": { "values": [ "db1" ] } },
+      "isDenyAllElse": true,
+      "policyItems": [
+        { "accesses": [ { "type": "_READ", "isAllowed": true } ], "users": [ "user1", "user3", "user4" ], "groups": [ "group1", "group2" ], "delegateAdmin": false }
+      ]
+    },
+    { "id": 200, "name": "url=s3a://qe-s3-bucket-mst/test_abcd/abcd; s3a://qe-s3-bucket-mst/demo/*: URL-access-policy", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "url": { "values": [ "s3a://qe-s3-bucket-mst/test_abcd/abcd", "s3a://qe-s3-bucket-mst/demo" ], "isRecursive": true } },
+      "policyItems": [
+        { "accesses": [ { "type": "_READ", "isAllowed": true }, { "type": "_UPDATE", "isAllowed": true } ], "users": [], "groups": [ "public" ], "delegateAdmin": false }
+      ]
+    },
+    { "id": 201, "name": "url=http://qe-s3-bucket-mst/test_abcd/abcd/ URL-access-policy", "isEnabled": true, "isAuditEnabled": true,
+      "resources": { "url": { "values": [ "http://qe-s3-bucket-mst/test_abcd/abcd/" ], "isRecursive": true } },
+      "policyItems": [
+        { "accesses": [ { "type": "_READ", "isAllowed": true }, { "type": "_UPDATE", "isAllowed": true } ], "users": [ "user1" ], "groups": [], "delegateAdmin": false }
+      ]
+    }
+  ],
+
+  "tests": [
+    { "name": "ALLOW 'read http://qe-s3-bucket-mst/test_abcd/abcd;' for user1",
+      "request": {
+        "resource": { "elements": { "url": [ "http://qe-s3-bucket-mst/test_abcd/abcd", "http://qe-s3-bucket-mst/test_abcd/abcd/" ] } },
+        "accessType": "read", "user": "user1", "userGroups": [ "users" ], "requestData": "read http://qe-s3-bucket-mst/test_abcd/abcd for user1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 201 }
+    },
+    { "name": "ALLOW '_any access to no-database' for user5: match when request has less levels than policy",
+      "request": {
+        "resource": { "elements": {} },
+        "accessType": "", "user": "user5", "userGroups": [ "users" ], "requestData": "show databases"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 200 }
+    },
+    { "name": "ALLOW '_any access to db1' for user5: match when request has less levels than policy",
+      "request": {
+        "resource": { "elements": { "database": "db1" } },
+        "accessType": "", "user": "user5", "userGroups": [ "users" ], "requestData": "use db1"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": 9 }
+    },
+    { "name": "DENY '_any access to db1' for user5: match when request has less levels than policy",
+      "request": {
+        "resource": { "elements": { "database": "db1" } },
+        "accessType": "", "user": "user5", "userGroups": [ "users" ], "requestData": "use db1"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": 9 }
+    },
+    { "name": "ALLOW 'any dummy/*/*;' for user1",
+      "request": {
+        "resource": { "elements": { "database": "dummy", "table": "dummy", "column": "dummy" } },
+        "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "any dummy/dummy/dummy for user1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 8 }
+    },
+    { "name": "DENY 'any dummy/*/*;' for user2",
+      "request": {
+        "resource": { "elements": { "database": "dummy", "table": "dummy", "column": "dummy" } },
+        "accessType": "", "user": "user2", "userGroups": [ "users" ], "requestData": "any dummy/dummy/dummy for user2"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "ALLOW 'read s3a://qe-s3-bucket-mst/demo;' for user1",
+      "request": {
+        "resource": { "elements": { "url": "s3a://qe-s3-bucket-mst/demo" } },
+        "accessType": "read", "user": "user1", "userGroups": [ "users" ], "requestData": "read s3a://qe-s3-bucket-mst/demo for user1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 200 }
+    },
+    { "name": "ALLOW 'read s3a://qe-s3-bucket-mst/test_abcd/abcd;' for user1",
+      "request": {
+        "resource": { "elements": { "url": "s3a://qe-s3-bucket-mst/test_abcd/abcd" } },
+        "accessType": "read", "user": "user1", "userGroups": [ "users" ], "requestData": "read s3a://qe-s3-bucket-mst/test_abcd/abcd for user1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 200 }
+    },
+    { "name": "ALLOW 'read s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent;' for user1",
+      "request": {
+        "resource": { "elements": { "url": "s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent" } },
+        "accessType": "read", "user": "user1", "userGroups": [ "users" ], "requestData": "read s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent for user1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 200 }
+    },
+    { "name": "ALLOW 'write s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent;' for user1",
+      "request": {
+        "resource": { "elements": { "url": "s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent" } },
+        "accessType": "write", "user": "user1", "userGroups": [ "users" ], "requestData": "write s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent for user1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 200 }
+    },
+    { "name": "DENY 'select tmp_1 from db1.tmp ;' for user1",
+      "request": {
+        "resource": { "elements": { "database": "db1", "table": "tmp", "column": "tmp_1" } },
+        "accessType": "select", "user": "user1", "userGroups": [ "users" ], "requestData": "select tmp_1 from db1.tmp for user1"
+        , "remoteIPAddress": "1.1.1.1", "forwardedAddresses": [ "127.0.0.1", "10.10.10.10" ]
+      },
+      "result": { "isAudited": false, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "ALLOW 'select abc_1 from db1.tmp ;' for user1",
+      "request": {
+        "resource": { "elements": { "database": "db1", "table": "tmp", "column": "abc_1" } },
+        "accessType": "select", "user": "user1", "userGroups": [ "users" ], "requestData": "select abc_1 from db1.tmp for user1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 4 }
+    },
+    { "name": "ALLOW 'use default;' for user1",
+      "request": {
+        "resource": { "elements": { "database": "default" } },
+        "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "use default"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "ALLOW 'use default;' for user2",
+      "request": {
+        "resource": { "elements": { "database": "default" } },
+        "accessType": "", "user": "user2", "userGroups": [ "users" ], "requestData": "use default"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "DENY 'use default;' to user3",
+      "request": {
+        "resource": { "elements": { "database": "default" } },
+        "accessType": "", "user": "user3", "userGroups": [ "users" ], "requestData": "use default"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "ALLOW 'use default;' to group1",
+      "request": {
+        "resource": { "elements": { "database": "default" } },
+        "accessType": "", "user": "user3", "userGroups": [ "users", "group1" ], "requestData": "use default"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "ALLOW 'use default;' to group2",
+      "request": {
+        "resource": { "elements": { "database": "default" } },
+        "accessType": "", "user": "user3", "userGroups": [ "users", "group2" ], "requestData": "use default"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "DENY 'use default;' to user3/group3",
+      "request": {
+        "resource": { "elements": { "database": "default" } },
+        "accessType": "", "user": "user3", "userGroups": [ "users", "group3" ], "requestData": "use default"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY 'use finance;' to user3/group3",
+      "request": {
+        "resource": { "elements": { "database": "finance" } },
+        "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "use finance"
+      },
+      "result": { "isAudited": false, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "ALLOW 'select col1 from default.testtable;' to user1",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } },
+        "accessType": "select", "user": "user1", "userGroups": [ "users" ], "requestData": "select col1 from default.testtable"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "ALLOW 'select col1 from default.testtable;' to user2",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } },
+        "accessType": "select", "user": "user2", "userGroups": [ "users" ], "requestData": "select col1 from default.testtable"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "DENY 'select col1 from default.testtable;' to user3",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } },
+        "accessType": "select", "user": "user3", "userGroups": [ "users" ], "requestData": "select col1 from default.testtable"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "ALLOW 'select col1 from default.testtable;' to group1",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } },
+        "accessType": "select", "user": "user3", "userGroups": [ "users", "group1" ], "requestData": "select col1 from default.testtable"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "ALLOW 'select col1 from default.testtable;' to group2",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } },
+        "accessType": "select", "user": "user3", "userGroups": [ "users", "group2" ], "requestData": "select col1 from default.testtable"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "DENY 'select col1 from default.testtable;' to user3/group3",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } },
+        "accessType": "select", "user": "user3", "userGroups": [ "users", "group3" ], "requestData": "select col1 from default.testtable"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY 'select col1 from default.table1;' to user1",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "table1", "column": "col1" } },
+        "accessType": "select", "user": "user1", "userGroups": [ "users" ], "requestData": "select col1 from default.table1"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY 'create table default.testtable1;' to user1",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable1" } },
+        "accessType": "create", "user": "user1", "userGroups": [ "users" ], "requestData": "create table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY 'create table default.testtable1;' to user1/group1",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable1" } },
+        "accessType": "create", "user": "user1", "userGroups": [ "users", "group1" ], "requestData": "create table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "ALLOW 'create table default.testtable1;' to admin",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable1" } },
+        "accessType": "create", "user": "admin", "userGroups": [ "users" ], "requestData": "create table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "ALLOW 'create table default.testtable1;' to user1/admin",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable1" } },
+        "accessType": "create", "user": "user1", "userGroups": [ "users", "admin" ], "requestData": "create table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "DENY 'drop table default.testtable1;' to user1",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable1" } },
+        "accessType": "drop", "user": "user1", "userGroups": [ "users" ], "requestData": "drop table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY 'drop table default.testtable1;' to user1/group1",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable1" } },
+        "accessType": "drop", "user": "user1", "userGroups": [ "users", "group1" ], "requestData": "drop table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "ALLOW 'drop table default.testtable1;' to admin",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable1" } },
+        "accessType": "drop", "user": "admin", "userGroups": [ "users" ], "requestData": "drop table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "ALLOW 'drop table default.testtable1;' to user1/admin",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "testtable1" } },
+        "accessType": "drop", "user": "user1", "userGroups": [ "users", "admin" ], "requestData": "drop table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
+    },
+    { "name": "DENY 'create table default.table1;' to user1",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "table1" } },
+        "accessType": "create", "user": "user1", "userGroups": [ "users" ], "requestData": "create table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY 'create table default.table1;' to user1/admin",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "table1" } },
+        "accessType": "create", "user": "user1", "userGroups": [ "users", "admin" ], "requestData": "create table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY 'drop table default.table1;' to user1",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "table1" } },
+        "accessType": "drop", "user": "user1", "userGroups": [ "users" ], "requestData": "drop table default.testtable1"
+      },
+      "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY 'drop table default.table1;' to user1/admin",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "table1" } },
+        "accessType": "drop", "user": "user1", "userGroups": [ "users", "admin" ], "requestData": "drop table default.testtable1"
+       },
+       "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY 'select col1 from default.table1;' to user3",
+      "request": {
+        "resource": { "elements": { "database": "default", "table": "table1", "column": "col1" } },
+        "accessType": "select", "user": "user3", "userGroups": [ "users" ], "requestData": "select col1 from default.table1"
+       },
+       "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY '_any access to db1/table1' for user1: table-level mismatch",
+      "request": {
+        "resource": { "elements": { "database": "db1", "table": "table1" } },
+        "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "show columns in table1 from db1;"
+       },
+       "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "DENY '_any access to db1/_/col1' for user1: table not specified but column was specified",
+      "request": {
+        "resource": { "elements": { "database": "db1", "column": "col1" } },
+        "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "fictional use case when request specified a lower level resource by skipping intermediate resource"
+       },
+       "result": { "isAudited": false, "isAllowed": false, "policyId": -1 }
+    },
+    { "name": "ALLOW '_any access to db1' for user1: match when request has less levels than policy",
+      "request": {
+        "resource": { "elements": { "database": "db1" } },
+        "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "use db1"
+       },
+       "result": { "isAudited": true, "isAllowed": true, "policyId": 3 }
+    },
+    { "name": "ALLOW '_any access to db1/tbl1' for user1: match when request has same levels as policy",
+      "request": {
+        "resource": { "elements": { "database": "db1", "table": "tbl1" } },
+        "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "describe db1.tbl1"
+       },
+       "result": { "isAudited": true, "isAllowed": true, "policyId": 3 }
+    },
+    { "name": "ALLOW '_any access to db1/tbl1/col1' for user1: match when request has more specific levels than policy",
+      "request": {
+        "resource": { "elements": { "database": "db1", "table": "tbl1", "column": "col1" } },
+        "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "fictional case: request for any match today happens only at a higher levels"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 3 }
+    },
+    { "name": "ALLOW 'kill_query' for user1 on any cluster",
+      "request": {
+        "resource": { "elements": { "hiveservice": "testcluster" } },
+        "accessType": "serviceadmin", "user": "user1", "userGroups": [ "users" ], "requestData": "kill query 'dummyqueryid'"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 5 }
+    },
+    { "name": "ALLOW '_any access to demo1/demo_tbl1' for user1: show table test",
+      "request": {
+        "resource": { "elements": { "database": "demo1", "table": "demo1_tbl1" } },
+        "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "show tables"
+      },
+      "result": { "isAudited": true, "isAllowed": true, "policyId": 7 }
+    }
+  ]
+}
+
diff --git a/agents-common/src/test/resources/test_servicedef-normalize.json b/agents-common/src/test/resources/test_servicedef-normalize.json
new file mode 100644
index 000000000..52825f4f5
--- /dev/null
+++ b/agents-common/src/test/resources/test_servicedef-normalize.json
@@ -0,0 +1,478 @@
+{
+    "serviceId":   4,
+    "serviceName": "dev_hive",
+    "serviceDef": {
+        "id":          3,
+        "isEnabled":   true,
+        "name":        "hive",
+        "displayName": "Hadoop SQL",
+        "implClass":   "org.apache.ranger.services.hive.RangerServiceHive",
+        "label":       "Hive Server2",
+        "description": "Hive Server2",
+        "options":     { "enableDenyAndExceptionsInPolicies": "true" },
+        "configs": [
+            { "itemId": 1, "name": "username",                    "type": "string",   "mandatory": true },
+            { "itemId": 2, "name": "password",                    "type": "password", "mandatory": true },
+            { "itemId": 3, "name": "jdbc.driverClassName",        "type": "string",   "mandatory": true, "defaultValue": "org.apache.hive.jdbc.HiveDriver" },
+            { "itemId": 4, "name": "jdbc.url",                    "type": "string",   "mandatory": true },
+            { "itemId": 5, "name": "commonNameForCertificate",    "type": "string",   "mandatory": false },
+            { "itemId": 6, "name": "ranger.plugin.audit.filters", "type": "string",   "mandatory": false, "defaultValue": "[ {'accessResult': 'DENIED', 'isAudited': true}, {'actions':['METADATA OPERATION'], 'isAudited': false}, {'users':['hive','hue'],'actions':['SHOW_ROLES'],'isAudited':false} ]" }
+        ],
+        "resources": [
+            { "itemId": 1, "name": "database", "type": "string", "level": 10, "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, "label": "Hive Database", "description": "Hive Database", "accessTypeRestrictions": [], "isValidLeaf": true },
+            { "itemId": 2, "name": "table", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, "label": "Hive Table", "description": "Hive Table", "accessTypeRestrictions": [], "isValidLeaf": true },
+            { "itemId": 3, "name": "udf", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, "label": "Hive UDF", "description": "Hive UDF", "accessTypeRestrictions": [], "isValidLeaf": true },
+            { "itemId": 4, "name": "column", "type": "string", "level": 30, "parent": "table", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, "label": "Hive Column", "description": "Hive Column", "accessTypeRestrictions": [], "isValidLeaf": true },
+            { "itemId": 5, "name": "url", "type": "string", "level": 10, "mandatory": true, "lookupSupported": false, "recursiveSupported": true, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerURLResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "false" }, "label": "URL", "description": "URL", "accessTypeRestrictions": [], "isValidLeaf": true },
+            { "itemId": 6, "name": "hiveservice", "type": "string", "level": 10, "mandatory": true, "lookupSupported": false, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "false" }, "label": "Hive Service", "description": "Hive Service", "accessTypeRestrictions": [], "isValidLeaf": true },
+            { "itemId": 7, "name": "global", "type": "string", "level": 10, "mandatory": false, "lookupSupported": false, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "false" }, "label": "Global", "description": "Global", "accessTypeRestrictions": [], "isValidLeaf": true }
+        ],
+        "accessTypes": [
+            { "itemId": 1, "name": "select",        "label": "select" },
+            { "itemId": 2, "name": "update",        "label": "update" },
+            { "itemId": 3, "name": "create",        "label": "Create" },
+            { "itemId": 4, "name": "drop",          "label": "Drop" },
+            { "itemId": 5, "name": "alter",         "label": "Alter" },
+            { "itemId": 6, "name": "index",         "label": "Index" },
+            { "itemId": 7, "name": "lock",          "label": "Lock" },
+            { "itemId": 8, "name": "all",           "label": "All",    "impliedGrants": [ "select", "update", "create", "drop", "alter", "index", "lock", "read", "write", "repladmin", "serviceadmin", "refresh" ] },
+            { "itemId": 9, "name": "read",          "label": "Read" },
+            { "itemId": 10, "name": "write",        "label": "Write" },
+            { "itemId": 11, "name": "repladmin",    "label": "ReplAdmin" },
+            { "itemId": 12, "name": "serviceadmin", "label": "Service Admin" },
+            { "itemId": 13, "name": "tempudfadmin", "label": "Temporary UDF Admin" },
+            { "itemId": 14, "name": "refresh",      "label": "Refresh" }
+        ],
+        "policyConditions": [],
+        "contextEnrichers": [],
+        "enums": [],
+        "dataMaskDef": {
+            "maskTypes": [
+                { "itemId": 1,  "name": "MASK",                "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "mask({col})", "dataMaskOptions": {} },
+                { "itemId": 2,  "name": "MASK_SHOW_LAST_4",    "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'x'", "transformer": "mask_show_last_n({col}, 4, 'x', 'x', 'x', -1, '1')", "dataMaskOptions": {} },
+                { "itemId": 3,  "name": "MASK_SHOW_FIRST_4",   "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "mask_show_first_n({col}, 4, 'x', 'x', 'x', -1, '1')", "dataMaskOptions": {} },
+                { "itemId": 4,  "name": "MASK_HASH",           "label": "Hash", "description": "Hash the value", "transformer": "mask_hash({col})", "dataMaskOptions": {} },
+                { "itemId": 5,  "name": "MASK_NULL",           "label": "Nullify", "description": "Replace with NULL", "dataMaskOptions": {} },
+                { "itemId": 6,  "name": "MASK_NONE",           "label": "Unmasked (retain original value)", "description": "No masking", "dataMaskOptions": {} },
+                { "itemId": 12, "name": "MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "mask({col}, 'x', 'x', 'x', -1, '1', 1, 0, -1)", "dataMaskOptions": {} },
+                { "itemId": 13, "name": "CUSTOM",              "label": "Custom", "description": "Custom", "dataMaskOptions": {} }
+            ],
+            "accessTypes": [
+                { "itemId": 1, "name": "select", "label": "select" }
+            ],
+            "resources": [
+                { "itemId": 1, "name": "database", "type": "string", "level": 10, "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, "uiHint": "{ \"singleValue\":true }", "label": "Hive Database", "description": "Hive Database", "accessTypeRestrictions": [], "isValidLeaf": false },
+                { "itemId": 2, "name": "table", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, "uiHint": "{ \"singleValue\":true }", "label": "Hive Table", "description": "Hive Table", "accessTypeRestrictions": [], "isValidLeaf": false },
+                { "itemId": 4, "name": "column", "type": "string", "level": 30, "parent": "table", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, "uiHint": "{ \"singleValue\":true }", "label": "Hive Column", "description": "Hive Column", "accessTypeRestrictions": [], "isValidLeaf": true
+                }
+            ]
+        },
+        "rowFilterDef": {
+            "accessTypes": [ { "itemId": 1, "name": "select", "label": "select" } ],
+            "resources": [
+                { "itemId": 1, "name": "database", "type": "string", "level": 10, "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, "uiHint": "{ \"singleValue\":true }", "label": "Hive Database", "description": "Hive Database", "accessTypeRestrictions": [], "isValidLeaf": false },
+                { "itemId": 2, "name": "table", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, "uiHint": "{ \"singleValue\":true }", "label": "Hive Table", "description": "Hive Table", "accessTypeRestrictions": [], "isValidLeaf": true }
+            ]
+        },
+        "markerAccessTypes": [
+            { "itemId": 20, "name": "_ALL", "label": "_ALL", "impliedGrants": [ "drop", "all", "select", "read", "update", "index", "refresh", "tempudfadmin", "serviceadmin", "create", "lock", "repladmin", "write", "alter" ] }
+        ]
+    },
+    "policies": [],
+    "auditMode": "audit-default",
+    "tagPolicies": {
+        "serviceId":   2,
+        "serviceName": "dev_tag",
+        "policies":    [],
+        "serviceDef": {
+	    "id":       100,
+	    "name":     "tag",
+	    "isEnabled": true,
+	    "implClass": "org.apache.ranger.services.tag.RangerServiceTag",
+	    "options":   { "enableDenyAndExceptionsInPolicies": "true", "ui.pages": "tag-based-policies" },
+	    "configs": [
+		{ "itemId": 1, "name": "ranger.plugin.audit.filters", "type": "string", "level": 1, "mandatory": false, "label": "Ranger Default Audit Filters" }
+	    ],
+	    "resources": [
+		{ "itemId": 1, "name": "tag", "type": "string", "level": 1, "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "false" }, "uiHint": "{ \"singleValue\":true }", "label": "TAG", "description": "TAG", "isValidLeaf": true }
+	    ],
+	    "accessTypes": [
+		{ "itemId": 14015, "name": "sqoop:READ", "label": "READ" },
+		{ "itemId": 14016, "name": "sqoop:WRITE", "label": "WRITE" },
+		{ "itemId": 12013, "name": "kylin:QUERY", "label": "QUERY" },
+		{ "itemId": 12014, "name": "kylin:OPERATION", "label": "OPERATION" },
+		{ "itemId": 12015, "name": "kylin:MANAGEMENT", "label": "MANAGEMENT" },
+		{ "itemId": 12016, "name": "kylin:ADMIN", "label": "ADMIN" },
+		{ "itemId": 16017, "name": "elasticsearch:all", "label": "all", "impliedGrants": [ "elasticsearch:read", "elasticsearch:read_cross_cluster", "elasticsearch:index", "elasticsearch:create", "elasticsearch:delete", "elasticsearch:write", "elasticsearch:delete_index", "elasticsearch:create_index", "elasticsearch:indices_put", "elasticsearch:indices_search_shards", "elasticsearch:indices_bulk", "elasticsearch:monitor", "elasticsearch:indices_index", "elasticsearch:manage", "elasticsearch:vi [...]
+		{ "itemId": 16018, "name": "elasticsearch:monitor", "label": "monitor" },
+		{ "itemId": 16019, "name": "elasticsearch:manage", "label": "manage", "impliedGrants": [ "elasticsearch:monitor" ] },
+		{ "itemId": 16020, "name": "elasticsearch:view_index_metadata", "label": "view_index_metadata", "impliedGrants": [ "elasticsearch:indices_search_shards" ] },
+		{ "itemId": 16021, "name": "elasticsearch:read", "label": "read" },
+		{ "itemId": 16022, "name": "elasticsearch:read_cross_cluster", "label": "read_cross_cluster", "impliedGrants": [ "elasticsearch:indices_search_shards" ] },
+		{ "itemId": 16023, "name": "elasticsearch:index", "label": "index", "impliedGrants": [ "elasticsearch:indices_put", "elasticsearch:indices_bulk", "elasticsearch:indices_index" ] },
+		{ "itemId": 16024, "name": "elasticsearch:create", "label": "create", "impliedGrants": [ "elasticsearch:indices_put", "elasticsearch:indices_bulk", "elasticsearch:indices_index" ] },
+		{ "itemId": 16025, "name": "elasticsearch:delete", "label": "delete", "impliedGrants": [ "elasticsearch:indices_bulk" ] },
+		{ "itemId": 16026, "name": "elasticsearch:write", "label": "write", "impliedGrants": [ "elasticsearch:indices_put" ] },
+		{ "itemId": 16027, "name": "elasticsearch:delete_index", "label": "delete_index" },
+		{ "itemId": 16028, "name": "elasticsearch:create_index", "label": "create_index" },
+		{ "itemId": 203204, "name": "trino:select", "label": "Select" },
+		{ "itemId": 203205, "name": "trino:insert", "label": "Insert" },
+		{ "itemId": 203206, "name": "trino:create", "label": "Create" },
+		{ "itemId": 203207, "name": "trino:drop", "label": "Drop" },
+		{ "itemId": 203208, "name": "trino:delete", "label": "Delete" },
+		{ "itemId": 203209, "name": "trino:use", "label": "Use" },
+		{ "itemId": 203210, "name": "trino:alter", "label": "Alter" },
+		{ "itemId": 203211, "name": "trino:grant", "label": "Grant" },
+		{ "itemId": 203212, "name": "trino:revoke", "label": "Revoke" },
+		{ "itemId": 203213, "name": "trino:show", "label": "Show" },
+		{ "itemId": 203214, "name": "trino:impersonate", "label": "Impersonate" },
+		{ "itemId": 203215, "name": "trino:all", "label": "All", "impliedGrants": [ "trino:execute", "trino:delete", "trino:drop", "trino:create", "trino:insert", "trino:select", "trino:revoke", "trino:impersonate", "trino:show", "trino:use", "trino:alter", "trino:grant" ] },
+		{ "itemId": 203216, "name": "trino:execute", "label": "execute" },
+		{ "itemId": 17018, "name": "presto:select", "label": "Select" },
+		{ "itemId": 17019, "name": "presto:insert", "label": "Insert" },
+		{ "itemId": 17020, "name": "presto:create", "label": "Create" },
+		{ "itemId": 17021, "name": "presto:drop", "label": "Drop" },
+		{ "itemId": 17022, "name": "presto:delete", "label": "Delete" },
+		{ "itemId": 17023, "name": "presto:use", "label": "Use" },
+		{ "itemId": 17024, "name": "presto:alter", "label": "Alter" },
+		{ "itemId": 17025, "name": "presto:grant", "label": "Grant" },
+		{ "itemId": 17026, "name": "presto:revoke", "label": "Revoke" },
+		{ "itemId": 17027, "name": "presto:show", "label": "Show" },
+		{ "itemId": 17028, "name": "presto:impersonate", "label": "Impersonate" },
+		{ "itemId": 17029, "name": "presto:all", "label": "All", "impliedGrants": [ "presto:use", "presto:alter", "presto:execute", "presto:impersonate", "presto:show", "presto:revoke", "presto:grant", "presto:select", "presto:insert", "presto:create", "presto:delete", "presto:drop" ] },
+		{ "itemId": 17030, "name": "presto:execute", "label": "execute" },
+		{ "itemId": 201209, "name": "ozone:all", "label": "All", "impliedGrants": [ "ozone:create", "ozone:read", "ozone:write", "ozone:list", "ozone:delete", "ozone:read_acl", "ozone:write_acl" ] },
+		{ "itemId": 201202, "name": "ozone:read", "label": "Read" },
+		{ "itemId": 201203, "name": "ozone:write", "label": "Write" },
+		{ "itemId": 201204, "name": "ozone:create", "label": "Create" },
+		{ "itemId": 201205, "name": "ozone:list", "label": "List" },
+		{ "itemId": 201206, "name": "ozone:delete", "label": "Delete" },
+		{ "itemId": 201207, "name": "ozone:read_acl", "label": "Read_ACL" },
+		{ "itemId": 201208, "name": "ozone:write_acl", "label": "Write_ACL" },
+		{ "itemId": 105106, "name": "kudu:select", "label": "SELECT", "impliedGrants": [ "kudu:metadata" ] },
+		{ "itemId": 105107, "name": "kudu:insert", "label": "INSERT", "impliedGrants": [ "kudu:metadata" ] },
+		{ "itemId": 105108, "name": "kudu:update", "label": "UPDATE", "impliedGrants": [ "kudu:metadata" ] },
+		{ "itemId": 105109, "name": "kudu:delete", "label": "DELETE", "impliedGrants": [ "kudu:metadata" ] },
+		{ "itemId": 105110, "name": "kudu:alter", "label": "ALTER", "impliedGrants": [ "kudu:metadata" ] },
+		{ "itemId": 105111, "name": "kudu:create", "label": "CREATE", "impliedGrants": [ "kudu:metadata" ] },
+		{ "itemId": 105112, "name": "kudu:drop", "label": "DROP", "impliedGrants": [ "kudu:metadata" ] },
+		{ "itemId": 105113, "name": "kudu:metadata", "label": "METADATA" },
+		{ "itemId": 105114, "name": "kudu:all", "label": "ALL", "impliedGrants": [ "kudu:insert", "kudu:update", "kudu:delete", "kudu:alter", "kudu:create", "kudu:drop", "kudu:metadata", "kudu:select" ] },
+		{ "itemId": 205206, "name": "nestedstructure:read", "label": "Read" },
+		{ "itemId": 205207, "name": "nestedstructure:write", "label": "Write" },
+		{ "itemId": 1002, "name": "hdfs:read", "label": "Read" },
+		{ "itemId": 1003, "name": "hdfs:write", "label": "Write" },
+		{ "itemId": 1004, "name": "hdfs:execute", "label": "Execute" },
+		{ "itemId": 2003, "name": "hbase:read", "label": "Read" },
+		{ "itemId": 2004, "name": "hbase:write", "label": "Write" },
+		{ "itemId": 2005, "name": "hbase:create", "label": "Create" },
+		{ "itemId": 2006, "name": "hbase:admin", "label": "Admin", "impliedGrants": [ "hbase:write", "hbase:create", "hbase:read" ] },
+		{ "itemId": 2007, "name": "hbase:execute", "label": "Execute" },
+		{ "itemId": 3004, "name": "hive:select", "label": "select" },
+		{ "itemId": 3005, "name": "hive:update", "label": "update" },
+		{ "itemId": 3006, "name": "hive:create", "label": "Create" },
+		{ "itemId": 3007, "name": "hive:drop", "label": "Drop" },
+		{ "itemId": 3008, "name": "hive:alter", "label": "Alter" },
+		{ "itemId": 3009, "name": "hive:index", "label": "Index" },
+		{ "itemId": 3010, "name": "hive:lock", "label": "Lock" },
+		{ "itemId": 3011, "name": "hive:all", "label": "All", "impliedGrants": [ "hive:read", "hive:select", "hive:update", "hive:create", "hive:drop", "hive:alter", "hive:index", "hive:lock", "hive:write", "hive:repladmin", "hive:serviceadmin", "hive:refresh" ] },
+		{ "itemId": 3012, "name": "hive:read", "label": "Read" },
+		{ "itemId": 3013, "name": "hive:write", "label": "Write" },
+		{ "itemId": 3014, "name": "hive:repladmin", "label": "ReplAdmin" },
+		{ "itemId": 3015, "name": "hive:serviceadmin", "label": "Service Admin" },
+		{ "itemId": 3016, "name": "hive:tempudfadmin", "label": "Temporary UDF Admin" },
+		{ "itemId": 3017, "name": "hive:refresh", "label": "Refresh" },
+		{ "itemId": 7008, "name": "kms:create", "label": "Create" },
+		{ "itemId": 7009, "name": "kms:delete", "label": "Delete" },
+		{ "itemId": 7010, "name": "kms:rollover", "label": "Rollover" },
+		{ "itemId": 7011, "name": "kms:setkeymaterial", "label": "Set Key Material" },
+		{ "itemId": 7012, "name": "kms:get", "label": "Get" },
+		{ "itemId": 7013, "name": "kms:getkeys", "label": "Get Keys" },
+		{ "itemId": 7014, "name": "kms:getmetadata", "label": "Get Metadata" },
+		{ "itemId": 7015, "name": "kms:generateeek", "label": "Generate EEK" },
+		{ "itemId": 7016, "name": "kms:decrypteek", "label": "Decrypt EEK" },
+		{ "itemId": 5006, "name": "knox:allow", "label": "Allow" },
+		{ "itemId": 6007, "name": "storm:submitTopology", "label": "Submit Topology", "impliedGrants": [ "storm:fileUpload", "storm:fileDownload" ] },
+		{ "itemId": 6008, "name": "storm:fileUpload", "label": "File Upload" },
+		{ "itemId": 6011, "name": "storm:fileDownload", "label": "File Download" },
+		{ "itemId": 6012, "name": "storm:killTopology", "label": "Kill Topology" },
+		{ "itemId": 6013, "name": "storm:rebalance", "label": "Rebalance" },
+		{ "itemId": 6014, "name": "storm:activate", "label": "Activate" },
+		{ "itemId": 6015, "name": "storm:deactivate", "label": "Deactivate" },
+		{ "itemId": 6016, "name": "storm:getTopologyConf", "label": "Get Topology Conf" },
+		{ "itemId": 6017, "name": "storm:getTopology", "label": "Get Topology" },
+		{ "itemId": 6018, "name": "storm:getUserTopology", "label": "Get User Topology" },
+		{ "itemId": 6019, "name": "storm:getTopologyInfo", "label": "Get Topology Info" },
+		{ "itemId": 6020, "name": "storm:uploadNewCredentials", "label": "Upload New Credential" },
+		{ "itemId": 4005, "name": "yarn:submit-app", "label": "submit-app" },
+		{ "itemId": 4006, "name": "yarn:admin-queue", "label": "admin-queue", "impliedGrants": [ "yarn:submit-app" ] },
+		{ "itemId": 9010, "name": "kafka:publish", "label": "Publish", "impliedGrants": [ "kafka:describe" ] },
+		{ "itemId": 9011, "name": "kafka:consume", "label": "Consume", "impliedGrants": [ "kafka:describe" ] },
+		{ "itemId": 9014, "name": "kafka:configure", "label": "Configure", "impliedGrants": [ "kafka:describe" ] },
+		{ "itemId": 9015, "name": "kafka:describe", "label": "Describe" },
+		{ "itemId": 9016, "name": "kafka:kafka_admin", "label": "Kafka Admin", "impliedGrants": [ "kafka:consume", "kafka:configure", "kafka:alter_configs", "kafka:describe_configs", "kafka:create", "kafka:describe", "kafka:alter", "kafka:idempotent_write", "kafka:cluster_action", "kafka:delete", "kafka:publish" ] },
+		{ "itemId": 9017, "name": "kafka:create", "label": "Create" },
+		{ "itemId": 9018, "name": "kafka:delete", "label": "Delete", "impliedGrants": [ "kafka:describe" ] },
+		{ "itemId": 9019, "name": "kafka:idempotent_write", "label": "Idempotent Write" },
+		{ "itemId": 9020, "name": "kafka:describe_configs", "label": "Describe Configs" },
+		{ "itemId": 9021, "name": "kafka:alter_configs", "label": "Alter Configs", "impliedGrants": [ "kafka:describe_configs" ] },
+		{ "itemId": 9022, "name": "kafka:cluster_action", "label": "Cluster Action" },
+		{ "itemId": 9023, "name": "kafka:alter", "label": "Alter" },
+		{ "itemId": 8108, "name": "solr:query", "label": "Query" },
+		{ "itemId": 8208, "name": "solr:update", "label": "Update" },
+		{ "itemId": 202203, "name": "schema-registry:create", "label": "Create" },
+		{ "itemId": 202204, "name": "schema-registry:read", "label": "Read" },
+		{ "itemId": 202205, "name": "schema-registry:update", "label": "Update" },
+		{ "itemId": 202206, "name": "schema-registry:delete", "label": "Delete" },
+		{ "itemId": 10110, "name": "nifi:READ", "label": "Read" },
+		{ "itemId": 10210, "name": "nifi:WRITE", "label": "Write" },
+		{ "itemId": 13113, "name": "nifi-registry:READ", "label": "Read" },
+		{ "itemId": 13213, "name": "nifi-registry:WRITE", "label": "Write" },
+		{ "itemId": 13313, "name": "nifi-registry:DELETE", "label": "Delete" },
+		{ "itemId": 15016, "name": "atlas:type-create", "label": "Create Type", "impliedGrants": [ "atlas:type-read" ] },
+		{ "itemId": 15017, "name": "atlas:type-update", "label": "Update Type", "impliedGrants": [ "atlas:type-read" ] },
+		{ "itemId": 15018, "name": "atlas:type-delete", "label": "Delete Type", "impliedGrants": [ "atlas:type-read" ] },
+		{ "itemId": 15019, "name": "atlas:entity-read", "label": "Read Entity" },
+		{ "itemId": 15020, "name": "atlas:entity-create", "label": "Create Entity" },
+		{ "itemId": 15021, "name": "atlas:entity-update", "label": "Update Entity" },
+		{ "itemId": 15022, "name": "atlas:entity-delete", "label": "Delete Entity" },
+		{ "itemId": 15023, "name": "atlas:entity-add-classification", "label": "Add Classification" },
+		{ "itemId": 15024, "name": "atlas:entity-update-classification", "label": "Update Classification" },
+		{ "itemId": 15025, "name": "atlas:entity-remove-classification", "label": "Remove Classification" },
+		{ "itemId": 15026, "name": "atlas:admin-export", "label": "Admin Export" },
+		{ "itemId": 15027, "name": "atlas:admin-import", "label": "Admin Import" },
+		{ "itemId": 15028, "name": "atlas:add-relationship", "label": "Add Relationship" },
+		{ "itemId": 15029, "name": "atlas:update-relationship", "label": "Update Relationship" },
+		{ "itemId": 15030, "name": "atlas:remove-relationship", "label": "Remove Relationship" },
+		{ "itemId": 15031, "name": "atlas:admin-purge", "label": "Admin Purge" },
+		{ "itemId": 15032, "name": "atlas:entity-add-label", "label": "Add Label" },
+		{ "itemId": 15033, "name": "atlas:entity-remove-label", "label": "Remove Label" },
+		{ "itemId": 15034, "name": "atlas:entity-update-business-metadata", "label": "Update Business Metadata" },
+		{ "itemId": 15035, "name": "atlas:type-read", "label": "Read Type" },
+		{ "itemId": 15036, "name": "atlas:admin-audits", "label": "Admin Audits" }
+	    ],
+	    "policyConditions": [],
+	    "contextEnrichers": [],
+	    "dataMaskDef": {
+		"maskTypes": [
+		    { "itemId": 203204, "name": "trino:MASK", "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "cast(regexp_replace(regexp_replace(regexp_replace({col},'([A-Z])', 'X'),'([a-z])','x'),'([0-9])','0') as {type})"
+		    },
+		    { "itemId": 203205, "name": "trino:MASK_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'X'", "transformer": "cast(regexp_replace({col}, '(.*)(.{4}$)', x -> regexp_replace(x[1], '.', 'X') || x[2]) as {type})" },
+		    { "itemId": 203206, "name": "trino:MASK_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "cast(regexp_replace({col}, '(^.{4})(.*)', x -> x[1] || regexp_replace(x[2], '.', 'X')) as {type})" },
+		    { "itemId": 203207, "name": "trino:MASK_HASH", "label": "Hash", "description": "Hash the value of a varchar with sha256", "transformer": "cast(to_hex(sha256(to_utf8({col}))) as {type})" },
+		    { "itemId": 203208, "name": "trino:MASK_NULL", "label": "Nullify", "description": "Replace with NULL" },
+		    { "itemId": 203209, "name": "trino:MASK_NONE", "label": "Unmasked (retain original value)", "description": "No masking" },
+		    { "itemId": 203215, "name": "trino:MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "date_trunc('year', {col})" },
+		    { "itemId": 203216, "name": "trino:CUSTOM", "label": "Custom", "description": "Custom" },
+		    { "itemId": 17018, "name": "presto:MASK", "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "cast(regexp_replace(regexp_replace(regexp_replace({col},'([A-Z])', 'X'),'([a-z])','x'),'([0-9])','0') as {type})" },
+		    { "itemId": 17019, "name": "presto:MASK_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'X'", "transformer": "cast(regexp_replace({col}, '(.*)(.{4}$)', x -> regexp_replace(x[1], '.', 'X') || x[2]) as {type})" },
+		    { "itemId": 17020, "name": "presto:MASK_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "cast(regexp_replace({col}, '(^.{4})(.*)', x -> x[1] || regexp_replace(x[2], '.', 'X')) as {type})" },
+		    { "itemId": 17021, "name": "presto:MASK_HASH", "label": "Hash", "description": "Hash the value of a varchar with sha256", "transformer": "cast(to_hex(sha256(to_utf8({col}))) as {type})" },
+		    { "itemId": 17022, "name": "presto:MASK_NULL", "label": "Nullify", "description": "Replace with NULL" },
+		    { "itemId": 17023, "name": "presto:MASK_NONE", "label": "Unmasked (retain original value)", "description": "No masking" },
+		    { "itemId": 17029, "name": "presto:MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "date_trunc('year', {col})" },
+		    { "itemId": 17030, "name": "presto:CUSTOM", "label": "Custom", "description": "Custom" },
+		    { "itemId": 205206, "name": "nestedstructure:MASK", "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "mask({field})" },
+		    { "itemId": 205207, "name": "nestedstructure:MASK_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'x'", "transformer": "mask_show_last_n({field}, 4, 'x', 'x', 'x', -1, '1')" },
+		    { "itemId": 205208, "name": "nestedstructure:MASK_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "mask_show_first_n({field}, 4, 'x', 'x', 'x', -1, '1')" },
+		    { "itemId": 205209, "name": "nestedstructure:MASK_HASH", "label": "Hash", "description": "Hash the value", "transformer": "mask_hash({field})" },
+		    { "itemId": 205210, "name": "nestedstructure:MASK_NULL", "label": "Nullify", "description": "Replace with NULL" },
+		    { "itemId": 205211, "name": "nestedstructure:MASK_NONE", "label": "Unmasked (retain original value)", "description": "No masking" },
+		    { "itemId": 205217, "name": "nestedstructure:MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "mask({field}, 'x', 'x', 'x', -1, '1', 1, 0, -1)" },
+		    { "itemId": 205218, "name": "nestedstructure:CUSTOM", "label": "Custom", "description": "Custom" },
+		    { "itemId": 3004, "name": "hive:MASK", "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "mask({col})" },
+		    { "itemId": 3005, "name": "hive:MASK_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'x'", "transformer": "mask_show_last_n({col}, 4, 'x', 'x', 'x', -1, '1')" },
+		    { "itemId": 3006, "name": "hive:MASK_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "mask_show_first_n({col}, 4, 'x', 'x', 'x', -1, '1')" },
+		    { "itemId": 3007, "name": "hive:MASK_HASH", "label": "Hash", "description": "Hash the value", "transformer": "mask_hash({col})" },
+		    { "itemId": 3008, "name": "hive:MASK_NULL", "label": "Nullify", "description": "Replace with NULL" },
+		    { "itemId": 3009, "name": "hive:MASK_NONE", "label": "Unmasked (retain original value)", "description": "No masking" },
+		    { "itemId": 3015, "name": "hive:MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "mask({col}, 'x', 'x', 'x', -1, '1', 1, 0, -1)" },
+		    { "itemId": 3016, "name": "hive:CUSTOM", "label": "Custom", "description": "Custom" }
+		],
+		"accessTypes": [
+		    { "itemId": 203204, "name": "trino:select",         "label": "Select" },
+		    { "itemId": 17018,  "name": "presto:select",        "label": "Select" },
+		    { "itemId": 205206, "name": "nestedstructure:read", "label": "Read" },
+		    { "itemId": 3004,   "name": "hive:select",          "label": "select" }
+		],
+		"resources": [
+		    { "itemId": 1, "name": "tag", "type": "string", "level": 1, "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "__isValidLeaf": "true", "wildCard": "false", "__accessTypeRestrictions": "[]", "ignoreCase": "false" }, "uiHint": "{ \"singleValue\":true }", "label": "TAG", "description": "TAG", "isValidLeaf": true }
+		]
+	    },
+	    "rowFilterDef": {},
+	    "markerAccessTypes": [
+		{
+		    "itemId": 205213,
+		    "name": "_ALL",
+		    "label": "_ALL",
+		    "impliedGrants": [
+			"ozone:write_acl",
+			"kms:get",
+			"atlas:type-delete",
+			"atlas:entity-create",
+			"hbase:execute",
+			"storm:fileDownload",
+			"kms:getkeys",
+			"storm:getTopologyConf",
+			"ozone:create",
+			"hive:tempudfadmin",
+			"kafka:idempotent_write",
+			"hive:write",
+			"trino:use",
+			"trino:grant",
+			"hdfs:execute",
+			"elasticsearch:indices_index",
+			"atlas:admin-export",
+			"kafka:configure",
+			"atlas:entity-read",
+			"presto:alter",
+			"atlas:entity-update-classification",
+			"trino:select",
+			"presto:execute",
+			"kafka:describe",
+			"atlas:admin-purge",
+			"kafka:consume",
+			"trino:delete",
+			"atlas:add-relationship",
+			"elasticsearch:indices_bulk",
+			"trino:drop",
+			"kudu:select",
+			"presto:use",
+			"hive:serviceadmin",
+			"elasticsearch:create_index",
+			"hive:index",
+			"nestedstructure:read",
+			"kms:setkeymaterial",
+			"kylin:OPERATION",
+			"schema-registry:create",
+			"presto:impersonate",
+			"storm:deactivate",
+			"elasticsearch:index",
+			"kafka:alter",
+			"atlas:entity-add-classification",
+			"atlas:entity-remove-classification",
+			"atlas:entity-add-label",
+			"schema-registry:update",
+			"kafka:kafka_admin",
+			"presto:drop",
+			"hive:refresh",
+			"atlas:entity-delete",
+			"presto:all",
+			"atlas:entity-update",
+			"elasticsearch:monitor",
+			"trino:insert",
+			"kudu:update",
+			"schema-registry:read",
+			"atlas:admin-audits",
+			"elasticsearch:delete_index",
+			"presto:show",
+			"ozone:write",
+			"hive:read",
+			"ozone:all",
+			"atlas:entity-remove-label",
+			"trino:all",
+			"presto:grant",
+			"kms:rollover",
+			"elasticsearch:view_index_metadata",
+			"presto:create",
+			"kafka:publish",
+			"kafka:create",
+			"trino:execute",
+			"hive:all",
+			"kms:delete",
+			"kylin:ADMIN",
+			"atlas:remove-relationship",
+			"kylin:MANAGEMENT",
+			"storm:killTopology",
+			"elasticsearch:indices_put",
+			"kudu:create",
+			"hive:update",
+			"sqoop:READ",
+			"presto:delete",
+			"atlas:entity-update-business-metadata",
+			"yarn:submit-app",
+			"solr:update",
+			"trino:create",
+			"hdfs:read",
+			"elasticsearch:write",
+			"hive:alter",
+			"kafka:alter_configs",
+			"storm:getUserTopology",
+			"storm:uploadNewCredentials",
+			"presto:insert",
+			"atlas:type-update",
+			"storm:submitTopology",
+			"storm:activate",
+			"kms:generateeek",
+			"kafka:cluster_action",
+			"trino:impersonate",
+			"hdfs:write",
+			"hbase:admin",
+			"elasticsearch:create",
+			"atlas:admin-import",
+			"kms:decrypteek",
+			"solr:query",
+			"atlas:type-create",
+			"kudu:all",
+			"nifi:WRITE",
+			"sqoop:WRITE",
+			"storm:getTopologyInfo",
+			"storm:getTopology",
+			"hbase:read",
+			"kms:getmetadata",
+			"storm:fileUpload",
+			"trino:alter",
+			"hive:drop",
+			"hive:create",
+			"yarn:admin-queue",
+			"kafka:describe_configs",
+			"ozone:delete",
+			"nifi-registry:READ",
+			"hive:repladmin",
+			"kudu:metadata",
+			"schema-registry:delete",
+			"nifi-registry:DELETE",
+			"kms:create",
+			"ozone:read",
+			"trino:show",
+			"ozone:read_acl",
+			"nifi:READ",
+			"hive:select",
+			"kudu:delete",
+			"atlas:type-read",
+			"kafka:delete",
+			"kylin:QUERY",
+			"elasticsearch:indices_search_shards",
+			"elasticsearch:read_cross_cluster",
+			"elasticsearch:manage",
+			"presto:select",
+			"ozone:list",
+			"nestedstructure:write",
+			"atlas:update-relationship",
+			"trino:revoke",
+			"nifi-registry:WRITE",
+			"storm:rebalance",
+			"hive:lock",
+			"presto:revoke",
+			"knox:allow",
+			"hbase:create",
+			"elasticsearch:delete",
+			"kudu:drop",
+			"hbase:write",
+			"elasticsearch:read",
+			"kudu:alter",
+			"kudu:insert",
+			"elasticsearch:all"
+		    ]
+		}
+	    ]
+	},
+        "auditMode": "audit-default",
+        "serviceConfig": {
+            "ranger.plugin.audit.filters": "[ {'accessResult': 'DENIED', 'isAudited': true} ]"
+        }
+    },
+    "serviceConfig": {
+        "ranger.plugin.audit.filters": "[ {'accessResult': 'DENIED', 'isAudited': true}, {'actions':['METADATA OPERATION'], 'isAudited': false}, {'users':['hive','hue'],'actions':['SHOW_ROLES'],'isAudited':false} ]"
+    }
+}
diff --git a/intg/src/main/python/apache_ranger/model/ranger_service_def.py b/intg/src/main/python/apache_ranger/model/ranger_service_def.py
index 3fd90f706..b3aff1dce 100644
--- a/intg/src/main/python/apache_ranger/model/ranger_service_def.py
+++ b/intg/src/main/python/apache_ranger/model/ranger_service_def.py
@@ -27,34 +27,36 @@ class RangerServiceDef(RangerBaseModelObject):
 
         RangerBaseModelObject.__init__(self, attrs)
 
-        self.name             = attrs.get('name')
-        self.displayName      = attrs.get('displayName')
-        self.implClass        = attrs.get('implClass')
-        self.label            = attrs.get('label')
-        self.description      = attrs.get('description')
-        self.rbKeyLabel       = attrs.get('rbKeyLabel')
-        self.rbKeyDescription = attrs.get('rbKeyDescription')
-        self.options          = attrs.get('options')
-        self.configs          = attrs.get('configs')
-        self.resources        = attrs.get('resources')
-        self.accessTypes      = attrs.get('accessTypes')
-        self.policyConditions = attrs.get('policyConditions')
-        self.contextEnrichers = attrs.get('contextEnrichers')
-        self.enums            = attrs.get('enums')
-        self.dataMaskDef      = attrs.get('dataMaskDef')
-        self.rowFilterDef     = attrs.get('rowFilterDef')
+        self.name              = attrs.get('name')
+        self.displayName       = attrs.get('displayName')
+        self.implClass         = attrs.get('implClass')
+        self.label             = attrs.get('label')
+        self.description       = attrs.get('description')
+        self.rbKeyLabel        = attrs.get('rbKeyLabel')
+        self.rbKeyDescription  = attrs.get('rbKeyDescription')
+        self.options           = attrs.get('options')
+        self.configs           = attrs.get('configs')
+        self.resources         = attrs.get('resources')
+        self.accessTypes       = attrs.get('accessTypes')
+        self.policyConditions  = attrs.get('policyConditions')
+        self.contextEnrichers  = attrs.get('contextEnrichers')
+        self.enums             = attrs.get('enums')
+        self.dataMaskDef       = attrs.get('dataMaskDef')
+        self.rowFilterDef      = attrs.get('rowFilterDef')
+        self.markerAccessTypes = attrs.get('markerAccessTypes')
 
     def type_coerce_attrs(self):
         super(RangerServiceDef, self).type_coerce_attrs()
 
-        self.configs          = type_coerce_list(self.configs, RangerResourceDef)
-        self.resources        = type_coerce_list(self.resources, RangerResourceDef)
-        self.accessTypes      = type_coerce_list(self.accessTypes, RangerAccessTypeDef)
-        self.policyConditions = type_coerce_list(self.policyConditions, RangerPolicyConditionDef)
-        self.contextEnrichers = type_coerce_list(self.contextEnrichers, RangerContextEnricherDef)
-        self.enums            = type_coerce_list(self.enums, RangerEnumDef)
-        self.dataMaskDef      = type_coerce(self.dataMaskDef, RangerDataMaskDef)
-        self.rowFilterDef     = type_coerce(self.rowFilterDef, RangerRowFilterDef)
+        self.configs           = type_coerce_list(self.configs, RangerResourceDef)
+        self.resources         = type_coerce_list(self.resources, RangerResourceDef)
+        self.accessTypes       = type_coerce_list(self.accessTypes, RangerAccessTypeDef)
+        self.policyConditions  = type_coerce_list(self.policyConditions, RangerPolicyConditionDef)
+        self.contextEnrichers  = type_coerce_list(self.contextEnrichers, RangerContextEnricherDef)
+        self.enums             = type_coerce_list(self.enums, RangerEnumDef)
+        self.dataMaskDef       = type_coerce(self.dataMaskDef, RangerDataMaskDef)
+        self.rowFilterDef      = type_coerce(self.rowFilterDef, RangerRowFilterDef)
+        self.markerAccessTypes = type_coerce_list(self.markerAccessTypes, RangerAccessTypeDef)
 
 
 class RangerServiceConfigDef:
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
index 4581112fe..a49d0cd29 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
@@ -53,6 +53,7 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
 import org.apache.ranger.plugin.model.RangerRole;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
 import org.apache.ranger.service.RangerAuditFields;
 import org.apache.ranger.service.RangerServiceDefService;
 import org.apache.ranger.service.XGroupService;
@@ -227,6 +228,10 @@ public class PolicyRefUpdater {
 		}
 
 		List<XXPolicyRefAccessType> xPolAccesses = new ArrayList<>();
+
+		// ignore built-in access-types while creating ref-table entries
+		accessTypes.removeAll(ServiceDefUtil.ACCESS_TYPE_MARKERS);
+
 		for (String accessType : accessTypes) {
 			XXAccessTypeDef xAccTypeDef = daoMgr.getXXAccessTypeDef().findByNameAndServiceId(accessType, xPolicy.getService());
 
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 562467e80..0fc3b85ee 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -71,6 +71,7 @@ import org.apache.ranger.db.XXPolicyDao;
 import org.apache.ranger.entity.XXTagChangeLog;
 import org.apache.ranger.plugin.model.RangerSecurityZone;
 import org.apache.ranger.plugin.util.RangerCommonConstants;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
 import org.apache.ranger.plugin.util.ServiceTags;
 import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
 import org.apache.ranger.plugin.model.validation.RangerValidator;
@@ -2976,6 +2977,8 @@ public class ServiceDBStore extends AbstractServiceStore {
 				throw new Exception("service-def does not exist. id=" + tagServiceDbObj.getType());
 			}
 
+			ServiceDefUtil.normalizeAccessTypeDefs(tagServiceDef, serviceType);
+
 			tagServiceVersionInfoDbObj = daoMgr.getXXServiceVersionInfo().findByServiceId(serviceDbObj.getTagService());
 
 			if (tagServiceVersionInfoDbObj == null) {
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
index 91d5f26bc..bcaf70e2c 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
@@ -128,6 +128,8 @@ public abstract class RangerServiceDefServiceBase<T extends XXServiceDefBase, V
 			serviceDef.setAccessTypes(accessTypes);
 		}
 
+		serviceDef.setMarkerAccessTypes(ServiceDefUtil.getMarkerAccessTypes(serviceDef.getAccessTypes()));
+
 		List<XXPolicyConditionDef> xPolicyConditions = daoMgr.getXXPolicyConditionDef()
 				.findByServiceDefId(serviceDefId);
 		if (!stringUtil.isEmpty(xPolicyConditions)) {