You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by rm...@apache.org on 2020/12/01 22:13:04 UTC

[ranger] branch ranger-2.2 updated: RANGER-3000:Audit-filter feature implementation to help reduce volume of audit logs generated

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

rmani pushed a commit to branch ranger-2.2
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/ranger-2.2 by this push:
     new 75578f0   RANGER-3000:Audit-filter feature implementation to help reduce volume of audit logs generated
75578f0 is described below

commit 75578f0333cc8e1999704e3948715dba41309eb2
Author: Ramesh Mani <rm...@cloudera.com>
AuthorDate: Tue Dec 1 08:33:02 2020 -0800

     RANGER-3000:Audit-filter feature implementation to help reduce volume of audit logs generated
---
 .../ranger/authorization/utils/JsonUtils.java      |  12 +
 .../apache/ranger/plugin/model/AuditFilter.java    | 130 +++++++
 .../apache/ranger/plugin/model/RangerPolicy.java   |   1 +
 .../model/validation/RangerServiceDefHelper.java   |   4 +
 .../plugin/policyengine/RangerAccessResult.java    |   2 +-
 .../plugin/policyengine/RangerPolicyEngine.java    |   3 +
 .../policyengine/RangerPolicyEngineImpl.java       | 109 ++++++
 .../policyengine/RangerPolicyRepository.java       | 123 ++++++-
 .../RangerAuditPolicyEvaluator.java                | 405 +++++++++++++++++++++
 .../RangerDefaultPolicyEvaluator.java              |   6 +-
 .../RangerDefaultPolicyResourceMatcher.java        |   2 +-
 .../ranger/plugin/service/RangerBasePlugin.java    |  32 +-
 .../apache/ranger/plugin/util/ServicePolicies.java |  11 +
 .../plugin/policyengine/TestPolicyEngine.java      |  30 +-
 .../test_policyengine_audit_filter_hdfs.json       | 120 ++++++
 .../test_policyengine_audit_filter_hive.json       | 248 +++++++++++++
 .../java/org/apache/ranger/rest/ServiceREST.java   |  12 +
 17 files changed, 1226 insertions(+), 24 deletions(-)

diff --git a/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java b/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java
index 994d394..ee4cef6 100644
--- a/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java
+++ b/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java
@@ -25,6 +25,7 @@ import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.AuditFilter;
 import org.apache.ranger.plugin.model.RangerValidityRecurrence;
 import org.apache.ranger.plugin.model.RangerValiditySchedule;
 
@@ -117,6 +118,17 @@ public class JsonUtils {
             return null;
         }
     }
+
+    public static List<AuditFilter> jsonToAuditFilterList(String jsonStr) {
+        try {
+            Type listType = new TypeToken<List<AuditFilter>>() {}.getType();
+            return gson.fromJson(jsonStr, listType);
+        } catch (Exception e) {
+            LOG.error("failed to create audit filters from: " + jsonStr, e);
+            return null;
+        }
+    }
+
     public static List<RangerValidityRecurrence> jsonToRangerValidityRecurringSchedule(String jsonStr) {
         try {
             Type listType = new TypeToken<List<RangerValidityRecurrence>>() {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/AuditFilter.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/AuditFilter.java
new file mode 100644
index 0000000..b437e14
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/AuditFilter.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.model;
+
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+@JsonAutoDetect(fieldVisibility=Visibility.ANY)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class AuditFilter {
+    public enum AccessResult { DENIED, ALLOWED, NOT_DETERMINED }
+
+    private AccessResult                      accessResult;
+    private Map<String, RangerPolicyResource> resources;
+    private List<String>                      accessTypes;
+    private List<String>                      actions;
+    private List<String>                      users;
+    private List<String>                      groups;
+    private List<String>                      roles;
+    private Boolean                           isAudited;
+
+    public AuditFilter() { }
+
+    public AccessResult getAccessResult() {
+        return accessResult;
+    }
+
+    public void setAccessResult(AccessResult accessResult) {
+        this.accessResult = accessResult;
+    }
+
+    public Map<String, RangerPolicyResource> getResources() {
+        return resources;
+    }
+
+    public void setResources(Map<String, RangerPolicyResource> resources) {
+        this.resources = resources;
+    }
+
+    public List<String> getAccessTypes() {
+        return accessTypes;
+    }
+
+    public void setAccessTypes(List<String> accessTypes) {
+        this.accessTypes = accessTypes;
+    }
+
+    public List<String> getActions() {
+        return actions;
+    }
+
+    public void setActions(List<String> actions) {
+        this.actions = actions;
+    }
+
+    public List<String> getUsers() {
+        return users;
+    }
+
+    public void setUsers(List<String> users) {
+        this.users = users;
+    }
+
+    public List<String> getGroups() {
+        return groups;
+    }
+
+    public void setGroups(List<String> groups) {
+        this.groups = groups;
+    }
+
+    public List<String> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(List<String> roles) {
+        this.roles = roles;
+    }
+
+    public Boolean getIsAudited() {
+        return isAudited;
+    }
+
+    public void setAction(Boolean isAudited) {
+        this.isAudited = isAudited;
+    }
+
+    @Override
+    public String toString() {
+        return "{accessResult=" + accessResult
+                + ", resources=" + resources
+                + ", accessTypes=" + accessTypes
+                + ", actions=" + actions
+                + ", users=" + users
+                + ", groups=" + groups
+                + ", roles=" + roles
+                + ", isAudited=" + isAudited
+                + "}";
+    }
+}
\ No newline at end of file
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
index 04c6e75..6444fe9 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
@@ -45,6 +45,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 	public static final int POLICY_TYPE_ACCESS    = 0;
 	public static final int POLICY_TYPE_DATAMASK  = 1;
 	public static final int POLICY_TYPE_ROWFILTER = 2;
+	public static final int POLICY_TYPE_AUDIT     = 3;
 
 	public static final int[] POLICY_TYPES = new int[] {
 			POLICY_TYPE_ACCESS,
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 0d9a346..bbcf82f 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
@@ -206,6 +206,10 @@ public class RangerServiceDefHelper {
 
 		Set<List<RangerResourceDef>> ret = new HashSet<List<RangerResourceDef>>();
 
+		if (policyType == RangerPolicy.POLICY_TYPE_AUDIT) {
+			policyType = RangerPolicy.POLICY_TYPE_ACCESS;
+		}
+
 		for (List<RangerResourceDef> hierarchy : getResourceHierarchies(policyType)) {
 			if (hierarchyHasAllResources(hierarchy, keys)) {
 				ret.add(hierarchy);
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
index c54ef17..407e3e7 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
@@ -155,7 +155,7 @@ public class RangerAccessResult {
 
 	public boolean getIsAuditedDetermined() { return isAuditedDetermined; }
 
-	private void setIsAuditedDetermined(boolean value) { isAuditedDetermined = value; }
+	public void setIsAuditedDetermined(boolean value) { isAuditedDetermined = value; }
 	
 	/**
 	 * @return the isAudited
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
index 4e41adc..71f8dae 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
@@ -44,6 +44,7 @@ public interface RangerPolicyEngine {
 	String PLUGIN_AUDIT_EXCLUDE_ROLES  = "ranger.plugin.audit.exclude.roles";
 	String PLUGIN_SUPER_USERS          = "ranger.plugin.super.users";
 	String PLUGIN_SUPER_GROUPS         = "ranger.plugin.super.groups";
+	String PLUGIN_AUDIT_FILTER         = "ranger.plugin.audit.filters";
 
 	String USER_CURRENT   = "{" + RangerAccessRequestUtil.KEY_USER + "}";
 	String RESOURCE_OWNER = "{OWNER}";
@@ -64,6 +65,8 @@ public interface RangerPolicyEngine {
 
 	Collection<RangerAccessResult> evaluatePolicies(Collection<RangerAccessRequest> requests, int policyType, RangerAccessResultProcessor resultProcessor);
 
+	void evaluateAuditPolicies(RangerAccessResult result);
+
 	RangerResourceACLs getResourceACLs(RangerAccessRequest request);
 
 	Set<String> getRolesFromUserAndGroups(String user, Set<String> groups);
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index b66d5a1..940cc65 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -162,6 +162,41 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 	}
 
 	@Override
+	public void evaluateAuditPolicies(RangerAccessResult result) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerPolicyEngineImpl.evaluateAuditPolicies(result=" + result + ")");
+		}
+
+		RangerPolicyRepository tagPolicyRepository      = policyEngine.getTagPolicyRepository();
+		RangerPolicyRepository policyRepository         = policyEngine.getPolicyRepository();
+		RangerAccessRequest    request                  = result.getAccessRequest();
+		boolean                savedIsAuditedDetermined = result.getIsAuditedDetermined();
+		boolean                savedIsAudited           = result.getIsAudited();
+
+		result.setIsAudited(false);
+		result.setIsAuditedDetermined(false);
+
+		try {
+			if (tagPolicyRepository != null) {
+				evaluateTagAuditPolicies(request, result, tagPolicyRepository);
+			}
+
+			if (!result.getIsAuditedDetermined() && policyRepository != null) {
+				evaluateResourceAuditPolicies(request, result, policyRepository);
+			}
+		} finally {
+			if (!result.getIsAuditedDetermined()) {
+				result.setIsAudited(savedIsAudited);
+				result.setIsAuditedDetermined(savedIsAuditedDetermined);
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerPolicyEngineImpl.evaluateAuditPolicies(result=" + result + ")");
+		}
+	}
+
+	@Override
 	public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("==> RangerPolicyEngineImpl.getResourceACLs(request=" + request + ")");
@@ -861,6 +896,80 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 		}
 	}
 
+	private void evaluateTagAuditPolicies(RangerAccessRequest request, RangerAccessResult result, RangerPolicyRepository tagPolicyRepository) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerPolicyEngineImpl.evaluateTagAuditPolicies(request=" + request + ", result=" + result + ")");
+		}
+
+		Set<RangerTagForEval> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
+
+		if (CollectionUtils.isNotEmpty(tags)) {
+			Date                        accessTime = request.getAccessTime() != null ? request.getAccessTime() : new Date();
+			List<PolicyEvaluatorForTag> evaluators = tagPolicyRepository.getLikelyMatchPolicyEvaluators(tags, RangerPolicy.POLICY_TYPE_AUDIT, accessTime);
+
+			if (CollectionUtils.isNotEmpty(evaluators)) {
+				for (PolicyEvaluatorForTag policyEvaluator : evaluators) {
+					RangerPolicyEvaluator evaluator      = policyEvaluator.getEvaluator();
+					RangerTagForEval      tag            = policyEvaluator.getTag();
+					RangerAccessRequest   tagEvalRequest = new RangerTagAccessRequest(tag, tagPolicyRepository.getServiceDef(), request);
+					RangerAccessResult    tagEvalResult  = createAccessResult(tagEvalRequest, RangerPolicy.POLICY_TYPE_AUDIT);
+
+					if (LOG.isDebugEnabled()) {
+						LOG.debug("RangerPolicyEngineImpl.evaluateTagAuditPolicies: Evaluating Audit policies for tag (" + tag.getType() + ")" + "Tag Evaluator: " + policyEvaluator);
+					}
+
+					tagEvalResult.setAccessResultFrom(result);
+
+					result.incrementEvaluatedPoliciesCount();
+
+					evaluator.evaluate(tagEvalRequest, tagEvalResult);
+
+					if (tagEvalResult.getIsAuditedDetermined()) {
+						result.setIsAudited(tagEvalResult.getIsAudited());
+						break;
+					}
+				}
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerPolicyEngineImpl.evaluateTagAuditPolicies(request=" + request + ", result=" + result + ")");
+		}
+	}
+
+	private boolean evaluateResourceAuditPolicies(RangerAccessRequest request, RangerAccessResult result, RangerPolicyRepository policyRepository) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerPolicyEngineImpl.evaluateResourceAuditPolicies(request=" + request + ", result=" + result + ")");
+		}
+
+		boolean                     ret        = false;
+		List<RangerPolicyEvaluator> evaluators = policyRepository.getLikelyMatchAuditPolicyEvaluators(request.getResource());
+
+		if (CollectionUtils.isNotEmpty(evaluators)) {
+			for (RangerPolicyEvaluator evaluator : evaluators) {
+				if (LOG.isDebugEnabled()) {
+					LOG.debug("==> RangerPolicyEngineImpl.evaluateResourceAuditPolicies(): Evaluating RangerPolicyEvaluator...: " + evaluator);
+				}
+
+				result.incrementEvaluatedPoliciesCount();
+
+				evaluator.evaluate(request, result);
+
+				if (result.getIsAuditedDetermined()) {
+					ret = true;
+
+					break;
+				}
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerPolicyEngineImpl.evaluateResourceAuditPolicies(request=" + request + ", result=" + result + "): ret=" + ret);
+		}
+
+		return ret;
+	}
+
 	private static class ServiceConfig {
 		private final Set<String> auditExcludedUsers;
 		private final Set<String> auditExcludedGroups;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
index 169ed0f..0d6074f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
@@ -23,16 +23,19 @@ import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.authorization.utils.JsonUtils;
 import org.apache.ranger.plugin.contextenricher.RangerAbstractContextEnricher;
 import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
 import org.apache.ranger.plugin.contextenricher.RangerTagEnricher;
 import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
+import org.apache.ranger.plugin.model.AuditFilter;
 import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
 import org.apache.ranger.plugin.model.RangerPolicyDelta;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
 import org.apache.ranger.plugin.policyevaluator.RangerAbstractPolicyEvaluator;
+import org.apache.ranger.plugin.policyevaluator.RangerAuditPolicyEvaluator;
 import org.apache.ranger.plugin.policyevaluator.RangerCachedPolicyEvaluator;
 import org.apache.ranger.plugin.policyevaluator.RangerOptimizedPolicyEvaluator;
 import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
@@ -52,6 +55,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static org.apache.ranger.plugin.policyengine.RangerPolicyEngine.PLUGIN_AUDIT_FILTER;
+
 public class RangerPolicyRepository {
     private static final Log LOG = LogFactory.getLog(RangerPolicyRepository.class);
 
@@ -78,9 +83,11 @@ public class RangerPolicyRepository {
     private final Map<String, RangerResourceTrie>   policyResourceTrie;
     private final Map<String, RangerResourceTrie>   dataMaskResourceTrie;
     private final Map<String, RangerResourceTrie>   rowFilterResourceTrie;
+    private final Map<String, RangerResourceTrie>   auditFilterResourceTrie;
     private       List<RangerPolicyEvaluator>       policyEvaluators;
     private       List<RangerPolicyEvaluator>       dataMaskPolicyEvaluators;
     private       List<RangerPolicyEvaluator>       rowFilterPolicyEvaluators;
+    private final List<RangerPolicyEvaluator>       auditPolicyEvaluators;
     private       Map<Long, RangerPolicyEvaluator>  policyEvaluatorsMap;
     private       boolean                           isContextEnrichersShared = false;
     private       boolean                           isPreCleaned             = false;
@@ -96,6 +103,7 @@ public class RangerPolicyRepository {
         this.policyEvaluators          = new ArrayList<>(other.policyEvaluators);
         this.dataMaskPolicyEvaluators  = new ArrayList<>(other.dataMaskPolicyEvaluators);
         this.rowFilterPolicyEvaluators = new ArrayList<>(other.rowFilterPolicyEvaluators);
+        this.auditPolicyEvaluators     = new ArrayList<>(other.auditPolicyEvaluators);
         this.auditModeEnum             = other.auditModeEnum;
         this.componentServiceName      = other.componentServiceName;
         this.componentServiceDef       = other.componentServiceDef;
@@ -131,6 +139,16 @@ public class RangerPolicyRepository {
             this.rowFilterResourceTrie = null;
         }
 
+        if (other.auditFilterResourceTrie != null) {
+            this.auditFilterResourceTrie = new HashMap<>();
+
+            for (Map.Entry<String, RangerResourceTrie> entry : other.auditFilterResourceTrie.entrySet()) {
+                auditFilterResourceTrie.put(entry.getKey(), new RangerResourceTrie(entry.getValue()));
+            }
+        } else {
+            this.auditFilterResourceTrie = null;
+        }
+
         if (other.accessAuditCache != null) {
             int auditResultCacheSize = other.accessAuditCache.size();
 
@@ -224,6 +242,12 @@ public class RangerPolicyRepository {
             }
         }
 
+        if (auditFilterResourceTrie != null) {
+            for (Map.Entry<String, RangerResourceTrie> entry : auditFilterResourceTrie.entrySet()) {
+                entry.getValue().wrapUpUpdate();
+            }
+        }
+
         if (StringUtils.isEmpty(zoneName)) {
             if (CollectionUtils.isNotEmpty(other.getPolicies())) {
                 if (CollectionUtils.isNotEmpty(this.getPolicies())) {
@@ -303,18 +327,22 @@ public class RangerPolicyRepository {
 
         if (StringUtils.isEmpty(zoneName)) {
             this.contextEnrichers = Collections.unmodifiableList(buildContextEnrichers(options));
+            this.auditPolicyEvaluators = buildAuditPolicyEvaluators(servicePolicies.getServiceConfig());
         } else {
             this.contextEnrichers = null;
+            this.auditPolicyEvaluators = Collections.emptyList();
         }
 
         if (options.disableTrieLookupPrefilter) {
-            policyResourceTrie    = null;
-            dataMaskResourceTrie  = null;
-            rowFilterResourceTrie = null;
+            policyResourceTrie      = null;
+            dataMaskResourceTrie    = null;
+            rowFilterResourceTrie   = null;
+            auditFilterResourceTrie = null;
         } else {
-            policyResourceTrie    = createResourceTrieMap(policyEvaluators, options.optimizeTrieForRetrieval);
-            dataMaskResourceTrie  = createResourceTrieMap(dataMaskPolicyEvaluators, options.optimizeTrieForRetrieval);
-            rowFilterResourceTrie = createResourceTrieMap(rowFilterPolicyEvaluators, options.optimizeTrieForRetrieval);
+            policyResourceTrie      = createResourceTrieMap(policyEvaluators, options.optimizeTrieForRetrieval);
+            dataMaskResourceTrie    = createResourceTrieMap(dataMaskPolicyEvaluators, options.optimizeTrieForRetrieval);
+            rowFilterResourceTrie   = createResourceTrieMap(rowFilterPolicyEvaluators, options.optimizeTrieForRetrieval);
+            auditFilterResourceTrie = createResourceTrieMap(auditPolicyEvaluators, options.optimizeTrieForRetrieval);
         }
     }
 
@@ -353,19 +381,50 @@ public class RangerPolicyRepository {
 
         if (StringUtils.isEmpty(zoneName)) {
             this.contextEnrichers = Collections.unmodifiableList(buildContextEnrichers(options));
+            this.auditPolicyEvaluators = buildAuditPolicyEvaluators(tagPolicies.getServiceConfig());
         } else {
             this.contextEnrichers = null;
+            this.auditPolicyEvaluators = Collections.emptyList();
         }
 
         if (options.disableTrieLookupPrefilter) {
-            policyResourceTrie    = null;
-            dataMaskResourceTrie  = null;
-            rowFilterResourceTrie = null;
+            policyResourceTrie      = null;
+            dataMaskResourceTrie    = null;
+            rowFilterResourceTrie   = null;
+            auditFilterResourceTrie = null;
         } else {
-            policyResourceTrie    = createResourceTrieMap(policyEvaluators, options.optimizeTrieForRetrieval);
-            dataMaskResourceTrie  = createResourceTrieMap(dataMaskPolicyEvaluators, options.optimizeTrieForRetrieval);
-            rowFilterResourceTrie = createResourceTrieMap(rowFilterPolicyEvaluators, options.optimizeTrieForRetrieval);
+            policyResourceTrie      = createResourceTrieMap(policyEvaluators, options.optimizeTrieForRetrieval);
+            dataMaskResourceTrie    = createResourceTrieMap(dataMaskPolicyEvaluators, options.optimizeTrieForRetrieval);
+            rowFilterResourceTrie   = createResourceTrieMap(rowFilterPolicyEvaluators, options.optimizeTrieForRetrieval);
+            auditFilterResourceTrie = createResourceTrieMap(auditPolicyEvaluators, options.optimizeTrieForRetrieval);
+        }
+    }
+
+    private List<RangerPolicyEvaluator> buildAuditPolicyEvaluators(Map<String, String> svcConfigs) {
+        List<RangerPolicyEvaluator> ret     = Collections.emptyList();
+        String                      jsonStr = svcConfigs != null ? svcConfigs.get(PLUGIN_AUDIT_FILTER) : null;
+
+        if (StringUtils.isNotBlank(jsonStr)) {
+            List<AuditFilter> auditFilters = JsonUtils.jsonToAuditFilterList(jsonStr);
+            int               filterCount  = auditFilters != null ? auditFilters.size() : 0;
+
+            if (filterCount > 0) {
+                ret = new ArrayList<>(filterCount);
+
+                // set priority so that policies will be evaluated in the same order as in the list
+                int policyPriority = filterCount;
+
+                for (AuditFilter auditFilter : auditFilters) {
+                    RangerAuditPolicyEvaluator evaluator = new RangerAuditPolicyEvaluator(auditFilter, policyPriority--);
+
+                    evaluator.init(evaluator.getAuditPolicy(), serviceDef, options);
+
+                    ret.add(evaluator);
+                }
+            }
         }
+
+        return ret;
     }
 
     @Override
@@ -419,6 +478,16 @@ public class RangerPolicyRepository {
         }
         sb.append("} ");
 
+        sb.append("auditPolicyEvaluators={");
+        if (this.auditPolicyEvaluators != null) {
+            for (RangerPolicyEvaluator policyEvaluator : auditPolicyEvaluators) {
+                if (policyEvaluator != null) {
+                    sb.append(policyEvaluator).append(" ");
+                }
+            }
+        }
+        sb.append("} ");
+
         sb.append("contextEnrichers={");
         if (contextEnrichers != null) {
             for (RangerContextEnricher contextEnricher : contextEnrichers) {
@@ -599,6 +668,10 @@ public class RangerPolicyRepository {
 	    return rowFilterPolicyEvaluators;
     }
 
+    List<RangerPolicyEvaluator> getAuditPolicyEvaluators() {
+        return auditPolicyEvaluators;
+    }
+
     String getAppId() { return appId; }
 
     RangerPolicyEngineOptions getOptions() { return options; }
@@ -632,6 +705,7 @@ public class RangerPolicyRepository {
             if (CollectionUtils.isNotEmpty(ret)) {
                 switch (policyType) {
                     case RangerPolicy.POLICY_TYPE_ACCESS:
+                    case RangerPolicy.POLICY_TYPE_AUDIT:
                         Collections.sort(ret, PolicyEvaluatorForTag.EVAL_ORDER_COMPARATOR);
                         break;
                     case RangerPolicy.POLICY_TYPE_DATAMASK:
@@ -669,6 +743,8 @@ public class RangerPolicyRepository {
                 return getLikelyMatchDataMaskPolicyEvaluators(resource);
             case RangerPolicy.POLICY_TYPE_ROWFILTER:
                 return getLikelyMatchRowFilterPolicyEvaluators(resource);
+            case RangerPolicy.POLICY_TYPE_AUDIT:
+                return getLikelyMatchAuditPolicyEvaluators(resource);
             default:
                 return Collections.EMPTY_LIST;
         }
@@ -699,6 +775,12 @@ public class RangerPolicyRepository {
         return rowFilterResourceTrie == null || StringUtils.isEmpty(resourceStr)  ? getRowFilterPolicyEvaluators() : getLikelyMatchPolicyEvaluators(rowFilterResourceTrie, resource);
     }
 
+    List<RangerPolicyEvaluator> getLikelyMatchAuditPolicyEvaluators(RangerAccessResource resource) {
+        String resourceStr = resource == null ? null : resource.getAsString();
+
+        return auditFilterResourceTrie == null || StringUtils.isEmpty(resourceStr)  ? getAuditPolicyEvaluators() : getLikelyMatchPolicyEvaluators(auditFilterResourceTrie, resource);
+    }
+
     private List<RangerPolicyEvaluator> getLikelyMatchPolicyEvaluators(Map<String, RangerResourceTrie> resourceTrie, RangerAccessResource resource) {
         List<RangerPolicyEvaluator> ret          = Collections.EMPTY_LIST;
 
@@ -989,6 +1071,14 @@ public class RangerPolicyRepository {
 
                 LOG.debug("rowFilter policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder());
             }
+
+            LOG.debug("audit policy evaluation order: " + this.auditPolicyEvaluators.size() + " policies");
+            order = 0;
+            for(RangerPolicyEvaluator policyEvaluator : this.auditPolicyEvaluators) {
+                RangerPolicy policy = policyEvaluator.getPolicy();
+
+                LOG.debug("rowFilter policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder());
+            }
         }
     }
 
@@ -1171,7 +1261,7 @@ public class RangerPolicyRepository {
         return ret;
     }
 
-    private Map<String, RangerResourceTrie> createResourceTrieMap(List<RangerPolicyEvaluator> evaluators, boolean optimizeTrieForRetrieval) {
+    private Map<String, RangerResourceTrie> createResourceTrieMap(List<? extends RangerPolicyEvaluator> evaluators, boolean optimizeTrieForRetrieval) {
         final Map<String, RangerResourceTrie> ret;
 
         if (serviceDef != null && CollectionUtils.isNotEmpty(serviceDef.getResources())) {
@@ -1278,7 +1368,9 @@ public class RangerPolicyRepository {
                         LOG.warn("RangerPolicyEngine: ignoring policy id=" + policy.getId() + " - invalid policyType '" + policy.getPolicyType() + "'");
                     }
 
-                    policyEvaluatorsMap.put(policy.getId(), ret);
+                    if (policy.getPolicyType() != RangerPolicy.POLICY_TYPE_AUDIT) {
+                        policyEvaluatorsMap.put(policy.getId(), ret);
+                    }
                 }
             }
         }
@@ -1401,6 +1493,9 @@ public class RangerPolicyRepository {
             case RangerPolicy.POLICY_TYPE_ROWFILTER:
                 ret = rowFilterResourceTrie;
                 break;
+            case RangerPolicy.POLICY_TYPE_AUDIT:
+                ret = auditFilterResourceTrie;
+                break;
             default:
                 ret = null;
         }
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
new file mode 100644
index 0000000..7e1b3b4
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
@@ -0,0 +1,405 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.policyevaluator;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.AuditFilter;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.policyengine.*;
+import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+public class RangerAuditPolicyEvaluator extends RangerDefaultPolicyEvaluator {
+    private static final Log LOG = LogFactory.getLog(RangerAuditPolicyEvaluator.class);
+
+    private final RangerAuditPolicy                    auditPolicy;
+    private final boolean                              matchAnyResource;
+    private final List<RangerAuditPolicyItemEvaluator> auditItemEvaluators = new ArrayList<>();
+
+    public RangerAuditPolicyEvaluator(AuditFilter auditFilter, int priority) {
+        this.auditPolicy      = new RangerAuditPolicy(auditFilter, priority);
+        this.matchAnyResource = MapUtils.isEmpty(auditFilter.getResources());
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("RangerAuditPolicyEvaluator(auditFilter=" + auditFilter + ", priority=" + priority + ", matchAnyResource=" + matchAnyResource + ")");
+        }
+    }
+
+    public RangerAuditPolicy getAuditPolicy() { return auditPolicy; }
+
+    @Override
+    public void init(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerAuditPolicyEvaluator.init(" + auditPolicy.getId() + ")");
+        }
+
+        super.init(auditPolicy, serviceDef, options);
+
+        int policyItemIndex = 1;
+
+        for (RangerAuditPolicyItem policyItem : auditPolicy.getAuditPolicyItems()) {
+            RangerAuditPolicyItemEvaluator itemEvaluator = new RangerAuditPolicyItemEvaluator(serviceDef, auditPolicy, policyItem, policyItemIndex, options);
+            auditItemEvaluators.add(itemEvaluator);
+            policyItemIndex = policyItemIndex + 1;
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerAuditPolicyEvaluator.init(" + auditPolicy.getId() + ")");
+        }
+    }
+
+    @Override
+    public boolean isAncestorOf(RangerResourceDef resourceDef) {
+        return matchAnyResource ? true : super.isAncestorOf(resourceDef);
+    }
+
+    @Override
+    public void evaluate(RangerAccessRequest request, RangerAccessResult result) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerAuditPolicyEvaluator.evaluate(" + auditPolicy.getId() + ", " + request + ", " + result + ")");
+        }
+
+        if (request != null && result != null) {
+            if (!result.getIsAuditedDetermined()) {
+                if (matchResource(request)) {
+                    evaluatePolicyItems(request, result);
+                }
+            }
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerAuditPolicyEvaluator.evaluate(" + auditPolicy.getId() + ", " + request + ", " + result + ")");
+        }
+    }
+
+    @Override
+    protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
+        super.preprocessPolicy(policy, serviceDef);
+
+        Map<String, Collection<String>> impliedAccessGrants = getImpliedAccessGrants(serviceDef);
+
+        if(impliedAccessGrants == null || impliedAccessGrants.isEmpty()) {
+            return;
+        }
+
+        preprocessPolicyItems(auditPolicy.getAuditPolicyItems(), impliedAccessGrants);
+    }
+
+    private boolean matchResource(RangerAccessRequest request) {
+        final boolean ret;
+
+        if (!matchAnyResource) {
+            RangerPolicyResourceMatcher.MatchType matchType;
+
+            if (RangerTagAccessRequest.class.isInstance(request)) {
+                matchType = ((RangerTagAccessRequest) request).getMatchType();
+
+                if (matchType == RangerPolicyResourceMatcher.MatchType.ANCESTOR) {
+                    matchType = RangerPolicyResourceMatcher.MatchType.SELF;
+                }
+            } else {
+                RangerPolicyResourceMatcher resourceMatcher = getPolicyResourceMatcher();
+
+                if (resourceMatcher != null) {
+                    matchType = resourceMatcher.getMatchType(request.getResource(), request.getContext());
+                } else {
+                    matchType = RangerPolicyResourceMatcher.MatchType.NONE;
+                }
+            }
+
+            if (request.isAccessTypeAny()) {
+                ret = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
+            } else if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+                ret = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
+            } else {
+                ret = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS;
+            }
+        } else {
+            ret = true;
+        }
+
+        return ret;
+    }
+
+    private void evaluatePolicyItems(RangerAccessRequest request, RangerAccessResult result) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerAuditPolicyEvaluator.evaluatePolicyItems(" + auditPolicy.getId() + ", " + request + ", " + result + ")");
+        }
+
+        for (RangerAuditPolicyItemEvaluator itemEvaluator : auditItemEvaluators) {
+           if (itemEvaluator.isMatch(request, result)) {
+               Boolean isAudited = itemEvaluator.getIsAudited();
+
+               if (isAudited != null) {
+                   result.setIsAudited(isAudited);
+
+                   break;
+               }
+           }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerAuditPolicyEvaluator.evaluatePolicyItems(" + auditPolicy.getId() + ", " + request + ", " + result + ")");
+        }
+    }
+
+    @Override
+    public StringBuilder toString(StringBuilder sb) {
+        sb.append("RangerAuditPolicyEvaluator={");
+
+        super.toString(sb);
+
+        sb.append("auditPolicy={");
+        auditPolicy.toString(sb);
+        sb.append("}");
+
+        sb.append(" matchAnyResource={").append(matchAnyResource).append("}");
+
+        sb.append("}");
+
+        return sb;
+    }
+
+
+    public static class RangerAuditPolicyItemEvaluator extends RangerDefaultPolicyItemEvaluator {
+        private final RangerAuditPolicyItem auditPolicyItem;
+        private final boolean               matchAnyResult;
+        private final boolean               matchAnyUser;
+        private final boolean               matchAnyAction;
+        private final boolean               hasResourceOwner;
+
+        public RangerAuditPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerAuditPolicyItem policyItem, int policyItemIndex, RangerPolicyEngineOptions options) {
+            super(serviceDef, policy, policyItem, POLICY_ITEM_TYPE_ALLOW, policyItemIndex, options);
+
+            this.auditPolicyItem  = policyItem;
+            this.matchAnyResult   = policyItem.getAccessResult() == null;
+
+            List<String> users    = policyItem.getUsers();
+            List<String> groups   = policyItem.getGroups();
+            List<String> roles    = policyItem.getRoles();
+            this.matchAnyUser     = (CollectionUtils.isEmpty(users) && CollectionUtils.isEmpty(groups) && CollectionUtils.isEmpty(roles)) ||
+                                    (CollectionUtils.isNotEmpty(groups) && groups.contains(RangerPolicyEngine.GROUP_PUBLIC)) ||
+                                    (CollectionUtils.isNotEmpty(users) && users.contains(RangerPolicyEngine.USER_CURRENT));
+            this.matchAnyAction   = policyItem.getActions().isEmpty() && policyItem.getAccessTypes().isEmpty();
+            this.hasResourceOwner = CollectionUtils.isNotEmpty(users) && users.contains(RangerPolicyEngine.RESOURCE_OWNER);
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("RangerAuditPolicyItemEvaluator(" + auditPolicyItem + ", matchAnyUser=" + matchAnyUser + ", matchAnyAction=" + matchAnyAction + ", hasResourceOwner=" + hasResourceOwner + ")");
+            }
+        }
+
+        public Boolean getIsAudited() { return auditPolicyItem.getIsAudited(); }
+
+        public boolean isMatch(RangerAccessRequest request, RangerAccessResult result) {
+            boolean ret = matchAccessResult(result) &&
+                          matchUserGroupRole(request) &&
+                          matchAction(request);
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("RangerAuditPolicyItemEvaluator.isMatch(" + request + ", " + result + "): ret=" + ret);
+            }
+
+            return ret;
+        }
+
+        private boolean matchAccessResult(RangerAccessResult result) {
+            boolean ret = matchAnyResult;
+
+            if (!ret) {
+                switch (auditPolicyItem.getAccessResult()) {
+                    case DENIED:
+                        ret = result.getIsAccessDetermined() && !result.getIsAllowed();
+                        break;
+
+                    case ALLOWED:
+                        ret = result.getIsAccessDetermined() && result.getIsAllowed();
+                        break;
+
+                    case NOT_DETERMINED:
+                        ret = !result.getIsAccessDetermined();
+                        break;
+                }
+            }
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("RangerAuditPolicyItemEvaluator.matchAccessResult(" + result + "): ret=" + ret);
+            }
+
+            return ret;
+        }
+
+        private boolean matchUserGroupRole(RangerAccessRequest request) {
+            boolean ret = matchAnyUser;
+
+            if (!ret) {
+
+                if (auditPolicyItem.getUsers() != null && request.getUser() != null) {
+                   ret = auditPolicyItem.getUsers().contains(request.getUser());
+
+                   if (!ret && hasResourceOwner) {
+                        String owner = request.getResource() != null ? request.getResource().getOwnerUser() : null;
+                        ret = request.getUser().equals(owner);
+                   }
+                }
+
+                if (!ret && auditPolicyItem.getGroups() != null && request.getUserGroups() != null) {
+                    ret = CollectionUtils.containsAny(auditPolicyItem.getGroups(), request.getUserGroups());
+                }
+
+                if (!ret && auditPolicyItem.getRoles() != null) {
+                    ret = CollectionUtils.containsAny(auditPolicyItem.getRoles(), RangerAccessRequestUtil.getCurrentUserRolesFromContext(request.getContext()));
+                }
+            }
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("RangerAuditPolicyItemEvaluator.matchUserGroupRole(" + request + "): ret=" + ret);
+            }
+
+            return ret;
+        }
+
+        private boolean matchAction(RangerAccessRequest request) {
+            boolean ret = matchAnyAction;
+
+            if (!ret) {
+                if (request.getAction() != null) {
+                    ret = auditPolicyItem.getActions().contains(request.getAction());
+                }
+
+                if (!ret && request.getAccessType() != null) {
+                    ret = auditPolicyItem.getAccessTypes().contains(request.getAccessType());
+                }
+            }
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("RangerAuditPolicyItemEvaluator.matchAction(" + request + "): ret=" + ret);
+            }
+
+            return ret;
+        }
+    }
+
+    public static class RangerAuditPolicy extends RangerPolicy {
+        private final List<RangerAuditPolicyItem> auditPolicyItems;
+
+        public RangerAuditPolicy(AuditFilter auditFilter, int priority) {
+            setId((long)priority);
+            setResources(auditFilter.getResources());
+            setPolicyType(POLICY_TYPE_AUDIT);
+            setPolicyPriority(priority);
+
+            this.auditPolicyItems = Collections.singletonList(new RangerAuditPolicyItem(auditFilter));
+        }
+
+        public List<RangerAuditPolicyItem> getAuditPolicyItems() { return auditPolicyItems; }
+    }
+
+    public static class RangerAuditPolicyItem extends RangerPolicyItem {
+        private final AuditFilter.AccessResult accessResult;
+        private final Set<String>              actions;
+        private final Set<String>              accessTypes;
+        private final Boolean                  isAudited;
+
+        public RangerAuditPolicyItem(AuditFilter auditFilter) {
+            super(getPolicyItemAccesses(auditFilter.getAccessTypes()), auditFilter.getUsers(), auditFilter.getGroups(), auditFilter.getRoles(), null, null);
+
+            this.accessResult = auditFilter.getAccessResult();
+            this.actions      = auditFilter.getActions() != null ? new HashSet<>(auditFilter.getActions()) : Collections.emptySet();
+            this.accessTypes  = auditFilter.getAccessTypes() != null ? new HashSet<>(auditFilter.getAccessTypes()) : Collections.emptySet();
+            this.isAudited    = auditFilter.getIsAudited();
+        }
+
+        public Set<String> getActions() { return actions; }
+
+        public Set<String> getAccessTypes() { return accessTypes; }
+
+        public AuditFilter.AccessResult getAccessResult() { return accessResult; }
+
+        public Boolean getIsAudited() { return isAudited; }
+
+        @Override
+        public StringBuilder toString(StringBuilder sb) {
+            if (sb == null) {
+                sb = new StringBuilder();
+            }
+
+            sb.append("RangerAuditPolicyItem={");
+            super.toString(sb);
+            sb.append(" accessResult={").append(accessResult).append("}");
+
+            sb.append(" actions={");
+            if (actions != null) {
+                for (String action : actions) {
+                    if (action != null) {
+                        sb.append(action).append(" ");
+                    }
+                }
+            }
+            sb.append("}");
+
+            sb.append(" accessTypes={");
+            if (accessTypes != null) {
+                for (String accessTypes : accessTypes) {
+                    if (accessTypes != null) {
+                        sb.append(accessTypes).append(" ");
+                    }
+                }
+            }
+            sb.append("}");
+
+            sb.append(" isAudited={").append(isAudited).append("}");
+            sb.append("}");
+
+            return sb;
+        }
+
+        private static List<RangerPolicyItemAccess> getPolicyItemAccesses(List<String> accessTypes) {
+            final List<RangerPolicyItemAccess> ret;
+
+            if (accessTypes != null) {
+                ret = new ArrayList<>(accessTypes.size());
+
+                for (String accessType : accessTypes) {
+                    ret.add(new RangerPolicyItemAccess(accessType));
+                }
+            } else {
+                ret = Collections.emptyList();
+            }
+
+            return ret;
+        }
+    }
+}
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 07fb638..d64d226 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
@@ -856,7 +856,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		return sb;
 	}
 
-	private void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
+	protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
 		if(policy == null || (!hasAllow() && !hasDeny()) || serviceDef == null) {
 			return;
 		}
@@ -875,7 +875,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		preprocessPolicyItems(policy.getRowFilterPolicyItems(), impliedAccessGrants);
 	}
 
-	private void preprocessPolicyItems(List<? extends RangerPolicyItem> policyItems, Map<String, Collection<String>> impliedAccessGrants) {
+	protected void preprocessPolicyItems(List<? extends RangerPolicyItem> policyItems, Map<String, Collection<String>> impliedAccessGrants) {
 		for(RangerPolicyItem policyItem : policyItems) {
 			if(CollectionUtils.isEmpty(policyItem.getAccesses())) {
 				continue;
@@ -910,7 +910,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		}
 	}
 
-	private Map<String, Collection<String>> getImpliedAccessGrants(RangerServiceDef serviceDef) {
+	protected Map<String, Collection<String>> getImpliedAccessGrants(RangerServiceDef serviceDef) {
 		Map<String, Collection<String>> ret = null;
 
 		if(serviceDef != null && !CollectionUtils.isEmpty(serviceDef.getAccessTypes())) {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
index 9794881..f218900 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
@@ -202,7 +202,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
             errorText = "policyResources is null or empty, or serviceDef is null.";
         }
 
-        if (allMatchers == null) {
+        if (allMatchers == null && policyType != RangerPolicy.POLICY_TYPE_AUDIT) {
             serviceDefHelper       = null;
             validResourceHierarchy = null;
 
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
index 2d9bc73..873553a 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
@@ -364,6 +364,10 @@ public class RangerBasePlugin {
 
 		}
 
+		if (policyEngine != null) {
+			policyEngine.evaluateAuditPolicies(ret);
+		}
+
 		if (resultProcessor != null) {
 			resultProcessor.processResult(ret);
 		}
@@ -399,6 +403,12 @@ public class RangerBasePlugin {
 			}
 		}
 
+		if (policyEngine != null && CollectionUtils.isNotEmpty(ret)) {
+			for (RangerAccessResult result : ret) {
+				policyEngine.evaluateAuditPolicies(result);
+			}
+		}
+
 		if (resultProcessor != null) {
 			resultProcessor.processResults(ret);
 		}
@@ -408,22 +418,36 @@ public class RangerBasePlugin {
 
 	public RangerAccessResult evalDataMaskPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) {
 		RangerPolicyEngine policyEngine = this.policyEngine;
+		RangerAccessResult ret          = null;
 
 		if(policyEngine != null) {
-			return policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_DATAMASK, resultProcessor);
+			ret = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_DATAMASK, resultProcessor);
+
+			policyEngine.evaluateAuditPolicies(ret);
 		}
 
-		return null;
+		return ret;
 	}
 
 	public RangerAccessResult evalRowFilterPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) {
 		RangerPolicyEngine policyEngine = this.policyEngine;
+		RangerAccessResult ret          = null;
 
 		if(policyEngine != null) {
-			return policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ROWFILTER, resultProcessor);
+			ret = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ROWFILTER, resultProcessor);
+
+			policyEngine.evaluateAuditPolicies(ret);
 		}
 
-		return null;
+		return ret;
+	}
+
+	public void evalAuditPolicies(RangerAccessResult result) {
+		RangerPolicyEngine policyEngine = this.policyEngine;
+
+		if (policyEngine != null) {
+			policyEngine.evaluateAuditPolicies(result);
+		}
 	}
 
 	public RangerResourceAccessInfo getResourceAccessInfo(RangerAccessRequest request) {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java
index 6ab068f..c3d7816 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java
@@ -201,6 +201,8 @@ public class ServicePolicies implements java.io.Serializable {
 		private List<RangerPolicy> policies;
 		private RangerServiceDef   serviceDef;
 		private String             auditMode = RangerPolicyEngine.AUDIT_DEFAULT;
+		private Map<String, String> serviceConfig;
+
 		/**
 		 * @return the serviceName
 		 */
@@ -282,6 +284,14 @@ public class ServicePolicies implements java.io.Serializable {
 			this.auditMode = auditMode;
 		}
 
+		public Map<String, String> getServiceConfig() {
+			return serviceConfig;
+		}
+
+		public void setServiceConfig(Map<String, String> serviceConfig) {
+			this.serviceConfig = serviceConfig;
+		}
+
 		@Override
 		public String toString() {
 			return "serviceName=" + serviceName + ", "
@@ -291,6 +301,7 @@ public class ServicePolicies implements java.io.Serializable {
 					+ "policies=" + policies + ", "
 					+ "serviceDef=" + serviceDef + ", "
 					+ "auditMode=" + auditMode
+					+ "serviceConfig=" + serviceConfig
 					;
 		}
 	}
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 63fccd0..046e15f 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
@@ -430,6 +430,21 @@ public class TestPolicyEngine {
 		runTestsFromResourceFiles(resourceFiles);
 	}
 
+	@Test
+	public void testPolicyEngine_auditFilterHdfs() {
+		String[] resourceFiles = {"/policyengine/test_policyengine_audit_filter_hdfs.json"};
+
+		runTestsFromResourceFiles(resourceFiles);
+	}
+
+
+	@Test
+	public void testPolicyEngine_auditFilterHive() {
+		String[] resourceFiles = {"/policyengine/test_policyengine_audit_filter_hive.json"};
+
+		runTestsFromResourceFiles(resourceFiles);
+	}
+
 	private void runTestsFromResourceFiles(String[] resourceNames) {
 		for(String resourceName : resourceNames) {
 			InputStream inStream = this.getClass().getResourceAsStream(resourceName);
@@ -461,6 +476,7 @@ public class TestPolicyEngine {
 			tagPolicies.setServiceName(testCase.tagPolicyInfo.serviceName);
 			tagPolicies.setServiceDef(testCase.tagPolicyInfo.serviceDef);
 			tagPolicies.setPolicies(testCase.tagPolicyInfo.tagPolicies);
+			tagPolicies.setServiceConfig(testCase.tagPolicyInfo.serviceConfig);
 
 			if (StringUtils.isNotBlank(testCase.auditMode)) {
 				tagPolicies.setAuditMode(testCase.auditMode);
@@ -563,7 +579,6 @@ public class TestPolicyEngine {
 	}
 
     private void runTestCaseTests(RangerPolicyEngine policyEngine, RangerPolicyEngine policyEngineForEvaluatingWithACLs, RangerServiceDef serviceDef, String testName, List<TestData> tests) {
-
         RangerAccessRequest request = null;
 
         for(TestData test : tests) {
@@ -643,12 +658,16 @@ public class TestPolicyEngine {
 
 				result   = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ACCESS, auditHandler);
 
+				policyEngine.evaluateAuditPolicies(result);
+
 				assertNotNull("result was null! - " + test.name, result);
 				assertEquals("isAllowed mismatched! - " + test.name, expected.getIsAllowed(), result.getIsAllowed());
 				assertEquals("isAudited mismatched! - " + test.name, expected.getIsAudited(), result.getIsAudited());
 
 				result   = policyEngineForEvaluatingWithACLs.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ACCESS, auditHandler);
 
+				policyEngine.evaluateAuditPolicies(result);
+
                 assertNotNull("result was null! - " + test.name, result);
                 assertEquals("isAllowed mismatched! - " + test.name, expected.getIsAllowed(), result.getIsAllowed());
                 assertEquals("isAudited mismatched! - " + test.name, expected.getIsAudited(), result.getIsAudited());
@@ -660,6 +679,8 @@ public class TestPolicyEngine {
 
                 result   = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_DATAMASK, auditHandler);
 
+                policyEngine.evaluateAuditPolicies(result);
+
                 assertNotNull("result was null! - " + test.name, result);
                 assertEquals("maskType mismatched! - " + test.name, expected.getMaskType(), result.getMaskType());
                 assertEquals("maskCondition mismatched! - " + test.name, expected.getMaskCondition(), result.getMaskCondition());
@@ -668,6 +689,8 @@ public class TestPolicyEngine {
 
                 result = policyEngineForEvaluatingWithACLs.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_DATAMASK, auditHandler);
 
+                policyEngine.evaluateAuditPolicies(result);
+
 				assertNotNull("result was null! - " + test.name, result);
 				assertEquals("maskType mismatched! - " + test.name, expected.getMaskType(), result.getMaskType());
 				assertEquals("maskCondition mismatched! - " + test.name, expected.getMaskCondition(), result.getMaskCondition());
@@ -682,12 +705,16 @@ public class TestPolicyEngine {
 
                 result   = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ROWFILTER, auditHandler);
 
+                policyEngine.evaluateAuditPolicies(result);
+
                 assertNotNull("result was null! - " + test.name, result);
                 assertEquals("filterExpr mismatched! - " + test.name, expected.getFilterExpr(), result.getFilterExpr());
                 assertEquals("policyId mismatched! - " + test.name, expected.getPolicyId(), result.getPolicyId());
 
 				result = policyEngineForEvaluatingWithACLs.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ROWFILTER, auditHandler);
 
+				policyEngine.evaluateAuditPolicies(result);
+
 				assertNotNull("result was null! - " + test.name, result);
 				assertEquals("filterExpr mismatched! - " + test.name, expected.getFilterExpr(), result.getFilterExpr());
 				assertEquals("policyId mismatched! - " + test.name, expected.getPolicyId(), result.getPolicyId());
@@ -745,6 +772,7 @@ public class TestPolicyEngine {
 		class TagPolicyInfo {
 			public String	serviceName;
 			public RangerServiceDef serviceDef;
+			public Map<String, String> serviceConfig;
 			public List<RangerPolicy> tagPolicies;
 		}
 	}
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hdfs.json b/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hdfs.json
new file mode 100644
index 0000000..153b39b
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hdfs.json
@@ -0,0 +1,120 @@
+{
+  "serviceName":"hdfsdev",
+
+  "serviceDef":{ "name":"hdfs", "id":1,
+    "resources":[
+      {"name":"path","type":"path","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Resource Path","description":"HDFS file or directory path"}
+    ],
+
+    "accessTypes":[
+      {"name":"read","label":"Read"},
+      {"name":"write","label":"Write"},
+      {"name":"execute","label":"Execute"}
+    ]
+  },
+
+  "serviceConfig": {
+    "ranger.plugin.audit.filters": "[ {'accessResult': 'DENIED', 'isAudited': true}, {'users': ['unaudited-user1'], 'groups': ['unaudited-group1'], 'roles': ['unaudited-role1'], 'isAudited': false}, {'actions': [ 'listStatus', 'getfileinfo' ], 'accessTypes':['execute'], 'isAudited': false}, {'resources':{'path':{'values':['/audited'], 'isRecursive': true}},'isAudited': true}, {'resources':{'path':{'values':['/unaudited'], 'isRecursive': true}},'isAudited': false} ]"
+  },
+
+  "policies":[
+    { "id":10,"name":"/audited/","isEnabled":true,"isAuditEnabled":true,
+      "isDenyAllElse": true,
+      "resources":{"path":{"values":["/audited"],"isRecursive":true}},
+      "policyItems":[
+        {"accesses":[{"type":"write","isAllowed":true},{"type":"read","isAllowed":true},{"type":"execute","isAllowed":true}],"users":["allowed-user1", "unaudited-user1"], "groups": ["unaudited-group1"], "roles": ["unaudited-role1"] }
+      ]
+    },
+    { "id":11,"name":"/unaudited/","isEnabled":true,"isAuditEnabled":true,
+      "isDenyAllElse": true,
+      "resources":{"path":{"values":["/unaudited"],"isRecursive":true}},
+      "policyItems":[
+        {"accesses":[{"type":"write","isAllowed":true},{"type":"read","isAllowed":true},{"type":"execute","isAllowed":true}],"users":["allowed-user1"]}
+      ]
+    }
+  ],
+
+  "tagPolicyInfo": {
+    "serviceName":"tagdev",
+
+    "serviceDef": { "name": "tag", "id": 100,
+      "resources": [
+        { "name": "tag", "type": "string", "level": 1, "mandatory": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": false, "ignoreCase": false }, "label": "TAG", "description": "TAG" }
+      ],
+      "accessTypes": [
+        { "name": "hdfs:read", "label": "hdfs:Read"  },
+        { "name": "hdfs:write", "label": "hdfs:Write" },
+        { "name": "hdfs:execute", "label": "hdfs:Execute" }
+      ]
+    },
+
+    "serviceConfig": {
+      "ranger.plugin.audit.filters": "[ {'resources':{'tag':{'values':['AUDIT_ALL_ACCESS']}},'isAudited': true}, {'resources':{'tag':{'values':['NO_AUDIT_ACCESS']}},'isAudited': false} ]"
+    },
+
+    "tagPolicies":[
+      { "id":101, "name":"PII", "isEnabled":true, "isAuditEnabled":true,
+        "resources":{"tag":{"values":["PII"]}},
+        "policyItems":[
+          { "accesses":[{"type":"hdfs:read", "isAllowed":true},{"type":"hdfs:write", "isAllowed":true}], "users":["allowed-user1", "unaudited-user1"], "groups":["unaudited-group1"], "roles":["unaudited-role1"]}
+        ]
+      }
+    ]
+  },
+
+  "tests":[
+    { "name":"audit denied access: resource=/audited/test.txt, accessType=read, action=null, user=denied-user1",
+      "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"read", "user":"denied-user1" },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+    },
+    { "name":"audit denied access: resource=/unaudited/test.txt, accessType=read, action=null, user=denied-user1",
+      "request":{ "resource":{"elements":{"path":"/unaudited/test.txt"}}, "accessType":"read","user":"denied-user1" },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+    },
+    { "name":"audit read access to /audited: resource=/audited/test.txt, accessType=read, action=null, user=allowed-user1",
+      "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"read","user":"allowed-user1" },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":10}
+    },
+    { "name":"audit write access to /audited: resource=/audited/test.txt, accessType=write, action=null, user=allowed-user1",
+      "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"write","user":"allowed-user1" },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":10}
+    },
+    { "name":"no audit for access to /unaudited: resource=/unaudited/test.txt, accessType=read, action=null, user=allowed-user1",
+      "request":{ "resource":{"elements":{"path":"/unaudited/test.txt"}}, "accessType":"read","user":"allowed-user1" },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":11}
+    },
+    { "name":"no audit for listStatus action: resource=/audited/test.txt', accessType=read, action=listStatus, user=allowed-user1",
+      "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"read","action":"listStatus","user":"allowed-user1" },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+    },
+    { "name":"no audit for getfileinfo action: resource=/audited/test.txt, accessType=read, action=getfileinfo, user=allowed-user1",
+      "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"read","action":"getfileinfo","user":"allowed-user1" },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+    },
+    { "name":"no audit for execute access: resource=/audited/test.txt, accessType=execute, action=null, user=allowed-user1",
+      "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"execute","user":"allowed-user1" },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+    },
+    { "name":"no audit for unaudited-user1 user: resource=/audited/test.txt, accessType=execute, action=null, user=unaudited-user1",
+      "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"write","user":"unaudited-user1" },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+    },
+    { "name":"no audit for unaudited-group1 group: resource=/audited/test.txt, accessType=execute, action=null, group=unaudited-group1",
+      "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"write","user":"nonexisting-user1", "userGroups":["unaudited-group1"] },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+    },
+    { "name":"no audit for unaudited-role1 role: resource=/audited/test.txt, accessType=execute, action=null, role=unaudited-role1",
+      "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"write","user":"nonexisting-user1", "userGroups":["nonexisting-group1"], "userRoles":["unaudited-role1"] },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+    },
+    { "name":"audit access to AUDIT_ALL_ACCESS tagged: resource=/unaudited/test.txt, accessType=write, action=null, user=allowed-user1, tags=AUDIT_ALL_ACCESS",
+      "request":{ "resource":{"elements":{"path":"/unaudited/test.txt"}}, "accessType":"write", "user":"allowed-user1", "context":{"TAGS": "[{'type':'AUDIT_ALL_ACCESS'}]"}},
+      "result":{"isAudited":true,"isAllowed":true,"policyId":10}
+    },
+    { "name":"no audit access to NO_AUDIT_ACCESS tagged: resource=/audited/test.txt, accessType=write, action=null, user=allowed-user1, tags=NO_AUDIT_ACCESS",
+      "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"write", "user":"allowed-user1", "context":{"TAGS": "[{'type':'NO_AUDIT_ACCESS'}]"}},
+      "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+    }
+  ]
+}
+
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hive.json b/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hive.json
new file mode 100644
index 0000000..3225f15
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hive.json
@@ -0,0 +1,248 @@
+{
+  "serviceName":"hivedev",
+
+  "serviceDef":{
+    "name":"hive",
+    "id":3,
+    "resources":[
+      {"name":"database","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Database","description":"Hive Database"},
+      {"name":"global","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Global","description":"Global"},
+      {"name":"url","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"URL","description":"URL"},
+      {"name":"hiveservice","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Service","description":"Hive Service"},
+      {"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"},
+      {"name":"update","label":"Update"},
+      {"name":"create","label":"Create"},
+      {"name":"drop","label":"Drop"},
+      {"name":"alter","label":"Alter"},
+      {"name":"index","label":"Index"},
+      {"name":"lock","label":"Lock"},
+      {"name":"all","label":"All",
+        "impliedGrants": [
+          "select",
+          "update",
+          "create",
+          "drop",
+          "alter",
+          "index",
+          "lock"
+        ]
+      }
+    ]
+  },
+
+  "serviceConfig": {
+    "ranger.plugin.audit.filters": "[ {'accessResult': 'DENIED', 'isAudited': true}, {'resources':{'database':{'values':['temp']},'table':{'values':['tempdata']},'column':{'values':['*']}},'isAudited' : false}, {'resources':{'database':{'values':['sys']},'table':{'values':['dump']}},'users':['user2'],'isAudited': false }, {'actions':['METADATA OPERATION'], 'isAudited': false}, {'users':['superuser1'],'groups':['supergroup1'], 'isAudited': false} ]"
+ },
+
+"policies": [
+    {"id":1,"name":"db=*:table=*,column=*","isEnabled":true,"isAuditEnabled":true,"policyType":0,
+      "resources":{"database":{"values":["*"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+      "policyItems":[
+        {"accesses":[{"type":"select","isAllowed":true}],"users":["hive", "user1", "user2", "superuser1"],"groups":["supergroup1"],"delegateAdmin":false}
+      ]
+    }
+  ],
+  "tagPolicyInfo": {
+
+    "serviceName":"tagdev",
+    "serviceDef": {
+      "name": "tag",
+      "id": 100,
+      "resources": [
+        {
+          "itemId": 1,
+          "name": "tag",
+          "type": "string",
+          "level": 1,
+          "parent": "",
+          "mandatory": true,
+          "lookupSupported": true,
+          "recursiveSupported": false,
+          "excludesSupported": false,
+          "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+          "matcherOptions": {
+            "wildCard": true,
+            "ignoreCase": false
+          },
+          "validationRegEx": "",
+          "validationMessage": "",
+          "uiHint": "",
+          "label": "TAG",
+          "description": "TAG"
+        }
+      ],
+      "accessTypes": [
+        {
+          "itemId": 1,
+          "name": "hive:select",
+          "label": "hive:select"
+        },
+        {
+          "itemId": 2,
+          "name": "hive:update",
+          "label": "hive:update"
+        },
+        {
+          "itemId": 3,
+          "name": "hive:create",
+          "label": "hive:create"
+        }
+      ,
+        {
+          "itemId": 4,
+          "name": "hive:grant",
+          "label": "hive:grant"
+        }
+      ,
+        {
+          "itemId": 5,
+          "name": "hive:drop",
+          "label": "hive:drop"
+        }
+      ,
+        {
+          "itemId": 6,
+          "name": "hive:alter",
+          "label": "hive:alter"
+        },
+        {
+          "itemId": 7,
+          "name": "hive:index",
+          "label": "hive:index"
+        },
+        {
+          "itemId": 8,
+          "name": "hive:lock",
+          "label": "hive:lock"
+        },
+        {
+          "itemId": 9,
+          "name": "hive:all",
+          "label": "hive:all",
+          "impliedGrants":
+          [
+            "hive:select",
+            "hive:update",
+            "hive:create",
+            "hive:grant",
+            "hive:drop",
+            "hive:alter",
+            "hive:index",
+            "hive:lock"
+          ]
+        }
+      ],
+      "contextEnrichers": [],
+      "policyConditions": []
+    },
+
+    "serviceConfig": {
+      "ranger.plugin.audit.filters": "[ {'resources':{'tag':{'values':['NO_AUDIT']}},'isAudited': false}, {'resources':{'tag':{'values':['SYS_DATA']}},'users':['user1'],'isAudited': false}, {'resources':{'tag':{'values':['HIPPA']}},'users':['user1'], 'isAudited': true} ]"
+    },
+
+    "tagPolicies":[
+      {"id":1001,"name":"DEFAULT","isEnabled":true,"isAuditEnabled":true,
+        "resources":{"tag":{"values":["DEFAULT"],"isRecursive":false}},
+        "policyItems":[{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", "user1"],"groups":[],"delegateAdmin":false}]
+      },
+      {"id":1002,"name":"HIPPA","isEnabled":true,"isAuditEnabled":true,
+        "resources":{"tag":{"values":["HIPPA"],"isRecursive":false}},
+        "policyItems":[{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", "user1","user2"],"groups":[],"delegateAdmin":false}]
+      }
+    ]
+  },
+
+  "tests": [
+    {"name":"cmd -> select * from temp.tempdata, discard access audit for user1 to table -> temp.tempdata",
+      "request":{
+        "resource":{"elements":{"database":"temp","table":"tempdata", "column": "*"}},
+        "accessType":"select","user":"user1","userGroups":["user1"],"requestData":"select * from temp.tempdata"
+      },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+    },
+    {"name":"cmd -> use temp, discard access audit for user1 to database -> temp" ,
+      "request":{
+        "resource":{"elements":{"database":"temp"},
+          "accessType":"_any","user":"user1","userGroups":["user1"],"requestData":"use temp"
+        },
+        "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+      }
+    },
+    {"name":"cmd -> select * from sys.dump, discard access audit for user2 to table -> sys.dump",
+      "request":{
+        "resource":{"elements":{"database":"sys","table":"dump"}},
+        "accessType":"select","user":"user2","userGroups":[],"requestData":"select * from sys.dump"
+      },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+    },
+    {"name":"cmd -> select * from hr.emp, discard access audit for superuser1 for access to table -> hr.emp",
+      "request":{
+        "resource":{"elements":{"database":"hr"}},
+        "accessType":"select","user":"superuser1","userGroups":[],"requestData":"select * from hr.emp"
+      },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+    },
+    {"name":"cmd -> select * from hr.emp, discard access audit for supergroup1 to table -> hr.emp",
+      "request":{
+        "resource":{"elements":{"database":"hr","table":"emp"}},
+        "accessType":"select","user":"","userGroups":["supergroup1"],"requestData":"select * from hr.emp"
+      },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+    },
+    {"name":"cmd -> select * from hr.emp;', Audit access for user4 to table hr.emp",
+      "request":{
+        "resource":{"elements":{"database":"hr","table":"emp"}},
+        "accessType":"select","user":"user4","userGroups":[],"requestData":"select * from hr.emp"
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+    },
+    {"name":"cmd -> select * from sys.scheduled_queries, discard access audit for hive operation = METADATA OPERATION",
+      "request":{
+        "resource":{"elements":{"database":"sys","table":"scheduled_queries"}},
+        "accessType":"select","user":"hive","userGroups":[],"requestData":"select * from sys.scheduled_queries","action": "METADATA OPERATION"
+      },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+    },
+
+    {"name":"cmd -> select name from medical.data, Audit access of resources with TAG = HIPPA",
+      "request":{
+        "resource":{"elements":{"database":"medical", "table":"data", "column":"name"}},
+        "accessType":"select","user":"user2","userGroups":[],"requestData":"select name from medical.data for user1",
+        "context": {"TAGS": "[{\"type\":\"HIPPA\"}]"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":-1}
+    },
+
+    {"name":"cmd -> select name from temp.data, discard  access audit of resources with TAG = NO_AUDIT",
+      "request":{
+        "resource":{"elements":{"database":"temp", "table":"data", "column":"name"}},
+        "accessType":"select","user":"user1","userGroups":[],"requestData":"select name from temp.data for user1",
+        "context": {"TAGS": "[{\"type\":\"NO_AUDIT\"}]"}
+      },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+    },
+
+    {"name":"cmd -> select name from sysdb.data, discard access audit of resources with TAG = SYS_DATA",
+      "request":{
+        "resource":{"elements":{"database":"sysdb", "table":"data", "column":"name"}},
+        "accessType":"select","user":"user1","userGroups":[],"requestData":"select name from sysdb.data for user1",
+        "context": {"TAGS": "[{\"type\":\"SYS_DATA\"}]"}
+      },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+    },
+
+    {"name":"cmd -> use sysdb, discard access audit of resource with TAG = SYS_DATA",
+      "request":{
+        "resource":{"elements":{"database":"sysdb"}},
+        "accessType":"_any","user":"user1","userGroups":[],"requestData":"use sysdb",
+        "context": {"TAGS": "[{\"type\":\"SYS_DATA\"}]"}
+      },
+      "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+    }
+  ]
+}
\ No newline at end of file
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
index 9aad6db..5e20091 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
@@ -3119,7 +3119,13 @@ public class ServiceREST {
 					} else {
 						ret = updatedServicePolicies;
 					}
+
 					ret.setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getServiceId()));
+
+					if (ret.getTagPolicies() != null && ret.getTagPolicies().getServiceId() != null) {
+						ret.getTagPolicies().setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getTagPolicies().getServiceId()));
+					}
+
 					httpCode = HttpServletResponse.SC_OK;
 					logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().size() : (ret.getPolicyDeltas() != null ? ret.getPolicyDeltas().size() : 0)) + " policies. Policy version=" + ret.getPolicyVersion();
 				}
@@ -3241,7 +3247,13 @@ public class ServiceREST {
 						} else {
 							ret = updatedServicePolicies;
 						}
+
 						ret.setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getServiceId()));
+
+						if (ret.getTagPolicies() != null && ret.getTagPolicies().getServiceId() != null) {
+							ret.getTagPolicies().setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getTagPolicies().getServiceId()));
+						}
+
 						httpCode = HttpServletResponse.SC_OK;
 						logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().size() : (ret.getPolicyDeltas() != null ? ret.getPolicyDeltas().size() : 0)) + " policies. Policy version=" + ret.getPolicyVersion();
 					}