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 2016/11/03 09:20:24 UTC

[1/2] incubator-ranger git commit: RANGER-1190: User has access to a database via tag-based policy - but 'show databases' does not include the database. Ensure that invalid access-resource never matches anything.

Repository: incubator-ranger
Updated Branches:
  refs/heads/master 91f270cfd -> 8b3f0e60e


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestDefaultPolicyResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestDefaultPolicyResourceMatcher.java b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestDefaultPolicyResourceMatcher.java
new file mode 100644
index 0000000..74cb45d
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestDefaultPolicyResourceMatcher.java
@@ -0,0 +1,160 @@
+/*
+ * 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.resourcematcher;
+
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
+import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
+import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class TestDefaultPolicyResourceMatcher {
+	static Gson gsonBuilder = null;
+
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z")
+				.setPrettyPrinting()
+				.registerTypeAdapter(RangerAccessResource.class, new TestDefaultPolicyResourceMatcher.RangerResourceDeserializer())
+				.create();
+	}
+
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+	}
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testDefaultPolicyResourceMatcher() throws Exception {
+		String[] tests = { "/resourcematcher/test_defaultpolicyresourcematcher.json" };
+
+		runTestsFromResourceFiles(tests);
+	}
+
+	private void runTestsFromResourceFiles(String[] resourceNames) throws Exception {
+		for(String resourceName : resourceNames) {
+			InputStream       inStream = this.getClass().getResourceAsStream(resourceName);
+			InputStreamReader reader   = new InputStreamReader(inStream);
+
+			runTests(reader);
+		}
+	}
+
+	private void runTests(InputStreamReader reader) throws Exception {
+		DefaultPolicyResourceMatcherTestCases testCases = gsonBuilder.fromJson(reader, DefaultPolicyResourceMatcherTestCases.class);
+
+		for (DefaultPolicyResourceMatcherTestCases.TestCase testCase : testCases.testCases) {
+			runTest(testCase, testCases.serviceDef);
+		}
+	}
+		private void runTest(DefaultPolicyResourceMatcherTestCases.TestCase testCase, RangerServiceDef serviceDef) throws Exception {
+
+		assertTrue("invalid input: " , testCase != null && testCase.tests != null);
+
+		RangerDefaultPolicyResourceMatcher matcher = new RangerDefaultPolicyResourceMatcher();
+		matcher.setServiceDef(serviceDef);
+		matcher.setPolicyResources(testCase.policyResources);
+		matcher.init();
+
+		for(DefaultPolicyResourceMatcherTestCases.TestCase.OneTest oneTest : testCase.tests) {
+			if(oneTest == null) {
+				continue;
+			}
+
+			boolean expected = oneTest.result;
+			RangerPolicyResourceMatcher.MatchScope scope;
+			if (StringUtils.equalsIgnoreCase(oneTest.type, "selfOrDescendantMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.SELF_OR_DESCENDANT;
+			} else if (StringUtils.equalsIgnoreCase(oneTest.type, "descendantMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.DESCENDANT;
+			} else if (StringUtils.equalsIgnoreCase(oneTest.type, "exactMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.SELF;
+			} else if (StringUtils.equalsIgnoreCase(oneTest.type, "selfOrAncestorMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.SELF_OR_ANCESTOR;
+			} else if (StringUtils.equalsIgnoreCase(oneTest.type, "ancestorMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.ANCESTOR;
+			} else if (StringUtils.equalsIgnoreCase(oneTest.type, "anyMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.SELF_OR_ANCESTOR_OR_DESCENDANT;
+			} else {
+				continue;
+			}
+			boolean result = matcher.isMatch(oneTest.resource, scope, oneTest.evalContext);
+
+			assertEquals("match failed! " + ":" + testCase.name + ":" + oneTest.name + ":" + oneTest.type + ": resource=" + oneTest.resource, expected, result);
+		}
+	}
+
+	private static class DefaultPolicyResourceMatcherTestCases {
+		RangerServiceDef serviceDef;
+
+		List<TestCase> testCases;
+
+		class TestCase {
+			public String name;
+			Map<String, RangerPolicyResource> policyResources;
+			public List<OneTest> tests;
+
+			class OneTest {
+				String name;
+				String type;
+				RangerAccessResourceImpl resource;
+				Map<String, Object> evalContext;
+				boolean result;
+			}
+		}
+	}
+
+	private static class RangerResourceDeserializer implements JsonDeserializer<RangerAccessResource> {
+		@Override
+		public RangerAccessResource deserialize(JsonElement jsonObj, Type type,
+												JsonDeserializationContext context) throws JsonParseException {
+			return gsonBuilder.fromJson(jsonObj, RangerAccessResourceImpl.class);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/resources/contextenricher/test_tagenricher_hive.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/contextenricher/test_tagenricher_hive.json b/agents-common/src/test/resources/contextenricher/test_tagenricher_hive.json
index 317c651..9fba96b 100644
--- a/agents-common/src/test/resources/contextenricher/test_tagenricher_hive.json
+++ b/agents-common/src/test/resources/contextenricher/test_tagenricher_hive.json
@@ -5,6 +5,7 @@
     "name":"hive",
     "id":3,
     "resources":[
+      {"name":"url","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"S3 URL","description":"S3 Bucket URL"},
       {"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":"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"},
@@ -38,39 +39,77 @@
     {"id":1,"serviceName":"cl1_hive","resourceElements":{"database":{"values":["hr"]},"table":{"values":["employee"]},"column":{"values":["ssn"]}}},
     {"id":2,"serviceName":"cl1_hive","resourceElements":{"database":{"values":["finance"]}}},
     {"id":3,"serviceName":"cl1_hive","resourceElements":{"database":{"values":["finance"]},"table":{"values":["tax_2010"]}}},
-    {"id":4,"serviceName":"cl1_hive","resourceElements":{"database":{"values":["finance"]},"table":{"values":["tax_2010"]},"column":{"values":["ssn"]}}}
+    {"id":4,"serviceName":"cl1_hive","resourceElements":{"database":{"values":["finance"]},"table":{"values":["tax_2010"]},"column":{"values":["ssn"]}}},
+    {"id":5,"serviceName":"cl1_hive","resourceElements":{"url":{"values":["someurl"]}}},
+    {"id":6,"serviceName":"cl1_hive","resourceElements":{"database":{"values":["def?n"]}}}
   ],
 
   "resourceToTagIds": {
     "1":[1],
 	"2":[3],
     "3":[2],
-    "4":[1]
+    "4":[1],
+    "5":[1]
   },
 
   "tests":[
+    {"name": "url-any",
+      "resource":{"elements":{"database":"default"}},
+      "accessType": "",
+      "result":[]
+    }
+    ,
+    {"name":"finance-any",
+      "resource":{"elements":{"database":"finance"}},
+      "accessType": "",
+      "result":[{"type":"EXPIRES_ON"}, {"type":"FINANCE"}, {"type":"PII"}]
+    }
+    ,
+    {"name":"finance-and-tax2010any",
+      "resource":{"elements":{"database":"finance", "table":"tax_2010"}},
+      "accessType": "",
+      "result":[{"type":"FINANCE"},{"type":"EXPIRES_ON"}, {"type":"PII"}]
+    }
+    ,
+    {"name":"hr-any",
+      "resource":{"elements":{"database":"hr"}},
+      "accessType": "",
+      "result":[{"type":"PII"}]
+    }
+    ,
+    {"name":"none-any",
+      "resource":{"elements":{}},
+      "accessType": "",
+      "result":[{"type":"EXPIRES_ON"}, {"type":"FINANCE"}, {"type":"PII"}, {"type":"PII"}, {"type":"PII"}]
+    }
+    ,
     {"name":"hr.employee.ssn",
       "resource":{"elements":{"database":"hr","table":"employee","column":"ssn"}},
+      "accessType": "read",
       "result":[{"type":"PII"}]
     }
     ,
     {"name":"hr.employee.id",
       "resource":{"elements":{"database":"hr","table":"employee","column":"id"}},
+      "accessType": "read",
       "result":[]
     }
     ,
     {"name":"finance.tax_2010",
       "resource":{"elements":{"database":"finance","table":"tax_2010"}},
+      "accessType": "read",
       "result":[{"type":"EXPIRES_ON"},{"type":"FINANCE"}]
     }
     ,
     {"name":"finance.tax_2010.ssn",
       "resource":{"elements":{"database":"finance","table":"tax_2010","column":"ssn"}},
+      "accessType": "read",
       "result":[{"type":"EXPIRES_ON"},{"type":"PII"},{"type":"FINANCE"}]
     }
     ,
     {"name":"finance.tax_2010.id",
       "resource":{"elements":{"database":"finance","table":"tax_2010","column":"id"}},
+      "accessType": "read",
       "result":[{"type":"EXPIRES_ON"},{"type":"FINANCE"}]
     }
   ]

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/resources/policyengine/descendant_tags.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/descendant_tags.json b/agents-common/src/test/resources/policyengine/descendant_tags.json
new file mode 100644
index 0000000..101ae26
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/descendant_tags.json
@@ -0,0 +1,108 @@
+{
+    "op":"add_or_update",
+    "tagModel":"resource_private",
+    "serviceName": "cl1_hive",
+    "tagDefinitions": {
+      "1": {
+        "name": "PII",
+        "attributeDefs": [ { "name": "expiry", "type": "datetime" } ],
+        "id": 1,
+        "guid": "tagdefinition-pii-guid"
+      },
+      "2": {
+        "name": "RESTRICTED",
+        "attributeDefs": [ { "name": "activation_date", "type": "datetime" } ],
+        "id": 2,
+        "guid": "tagdefinition-restricted-guid"
+      }
+      ,
+      "3": {
+        "name": "EXPIRES_ON",
+        "attributeDefs": [ { "name": "expiry_date", "type": "datetime" } ],
+        "id": 3,
+        "guid": "tagdefinition-expires_on-guid"
+      }
+    },
+    "tags": {
+      "1": {
+        "type": "PII",
+        "attributes": { "expiry": "2026/06/15" },
+        "id": 1,
+        "guid": "tag-pii-1-guid"
+      },
+      "2": {
+        "type": "RESTRICTED",
+        "attributes": { "activation_date": "2015/08/10" },
+        "id": 2,
+        "guid": "tag-restricted-2-guid"
+      }
+      ,
+      "3": {
+        "type": "EXPIRES_ON",
+        "attributes": { "expiry_date": "2025/08/10" },
+        "id": 3,
+        "guid": "tag-expires_on-3-guid"
+      }
+    },
+    "serviceResources": [
+      {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "finance" ] },
+          "table": { "values": [ "tax_2016" ] },
+          "column": { "values": [ "ssn" ] }
+        },
+        "id": 1,
+        "guid": "finance.tax_2016.ssn-guid"
+     },
+      {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "employee" ] },
+          "table": { "values": [ "personal" ] },
+          "column": { "values": [ "id" ] }
+        },
+        "id": 2,
+        "guid": "employee.personal.id-guid"
+     },
+     {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "default" ] },
+          "table": { "values": [ "table1" ] },
+          "column": { "values": [ "name" ] }
+        },
+        "id": 3,
+        "guid": "default.table1.name-guid"
+     }
+      ,
+      {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "finance" ] },
+          "table": { "values": [ "tax_2016" ] },
+          "column": { "values": [ "name" ] }
+        },
+        "id": 4,
+        "guid": "finance.tax_2016.name-guid"
+      }
+      ,
+      {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "default" ] },
+          "table": { "values": [ "table2" ] }
+        },
+        "id": 5,
+        "guid": "default.table2-guid"
+      }
+    ],
+    "resourceToTagIds": {
+      "1": [ 1 ],
+      "2": [ 2 ],
+      "3": [1],
+      "4": [2],
+      "5": [3]
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/resources/policyengine/test_policyengine_conditions.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_conditions.json b/agents-common/src/test/resources/policyengine/test_policyengine_conditions.json
index 2ab2bee..3b7b2ec 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_conditions.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_conditions.json
@@ -85,7 +85,7 @@
     {"name":"ALLOW 'create default.testTable;' country=US",
      "request":{
       "resource":{"elements":{"database":"default"}},
-      "accessType":"create","user":"user1","userGroups":["users"],"requestData":"create default.testTable",
+      "accessType":"create","user":"user1","userGroups":["users"],"requestData":"create default.testTable; country=US",
       "context":{"country":"US"}
      },
      "result":{"isAudited":true,"isAllowed":true,"policyId":2}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/resources/policyengine/test_policyengine_descendant_tags.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_descendant_tags.json b/agents-common/src/test/resources/policyengine/test_policyengine_descendant_tags.json
new file mode 100644
index 0000000..831342f
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_descendant_tags.json
@@ -0,0 +1,278 @@
+{
+  "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":"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":"grant","label":"Grant"},
+      {"name":"drop","label":"Drop"},
+      {"name":"alter","label":"Alter"},
+      {"name":"index","label":"Index"},
+      {"name":"lock","label":"Lock"},
+      {"name":"all","label":"All",
+        "impliedGrants": [
+          "select",
+          "update",
+          "create",
+          "grant",
+          "drop",
+          "alter",
+          "index",
+          "lock"
+        ]
+      }
+    ]
+  },
+
+  "policies":[
+  ],
+  "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": [
+        {
+          "itemId": 1,
+          "name" : "TagEnricher",
+          "enricher" : "org.apache.ranger.plugin.contextenricher.RangerTagEnricher",
+          "enricherOptions" : {"tagRetrieverClassName":"org.apache.ranger.plugin.contextenricher.RangerFileBasedTagRetriever", "tagRefresherPollingInterval":60000, "serviceTagsFileName":"/policyengine/descendant_tags.json"}
+        }
+      ],
+      "policyConditions": [
+      ]
+    },
+    "tagPolicies":[
+      {"id":1,"name":"RESTRICTED_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,
+        "resources":{"tag":{"values":["RESTRICTED"],"isRecursive":false}},
+        "policyItems":[
+          {
+            "accesses":[{"type":"hive:all","isAllowed":true}],"users":["hive", "user1"],"groups":[],"delegateAdmin":false,
+            "conditions":[]
+          }
+        ],
+        "denyPolicyItems":[
+          {"accesses":[{"type":"hive:all","isAllowed":true}],"users":["user1","hive"],"groups":[],"delegateAdmin":false}
+        ],
+        "denyExceptions":[
+          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["user3"],"groups":[],"delegateAdmin":false}
+        ]
+      },
+      {"id":2,"name":"PII_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,
+        "resources":{"tag":{"values":["PII"],"isRecursive":false}},
+        "policyItems":[
+          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", "user1"],"groups":[],"delegateAdmin":false}
+          ,
+          {"accesses":[{"type":"hive:all","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false}
+        ],
+        "denyPolicyItems":[
+          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false}
+          ,
+          {"accesses":[{"type":"hive:all","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false}
+        ]
+      }
+      ,
+      {"id":3,"name":"EXPIRES_ON_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,
+        "resources":{"tag":{"values":["EXPIRES_ON"],"isRecursive":false}},
+        "policyItems":[
+          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["user", "user1"],"groups":[],"delegateAdmin":false}
+        ],
+        "denyPolicyItems":[
+          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["user"],"groups":[],"delegateAdmin":false}
+        ,
+          {"accesses":[{"type":"hive:all","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false}
+        ]
+      }
+    ]
+  },
+
+  "tests":[
+    {
+      "name": "DENY 'use employee;' for user1 using RESTRICTED tag",
+      "request": {
+        "resource": {"elements": {"database": "employee"}},
+        "accessType": "", "user": "user1", "userGroups": [], "requestData": "'use employee;' for user1"
+      },
+      "result": {"isAudited": true, "isAllowed": false, "policyId":-1}
+    }
+    ,
+    {"name":"ALLOW 'use finance.tax_2016.ssn;' for user1 using PII tag",
+      "request":{
+        "resource":{"elements":{"database":"finance", "table":"tax_2016", "column":"ssn"}},
+        "accessType":"","user":"user1","userGroups":[],"requestData":"'use finance.tax_2016.ssn;' for user1"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    }
+    ,
+    {"name":"DENY 'use finance.tax_2016.name;' for user1 using RESTRICTED tag",
+      "request":{
+        "resource":{"elements":{"database":"finance", "table":"tax_2016", "column":"name"}},
+        "accessType":"","user":"user1","userGroups":[],"requestData":"'use finance.tax_2016.name;' for user1"
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":1}
+    }
+    ,
+    {"name":"DENY 'select finance.tax_2016.ssn;' for hive using PII tag",
+      "request":{
+        "resource":{"elements":{"database":"finance", "table":"tax_2016", "column":"ssn"}},
+        "accessType":"select","user":"hive","userGroups":[],"requestData":"'select finance.tax_2016.ssn;' for hive"
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":2}
+    }
+  ,
+    {"name":"ALLOW 'use finance;' for hive using PII and RESTRICTED tags",
+      "request":{
+        "resource":{"elements":{"database":"finance"}},
+        "accessType":"","user":"hive","userGroups":[],"requestData":"'use finance;' for hive"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    }
+    ,
+    {"name":"DENY 'use default;' for user2 using PII tag",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        "accessType":"","user":"user2","userGroups":[],"requestData":"'use default;' for user2"
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+    }
+    ,
+    {"name":"DENY 'use default.table1.name;' for user2 using PII tag",
+      "request":{
+        "resource":{"elements":{"database":"default", "table": "table1", "column":"name"}},
+        "accessType":"","user":"user2","userGroups":[],"requestData":"'use default.table1.name;' for user2"
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":2}
+    }
+    ,
+    {"name":"ALLOW 'use default;' for user using EXPIRES_ON tag",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        "accessType":"","user":"user","userGroups":[],"requestData":"'use default;' for user"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+    }
+    ,
+    {
+      "name":"ALLOW 'use default;' for hive",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        "accessType":"","user":"hive","userGroups":[],"requestData":"'use default;' for hive"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    }
+    ,
+    {
+      "name":"DENY 'use default.table2;' for hive",
+      "request":{
+        "resource":{"elements":{"database":"default", "table":"table2"}},
+        "accessType":"","user":"hive","userGroups":[],"requestData":"'use default.table2;' for hive"
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":3}
+    }
+    ,
+    {
+      "name":"ALLOW 'select default.table2;' for user1",
+      "request":{
+        "resource":{"elements":{"database":"default", "table":"table2"}},
+        "accessType":"select","user":"user1","userGroups":[],"requestData":"'select default.table2;' for user1"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+    }
+  ]
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
index 6c9b966..b09eedb 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
@@ -187,7 +187,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": true, "policyId": 1 }
@@ -201,7 +201,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": true, "policyId": 101 }
@@ -215,7 +215,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 101 }
@@ -229,7 +229,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 1 }
@@ -243,7 +243,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 1 }
@@ -257,7 +257,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 101 }
@@ -271,7 +271,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": true, "policyId": 101 }
@@ -285,7 +285,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 101 }
@@ -299,7 +299,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
@@ -315,7 +315,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": true, "policyId": 1 }
@@ -329,7 +329,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": true, "policyId": 102 }
@@ -343,7 +343,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 102 }
@@ -357,7 +357,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 1 }
@@ -371,7 +371,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 1 }
@@ -385,7 +385,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 102 }
@@ -399,7 +399,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": true, "policyId": 102 }
@@ -413,7 +413,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 102 }
@@ -427,7 +427,7 @@
         "userGroups": [ ],
         "requestData": "read /resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
@@ -443,7 +443,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": true, "policyId": 2 }
@@ -457,7 +457,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": true, "policyId": 101 }
@@ -471,7 +471,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 101 }
@@ -485,7 +485,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 2 }
@@ -499,7 +499,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 2 }
@@ -513,7 +513,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 101 }
@@ -527,7 +527,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": true, "policyId": 101 }
@@ -541,7 +541,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": 101 }
@@ -555,7 +555,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"PII\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"PII\"}}]"
         }
       },
       "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
@@ -571,7 +571,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": false, "isAllowed": true, "policyId": 2 }
@@ -585,7 +585,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": false, "isAllowed": true, "policyId": 102 }
@@ -599,7 +599,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": false, "isAllowed": false, "policyId": 102 }
@@ -613,7 +613,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": false, "isAllowed": false, "policyId": 2 }
@@ -627,7 +627,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": false, "isAllowed": false, "policyId": 2 }
@@ -641,7 +641,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": false, "isAllowed": false, "policyId": 102 }
@@ -655,7 +655,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": false, "isAllowed": true, "policyId": 102 }
@@ -669,7 +669,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": false, "isAllowed": false, "policyId": 102 }
@@ -683,7 +683,7 @@
         "userGroups": [ ],
         "requestData": "read /unaudited-resource",
         "context": {
-          "TAGS": "[{\"type\":\"Unaudited-TAG\"}]"
+          "TAGS": "[{\"tag\":{\"type\":\"Unaudited-TAG\"}}]"
         }
       },
       "result": { "isAudited": false, "isAllowed": false, "policyId": -1 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
index fab93f6..25f3703 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
@@ -14,6 +14,7 @@
       {"name":"select","label":"Select"},
       {"name":"update","label":"Update"},
       {"name":"create","label":"Create"},
+      {"name":"grant","label":"Grant"},
       {"name":"drop","label":"Drop"},
       {"name":"alter","label":"Alter"},
       {"name":"index","label":"Index"},
@@ -23,6 +24,7 @@
           "select",
           "update",
           "create",
+          "grant",
           "drop",
           "alter",
           "index",
@@ -122,7 +124,18 @@
         {
           "itemId": 9,
           "name": "hive:all",
-          "label": "hive:all"
+          "label": "hive:all",
+          "impliedGrants":
+          [
+            "hive:select",
+            "hive:update",
+            "hive:create",
+            "hive:grant",
+            "hive:drop",
+            "hive:alter",
+            "hive:index",
+            "hive:lock"
+          ]
         }
       ],
       "contextEnrichers": [
@@ -168,7 +181,7 @@
       {"id":3,"name":"PII_TAG_POLICY-FINAL","isEnabled":true,"isAuditEnabled":true,
         "resources":{"tag":{"values":["PII-FINAL"],"isRecursive":false}},
         "denyPolicyItems":[
-          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":[""],"groups":["public"],"delegateAdmin":false}
+          {"accesses":[{"type":"hive:all","isAllowed":true}],"users":[""],"groups":["public"],"delegateAdmin":false}
         ]
         ,
         "denyExceptions":[
@@ -211,7 +224,7 @@
         "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
         "accessType":"select","user":"user1","userGroups":[],"requestData":"select ssn from employee.personal;' for user1",
 
-        "context": {"TAGS":"[{\"type\":\"EXPIRES_ON\", \"attributes\":{\"expiry_date\":\"2026/06/15\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"EXPIRES_ON\", \"attributes\":{\"expiry_date\":\"2026/06/15\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":true,"policyId":101}
     },
@@ -220,7 +233,7 @@
         "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
         "accessType":"select","user":"user1","userGroups":[],"requestData":"select ssn from employee.personal;' for user1",
 
-        "context": {"TAGS":"[{\"type\":\"EXPIRES_ON\", \"attributes\":{\"expiry_date\":\"2015/08/10\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"EXPIRES_ON\", \"attributes\":{\"expiry_date\":\"2015/08/10\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":false,"policyId":5}
     },
@@ -228,7 +241,7 @@
       "request":{
         "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
         "accessType":"select","user":"user1","userGroups":[],"requestData":"select ssn from employee.personal;' for user1",
-        "context": {"TAGS":"[{\"type\":\"EXPIRES_ON\", \"attributes\":{\"expiry_date\":\"2015/08/10\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"EXPIRES_ON\", \"attributes\":{\"expiry_date\":\"2015/08/10\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":false,"policyId":5}
     },
@@ -236,7 +249,7 @@
       "request":{
         "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
         "accessType":"select","user":"dataloader","userGroups":[],"requestData":"select ssn from employee.personal;' for dataloader",
-        "context": {"TAGS":"[{\"type\":\"EXPIRES_ON\", \"attributes\":{\"expiry_date\":\"2015/08/10\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"EXPIRES_ON\", \"attributes\":{\"expiry_date\":\"2015/08/10\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":true,"policyId":101}
     },
@@ -244,7 +257,7 @@
       "request":{
         "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
         "accessType":"select","user":"user1","userGroups":[],"requestData":"select ssn from employee.personal;' for user1",
-        "context": {"TAGS":"[{\"type\":\"RESTRICTED\", \"attributes\":{\"expiry\":\"2026/06/15\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"RESTRICTED\", \"attributes\":{\"expiry\":\"2026/06/15\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":true,"policyId":1}
     },
@@ -252,7 +265,7 @@
       "request":{
         "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
         "accessType":"select","user":"user2","userGroups":[],"requestData":"select ssn from employee.personal;' for user2",
-        "context": {"TAGS":"[{\"type\":\"RESTRICTED-FINAL\", \"attributes\":{\"expiry\":\"2026/06/15\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"RESTRICTED-FINAL\", \"attributes\":{\"expiry\":\"2026/06/15\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":false,"policyId":4}
     },
@@ -277,7 +290,7 @@
       "request":{
         "resource":{"elements":{"database":"default", "table":"table1", "column":"name"}},
         "accessType":"select","user":"hive","userGroups":[],"requestData":"select name from default.table1;' for hive",
-        "context": {"TAGS":"[{\"type\":\"PII\", \"attributes\":{\"expiry\":\"2026/06/15\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"PII\", \"attributes\":{\"expiry\":\"2026/06/15\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":true,"policyId":2}
     },
@@ -285,7 +298,7 @@
       "request":{
         "resource":{"elements":{"database":"default", "table":"table1"}},
         "accessType":"","user":"hive","userGroups":[],"requestData":"desc default.table1;' for hive",
-        "context": {"TAGS":"[{\"type\":\"PII\", \"attributes\":{\"expiry\":\"2026/06/15\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"PII\", \"attributes\":{\"expiry\":\"2026/06/15\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":true,"policyId":2}
     },
@@ -293,7 +306,7 @@
       "request":{
         "resource":{"elements":{"database":"default", "table":"table1"}},
         "accessType":"","user":"user1","userGroups":[],"requestData":"desc default.table1;' for user1",
-        "context": {"TAGS":"[{\"type\":\"PII-FINAL\", \"attributes\":{\"expiry\":\"2026/06/15\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"PII-FINAL\", \"attributes\":{\"expiry\":\"2026/06/15\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":false,"policyId":3}
     },
@@ -301,15 +314,15 @@
       "request":{
         "resource":{"elements":{"database":"default"}},
         "accessType":"","user":"hive","userGroups":[],"requestData":"use default",
-        "context": {"TAGS":"[{\"type\":\"PII-FINAL\", \"attributes\":{\"expiry\":\"2026/06/15\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"PII-FINAL\", \"attributes\":{\"expiry\":\"2026/06/15\"}}}]"}
       },
-      "result":{"isAudited":true,"isAllowed":true,"policyId":101}
+      "result":{"isAudited":true,"isAllowed":false,"policyId":3}
     },
     {"name":"DENY 'use default;' for user1",
       "request":{
         "resource":{"elements":{"database":"default"}},
         "accessType":"","user":"user1","userGroups":[],"requestData":"use default for user1",
-        "context": {"TAGS":"[{\"type\":\"PII-FINAL\", \"attributes\":{\"expiry\":\"2026/06/15\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"PII-FINAL\", \"attributes\":{\"expiry\":\"2026/06/15\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":false,"policyId":3}
     },
@@ -317,7 +330,7 @@
       "request":{
         "resource":{"elements":{"database":"default", "table":"table1", "column":"name"}},
         "accessType":"select","user":"hive","userGroups":[],"requestData":"select * from default.table1",
-        "context": {"TAGS":"[{\"type\":\"PII\", \"attributes\":{\"expiry\":\"2026/06/15\"}}]"}
+        "context": {"TAGS":"[{\"tag\":{\"type\":\"PII\", \"attributes\":{\"expiry\":\"2026/06/15\"}}}]"}
       },
       "result":{"isAudited":true,"isAllowed":true,"policyId":2}
     }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
index 443ee53..c2cb0b3 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
@@ -14,6 +14,7 @@
       {"name":"select","label":"Select"},
       {"name":"update","label":"Update"},
       {"name":"create","label":"Create"},
+      {"name":"grant","label":"Grant"},
       {"name":"drop","label":"Drop"},
       {"name":"alter","label":"Alter"},
       {"name":"index","label":"Index"},
@@ -23,6 +24,7 @@
           "select",
           "update",
           "create",
+          "grant",
           "drop",
           "alter",
           "index",
@@ -122,7 +124,18 @@
         {
           "itemId": 9,
           "name": "hive:all",
-          "label": "hive:all"
+          "label": "hive:all",
+          "impliedGrants":
+          [
+            "hive:select",
+            "hive:update",
+            "hive:create",
+            "hive:grant",
+            "hive:drop",
+            "hive:alter",
+            "hive:index",
+            "hive:lock"
+          ]
         }
       ],
       "contextEnrichers": [
@@ -174,7 +187,7 @@
       {"id":3,"name":"PII_TAG_POLICY-FINAL","isEnabled":true,"isAuditEnabled":true,
         "resources":{"tag":{"values":["PII-FINAL"],"isRecursive":false}},
         "denyPolicyItems":[
-          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":[""],"groups":["public"],"delegateAdmin":false}
+          {"accesses":[{"type":"hive:all","isAllowed":true}],"users":[""],"groups":["public"],"delegateAdmin":false}
         ]
         ,
         "denyExceptions":[
@@ -275,7 +288,7 @@
         "resource":{"elements":{"database":"default", "table":"table1"}},
         "accessType":"","user":"hive","userGroups":[],"requestData":"desc default.table1;' for hive"
       },
-      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+      "result":{"isAudited":true,"isAllowed":false,"policyId":3}
     },
     {"name":"DENY 'desc default.table2;' for user1 using PII-FINAL tag",
       "request":{

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher.json b/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher.json
new file mode 100644
index 0000000..1ca9161
--- /dev/null
+++ b/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher.json
@@ -0,0 +1,778 @@
+{
+  "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": "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"
+      }
+    ]
+  },
+  "testCases": [
+    {
+      "name": "database=*:table=*",
+      "policyResources": {
+        "database": {"values": ["*"]},
+        "table": {"values": ["*"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for parent 'finance.tax.ssn'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance:tax'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+        ,
+        {
+          "name": "MATCH for parent ''",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    },
+    {
+      "name": "database=finance:table=tax",
+      "policyResources": {
+        "database": {"values": ["finance"]},
+        "table": {"values": ["tax"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for parent 'finance.tax.ssn'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for exact 'finance:tax'",
+          "type": "exactMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child ''",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    },
+    {
+      "name": "database=*:table=tax",
+      "policyResources": {
+        "database": {"values": ["*"]},
+        "table": {"values": ["tax"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for parent 'finance.tax.ssn'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for exact 'finance:tax'",
+          "type": "exactMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child ''",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    },
+    {
+      "name": "database=finance:table=*",
+      "policyResources": {
+        "database": {"values": ["finance"]},
+        "table": {"values": ["*"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for parent 'finance.tax.ssn'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance:tax'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child ''",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    },
+    {
+      "name": "database=finance",
+      "policyResources": {
+        "database": {"values": ["finance"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for parent 'finance.tax.ssn'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance:tax'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for exact 'finance'",
+          "type": "exactMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child ''",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    },
+    {
+      "name": "database=*",
+      "policyResources": {
+        "database": {"values": ["*"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for parent 'finance.tax.ssn'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance:tax'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent ''",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    },
+    {
+      "name": "database=*:table=*:column=*",
+      "policyResources": {
+        "database": {"values": [ "*"] },
+        "table": {"values": ["*"]},
+        "column": {"values": ["*"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for parent 'finance.tax.ssn'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance:tax'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent ''",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "NO MATCH for any 'finance::ssn'",
+          "type": "anyMatch",
+          "resource": {
+            "elements": {
+              "database": "finance","column":"ssn"
+            }
+          },
+          "evalContext": {},
+          "result": false
+        }
+      ]
+    }
+  ,
+    {
+      "name": "database=finance:table=tax:column=ssn",
+      "policyResources": {
+        "database": {"values": [ "finance"] },
+        "table": {"values": ["tax"]},
+        "column": {"values": ["ssn"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for exact 'finance.tax.ssn'",
+          "type": "exactMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance:tax'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child ''",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {}
+          },
+          "evalContext": {},
+          "result": true
+        }
+        ,
+        {
+          "name": "NO MATCH for any 'finance:udf=tax'",
+          "type": "anyMatch",
+          "resource": {
+            "elements": {
+              "database": "finance","udf":"tax"
+            }
+          },
+          "evalContext": {},
+          "result": false
+        }
+      ]
+    }
+    ,
+
+    {
+      "name": "database=*:table=*:column=ssn",
+      "policyResources": {
+        "database": {"values": [ "*"] },
+        "table": {"values": ["*"]},
+        "column": {"values": ["ssn"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for exact 'finance.tax.ssn'",
+          "type": "exactMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance:tax'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    }
+  ,
+
+    {
+      "name": "database=finance:table=*:column=*",
+      "policyResources": {
+        "database": {"values": [ "finance"] },
+        "table": {"values": ["*"]},
+        "column": {"values": ["*"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for parent 'finance.tax.ssn'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance:tax'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    }
+  ,
+
+    {
+      "name": "database=*:table=tax:column=*",
+      "policyResources": {
+        "database": {"values": [ "*"] },
+        "table": {"values": ["tax"]},
+        "column": {"values": ["*"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for parent 'finance.tax.ssn'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance:tax'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    }
+  ,
+    {
+      "name": "database=*:table=tax:column=ssn",
+      "policyResources": {
+        "database": {"values": [ "*"] },
+        "table": {"values": ["tax"]},
+        "column": {"values": ["ssn"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for exact 'finance.tax.ssn'",
+          "type": "exactMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance:tax'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    }
+  ,
+    {
+      "name": "database=finance:table=*:column=ssn",
+      "policyResources": {
+        "database": {"values": [ "finance"] },
+        "table": {"values": ["*"]},
+        "column": {"values": ["ssn"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for exact 'finance.tax.ssn'",
+          "type": "exactMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance:tax'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    }
+  ,
+    {
+      "name": "database=finance:table=tax:column=*",
+      "policyResources": {
+        "database": {"values": [ "finance"] },
+        "table": {"values": ["tax"]},
+        "column": {"values": ["*"]}
+      },
+      "tests": [
+        {
+          "name": "MATCH for parent 'finance.tax.ssn'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance", "table":"tax", "column":"ssn"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for parent 'finance:tax'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "finance","table": "tax"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ,
+        {
+          "name": "MATCH for child 'finance'",
+          "type": "descendantMatch",
+          "resource": {
+            "elements": {"database": "finance"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    }
+  ,
+    {
+      "name": "empty policyresources",
+      "policyResources": {
+      },
+      "tests": [
+        {
+          "name": "MATCH for exact ''",
+          "type": "exactMatch",
+          "resource": {
+            "elements": {}
+          },
+          "evalContext": {},
+          "result": true
+        }
+        ,
+        {
+          "name": "MATCH for parent 'default'",
+          "type": "ancestorMatch",
+          "resource": {
+            "elements": {"database": "default"}
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/plugin-kms/derby.log
----------------------------------------------------------------------
diff --git a/plugin-kms/derby.log b/plugin-kms/derby.log
new file mode 100644
index 0000000..68e1e03
--- /dev/null
+++ b/plugin-kms/derby.log
@@ -0,0 +1,74 @@
+Thu Nov 03 02:11:31 PDT 2016 Thread[main,5,main] Cleanup action starting
+java.sql.SQLException: Database 'memory:derbyDB' not found.
+	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
+	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
+	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
+	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
+	at org.apache.derby.impl.jdbc.EmbedConnection.newSQLException(Unknown Source)
+	at org.apache.derby.impl.jdbc.EmbedConnection.handleDBNotFound(Unknown Source)
+	at org.apache.derby.impl.jdbc.EmbedConnection.<init>(Unknown Source)
+	at org.apache.derby.jdbc.InternalDriver.getNewEmbedConnection(Unknown Source)
+	at org.apache.derby.jdbc.InternalDriver.connect(Unknown Source)
+	at org.apache.derby.jdbc.InternalDriver.connect(Unknown Source)
+	at org.apache.derby.jdbc.AutoloadedDriver.connect(Unknown Source)
+	at java.sql.DriverManager.getConnection(DriverManager.java:571)
+	at java.sql.DriverManager.getConnection(DriverManager.java:233)
+	at org.apache.ranger.authorization.kms.authorizer.DerbyTestUtils.stopDerby(DerbyTestUtils.java:60)
+	at org.apache.ranger.authorization.kms.authorizer.RangerKmsAuthorizerTest.stopServers(RangerKmsAuthorizerTest.java:95)
+	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.lang.reflect.Method.invoke(Method.java:606)
+	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
+	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
+	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
+	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)
+	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
+	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
+	at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
+	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
+	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
+	at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+Caused by: ERROR XJ004: Database 'memory:derbyDB' not found.
+	at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
+	at org.apache.derby.impl.jdbc.SQLExceptionFactory.wrapArgsForTransportAcrossDRDA(Unknown Source)
+	... 31 more
+============= begin nested exception, level (1) ===========
+ERROR XJ004: Database 'memory:derbyDB' not found.
+	at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
+	at org.apache.derby.impl.jdbc.SQLExceptionFactory.wrapArgsForTransportAcrossDRDA(Unknown Source)
+	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
+	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
+	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
+	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
+	at org.apache.derby.impl.jdbc.EmbedConnection.newSQLException(Unknown Source)
+	at org.apache.derby.impl.jdbc.EmbedConnection.handleDBNotFound(Unknown Source)
+	at org.apache.derby.impl.jdbc.EmbedConnection.<init>(Unknown Source)
+	at org.apache.derby.jdbc.InternalDriver.getNewEmbedConnection(Unknown Source)
+	at org.apache.derby.jdbc.InternalDriver.connect(Unknown Source)
+	at org.apache.derby.jdbc.InternalDriver.connect(Unknown Source)
+	at org.apache.derby.jdbc.AutoloadedDriver.connect(Unknown Source)
+	at java.sql.DriverManager.getConnection(DriverManager.java:571)
+	at java.sql.DriverManager.getConnection(DriverManager.java:233)
+	at org.apache.ranger.authorization.kms.authorizer.DerbyTestUtils.stopDerby(DerbyTestUtils.java:60)
+	at org.apache.ranger.authorization.kms.authorizer.RangerKmsAuthorizerTest.stopServers(RangerKmsAuthorizerTest.java:95)
+	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.lang.reflect.Method.invoke(Method.java:606)
+	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
+	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
+	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
+	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)
+	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
+	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
+	at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
+	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
+	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
+	at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+============= end nested exception, level (1) ===========
+Cleanup action completed


[2/2] incubator-ranger git commit: RANGER-1190: User has access to a database via tag-based policy - but 'show databases' does not include the database. Ensure that invalid access-resource never matches anything.

Posted by ma...@apache.org.
RANGER-1190: User has access to a database via tag-based policy - but 'show databases' does not include the database. Ensure that invalid access-resource never matches anything.

Signed-off-by: Madhan Neethiraj <ma...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/8b3f0e60
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/8b3f0e60
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/8b3f0e60

Branch: refs/heads/master
Commit: 8b3f0e60eb9d48ee0a89546b009ee84e7013759e
Parents: 91f270c
Author: Abhay Kulkarni <ak...@hortonworks.com>
Authored: Wed Oct 19 15:10:14 2016 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Thu Nov 3 02:18:58 2016 -0700

----------------------------------------------------------------------
 .../plugin/audit/RangerDefaultAuditHandler.java |   6 +-
 .../RangerScriptExecutionContext.java           |  26 +-
 .../RangerServiceResourceMatcher.java           |   5 +-
 .../contextenricher/RangerTagEnricher.java      |  45 +-
 .../contextenricher/RangerTagForEval.java       |  72 ++
 .../policyengine/RangerPolicyEngineImpl.java    | 120 +--
 .../policyengine/RangerPolicyRepository.java    |   4 +-
 .../policyengine/RangerTagAccessRequest.java    |  59 ++
 .../plugin/policyengine/RangerTagResource.java  |  33 +
 .../RangerCachedPolicyEvaluator.java            |  69 +-
 .../RangerDefaultPolicyEvaluator.java           | 258 +++---
 .../RangerDefaultPolicyItemEvaluator.java       |  34 +-
 .../RangerOptimizedPolicyEvaluator.java         |   1 +
 .../RangerDefaultPolicyResourceMatcher.java     | 305 ++++----
 .../RangerPolicyResourceMatcher.java            |   9 +-
 .../plugin/util/RangerAccessRequestUtil.java    |  20 +-
 .../plugin/contextenricher/TestTagEnricher.java |   7 +-
 .../plugin/policyengine/TestPolicyEngine.java   |  13 +-
 .../TestDefaultPolicyResourceMatcher.java       | 160 ++++
 .../contextenricher/test_tagenricher_hive.json  |  43 +-
 .../resources/policyengine/descendant_tags.json | 108 +++
 .../test_policyengine_conditions.json           |   2 +-
 .../test_policyengine_descendant_tags.json      | 278 +++++++
 .../test_policyengine_tag_hdfs.json             |  72 +-
 .../test_policyengine_tag_hive.json             |  43 +-
 .../test_policyengine_tag_hive_filebased.json   |  19 +-
 .../test_defaultpolicyresourcematcher.json      | 778 +++++++++++++++++++
 plugin-kms/derby.log                            |  74 ++
 28 files changed, 2065 insertions(+), 598 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/audit/RangerDefaultAuditHandler.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/audit/RangerDefaultAuditHandler.java b/agents-common/src/main/java/org/apache/ranger/plugin/audit/RangerDefaultAuditHandler.java
index 3c342a3..2a0896d 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/audit/RangerDefaultAuditHandler.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/audit/RangerDefaultAuditHandler.java
@@ -31,7 +31,7 @@ import org.apache.ranger.audit.provider.AuditProviderFactory;
 import org.apache.ranger.audit.provider.MiscUtil;
 import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
 import org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants;
-import org.apache.ranger.plugin.model.RangerTag;
+import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
 import org.apache.ranger.plugin.policyengine.*;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 
@@ -219,12 +219,12 @@ public class RangerDefaultAuditHandler implements RangerAccessResultProcessor {
 
 	protected final Set<String> getTags(RangerAccessRequest request) {
 		Set<String>     ret  = null;
-		List<RangerTag> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
+		List<RangerTagForEval> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
 
 		if (CollectionUtils.isNotEmpty(tags)) {
 			ret = new HashSet<String>();
 
-			for (RangerTag tag : tags) {
+			for (RangerTagForEval tag : tags) {
 				ret.add(tag.getType());
 			}
 		}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java
index 6873554..1428454 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java
@@ -24,7 +24,7 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.authorization.utils.StringUtil;
-import org.apache.ranger.plugin.model.RangerTag;
+import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
@@ -96,12 +96,12 @@ public final class RangerScriptExecutionContext {
 
 	public String getSessionId() { return accessRequest.getSessionId(); }
 
-	public RangerTag getCurrentTag() {
-		RangerTag ret = null;
+	public RangerTagForEval getCurrentTag() {
+		RangerTagForEval ret = null;
 		Object    val = getRequestContext().get(RangerAccessRequestUtil.KEY_CONTEXT_TAG_OBJECT);
 
-		if(val != null && val instanceof RangerTag) {
-			ret = (RangerTag)val;
+		if(val != null && val instanceof RangerTagForEval) {
+			ret = (RangerTagForEval)val;
 		} else {
 			if (LOG.isDebugEnabled()) {
 				LOG.debug("getCurrentTag() - No current TAG object. Script execution must be for resource-based policy.");
@@ -111,16 +111,16 @@ public final class RangerScriptExecutionContext {
 	}
 
 	public String getCurrentTagType() {
-		RangerTag tagObject = getCurrentTag();
+		RangerTagForEval tagObject = getCurrentTag();
 		return (tagObject != null) ? tagObject.getType() : null;
 	}
 
 	public Set<String> getAllTagTypes() {
 		Set<String>     allTagTypes   = null;
-		List<RangerTag> tagObjectList = getAllTags();
+		List<RangerTagForEval> tagObjectList = getAllTags();
 
 		if (CollectionUtils.isNotEmpty(tagObjectList)) {
-			for (RangerTag tag : tagObjectList) {
+			for (RangerTagForEval tag : tagObjectList) {
 				String tagType = tag.getType();
 				if (allTagTypes == null) {
 					allTagTypes = new HashSet<String>();
@@ -136,12 +136,12 @@ public final class RangerScriptExecutionContext {
 		Map<String, String> ret = null;
 
 		if (StringUtils.isNotBlank(tagType)) {
-			List<RangerTag> tagObjectList = getAllTags();
+			List<RangerTagForEval> tagObjectList = getAllTags();
 
 			// Assumption: There is exactly one tag with given tagType in the list of tags - may not be true ***TODO***
 			// This will get attributes of the first tagType that matches
 			if (CollectionUtils.isNotEmpty(tagObjectList)) {
-				for (RangerTag tag : tagObjectList) {
+				for (RangerTagForEval tag : tagObjectList) {
 					if (tag.getType().equals(tagType)) {
 						ret = tag.getAttributes();
 						break;
@@ -181,7 +181,7 @@ public final class RangerScriptExecutionContext {
 		String ret = null;
 
 		if (StringUtils.isNotBlank(attributeName)) {
-			RangerTag tag = getCurrentTag();
+			RangerTagForEval tag = getCurrentTag();
 			Map<String, String> attributes = null;
 			if (tag != null) {
 				attributes = tag.getAttributes();
@@ -279,8 +279,8 @@ public final class RangerScriptExecutionContext {
 		return ret;
 	}
 
-	private List<RangerTag> getAllTags() {
-		List<RangerTag> ret = RangerAccessRequestUtil.getRequestTagsFromContext(accessRequest.getContext());
+	private List<RangerTagForEval> getAllTags() {
+		List<RangerTagForEval> ret = RangerAccessRequestUtil.getRequestTagsFromContext(accessRequest.getContext());
 		
 		if(ret == null) {
 			if (LOG.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
index 637423e..23dfe23 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
@@ -71,10 +71,9 @@ public class RangerServiceResourceMatcher implements RangerPolicyResourceEvaluat
 		return Long.compare(getId(), other.getId());
 	}
 
-	public boolean isMatch(RangerAccessResource requestedResource, Map<String, Object> evalContext) {
-		return policyResourceMatcher != null ? policyResourceMatcher.isExactHeadMatch(requestedResource, evalContext) : false;
+	public RangerPolicyResourceMatcher.MatchType getMatchType(RangerAccessResource requestedResource, Map<String, Object> evalContext) {
+		return policyResourceMatcher != null ?  policyResourceMatcher.getMatchType(requestedResource, evalContext) : RangerPolicyResourceMatcher.MatchType.NONE;
 	}
-
 	RangerServiceDef getServiceDef() {
 		return policyResourceMatcher != null ? policyResourceMatcher.getServiceDef() : null;
 	}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
index 1a6e1b2..00e46ea 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
@@ -33,6 +33,7 @@ import org.apache.ranger.plugin.model.RangerTag;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
+import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.RangerResourceTrie;
@@ -132,7 +133,9 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 			LOG.debug("==> RangerTagEnricher.enrich(" + request + ")");
 		}
 
-		List<RangerTag> matchedTags = findMatchingTags(request.getResource(), request.getContext());
+		final List<RangerTagForEval> matchedTags;
+
+		matchedTags = findMatchingTags(request);
 
 		RangerAccessRequestUtil.setRequestTagsInContext(request.getContext(), matchedTags);
 
@@ -202,12 +205,13 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 		return ret;
 	}
 
-	private List<RangerTag> findMatchingTags(final RangerAccessResource resource, final Map<String, Object> evalContext) {
+	private List<RangerTagForEval> findMatchingTags(final RangerAccessRequest request) {
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerTagEnricher.findMatchingTags(" + resource + ", " + evalContext + ")");
+			LOG.debug("==> RangerTagEnricher.findMatchingTags(" + request + ")");
 		}
 
-		List<RangerTag> ret = null;
+		RangerAccessResource resource = request.getResource();
+		List<RangerTagForEval> ret = null;
 		final List<RangerServiceResourceMatcher> serviceResourceMatchers = getEvaluators(resource);
 
 		if (CollectionUtils.isNotEmpty(serviceResourceMatchers)) {
@@ -216,14 +220,22 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 
 			for (RangerServiceResourceMatcher resourceMatcher : serviceResourceMatchers) {
 
-				boolean matchResult = resourceMatcher.isMatch(resource, evalContext);
+				final RangerPolicyResourceMatcher.MatchType matchType = resourceMatcher.getMatchType(resource, request.getContext());
+
+				final boolean isMatched;
 
-				if (matchResult) {
+				if(request.isAccessTypeAny()) {
+					isMatched = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
+				}  else if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+					isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.DESCENDANT;
+				} else {
+					isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.ANCESTOR;
+				}
+				if (isMatched) {
 					if (ret == null) {
-						ret = new ArrayList<RangerTag>();
+						ret = new ArrayList<RangerTagForEval>();
 					}
-					// Find tags from serviceResource
-					ret.addAll(getTagsForServiceResource(serviceTags, resourceMatcher.getServiceResource()));
+					ret.addAll(getTagsForServiceResource(serviceTags, resourceMatcher.getServiceResource(), matchType));
 				}
 			}
 		}
@@ -237,7 +249,7 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 		}
 
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerTagEnricher.findMatchingTags(" + resource + ", " + evalContext + ")");
+			LOG.debug("<== RangerTagEnricher.findMatchingTags(" + request + ")");
 		}
 
 		return ret;
@@ -246,12 +258,15 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 	private List<RangerServiceResourceMatcher> getEvaluators(RangerAccessResource resource) {
 		List<RangerServiceResourceMatcher> ret = null;
 
-		if(serviceResourceTrie == null) {
+		String resourceStr = resource != null ? resource.getAsString() : null;
+
+		if (serviceResourceTrie == null || StringUtils.isEmpty(resourceStr)) {
 			ret = serviceResourceMatchers;
 		} else {
-			Set<String> resourceKeys = resource == null ? null : resource.getKeys();
+			Set<String> resourceKeys = resource.getKeys();
 
 			if (CollectionUtils.isNotEmpty(resourceKeys)) {
+
 				boolean isRetModifiable = false;
 
 				for (String resourceName : resourceKeys) {
@@ -307,9 +322,9 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 		return ret;
 	}
 
-	static private List<RangerTag> getTagsForServiceResource(final ServiceTags serviceTags, final RangerServiceResource serviceResource) {
+	static private List<RangerTagForEval> getTagsForServiceResource(final ServiceTags serviceTags, final RangerServiceResource serviceResource, final RangerPolicyResourceMatcher.MatchType matchType) {
 
-		List<RangerTag> ret = new ArrayList<RangerTag>();
+		List<RangerTagForEval> ret = new ArrayList<RangerTagForEval>();
 
 		final Long resourceId = serviceResource.getId();
 
@@ -327,7 +342,7 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 					RangerTag tag = tags.get(tagId);
 
 					if (tag != null) {
-						ret.add(tag);
+						ret.add(new RangerTagForEval(tag, matchType));
 					}
 				}
 			}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagForEval.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagForEval.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagForEval.java
new file mode 100644
index 0000000..014686d
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagForEval.java
@@ -0,0 +1,72 @@
+/*
+ * 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.contextenricher;
+
+import org.apache.ranger.plugin.model.RangerTag;
+import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Map;
+
+@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+
+// This class needs above annotations for policy-engine unit tests involving RangerTagForEval objects that are initialized
+// from JSON specification
+
+public class RangerTagForEval {
+    private RangerTag tag;
+    private RangerPolicyResourceMatcher.MatchType matchType = RangerPolicyResourceMatcher.MatchType.SELF;
+
+    private RangerTagForEval() {
+    }
+
+    public RangerTagForEval(RangerTag tag, RangerPolicyResourceMatcher.MatchType matchType) {
+        this.tag = tag;
+        this.matchType = matchType;
+    }
+
+    public void setTag(RangerTag tag) {
+        this.tag = tag;
+    }
+    public void setMatchType(RangerPolicyResourceMatcher.MatchType matchType) {
+        this.matchType = matchType;
+    }
+
+    public RangerPolicyResourceMatcher.MatchType getMatchType() {
+        return matchType;
+    }
+
+    public String getType() { return tag.getType();}
+    public Map<String, String> getAttributes() {
+        return tag.getAttributes();
+    }
+    public Long getVersion() {
+        return tag.getVersion();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
----------------------------------------------------------------------
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 905262c..6a9fc18 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
@@ -26,8 +26,8 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
 import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
+import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
 import org.apache.ranger.plugin.model.RangerPolicy;
-import org.apache.ranger.plugin.model.RangerTag;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
@@ -549,10 +549,10 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 		List<RangerPolicyEvaluator> tagPolicyEvaluators = tagPolicyRepository == null ? null : tagPolicyRepository.getPolicyEvaluators();
 
 		if (CollectionUtils.isNotEmpty(tagPolicyEvaluators)) {
-			List<RangerTag> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
+			List<RangerTagForEval> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
 
 			if(CollectionUtils.isNotEmpty(tags)) {
-				for (RangerTag tag : tags) {
+				for (RangerTagForEval tag : tags) {
 					RangerAccessRequest tagEvalRequest = new RangerTagAccessRequest(tag, tagPolicyRepository.getServiceDef(), request);
 
 					List<RangerPolicyEvaluator> evaluators = tagPolicyRepository.getPolicyEvaluators(tagEvalRequest.getResource());
@@ -651,21 +651,21 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 		List<RangerPolicyEvaluator> tagEvaluators = tagPolicyRepository == null ? null : tagPolicyRepository.getPolicyEvaluators();
 
 		if (CollectionUtils.isNotEmpty(tagEvaluators)) {
-			List<RangerTag> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
+			List<RangerTagForEval> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
 
-			if(CollectionUtils.isNotEmpty(tags)) {
-				for (RangerTag tag : tags) {
+			if (CollectionUtils.isNotEmpty(tags)) {
+				for (RangerTagForEval tag : tags) {
 					if (LOG.isDebugEnabled()) {
 						LOG.debug("RangerPolicyEngineImpl.isAccessAllowedForTagPolicies: Evaluating policies for tag (" + tag.getType() + ")");
 					}
 
 					RangerAccessRequest tagEvalRequest = new RangerTagAccessRequest(tag, tagPolicyRepository.getServiceDef(), request);
-					RangerAccessResult  tagEvalResult  = createAccessResult(tagEvalRequest);
+					RangerAccessResult tagEvalResult = createAccessResult(tagEvalRequest);
 
 					// carry fwd results from earlier tags, to optimize the current evaluation
 					//  - if access was already allowed by a tag, only deny needs to be looked into
 					//  - if audit was already determined, evaluation can bail out as soon as access is determined
-					if(result.getIsAllowed()) {
+					if (result.getIsAllowed()) {
 						tagEvalResult.setIsAllowed(result.getIsAllowed());
 					}
 					tagEvalResult.setAuditResultFrom(result);
@@ -677,20 +677,20 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 
 						evaluator.evaluate(tagEvalRequest, tagEvalResult);
 
-						if(tagEvalResult.getIsAllowed() && !evaluator.hasDeny()) { // all policies having deny have been evaluated
+						if (tagEvalResult.getIsAllowed() && !evaluator.hasDeny()) { // all policies having deny have been evaluated
 							tagEvalResult.setIsAccessDetermined(true);
 						}
 
-						if(tagEvalResult.getIsAuditedDetermined() && tagEvalResult.getIsAccessDetermined()) {
+						if (tagEvalResult.getIsAuditedDetermined() && tagEvalResult.getIsAccessDetermined()) {
 							if (LOG.isDebugEnabled()) {
 								LOG.debug("RangerPolicyEngineImpl.isAccessAllowedForTagPolicies: concluding eval of tag (" + tag.getType() + ") with authorization=" + tagEvalResult.getIsAllowed());
 							}
 
-							break;			// Break out of policy-evaluation loop for this tag
+							break;            // Break out of policy-evaluation loop for this tag
 						}
 					}
 
-					if(tagEvalResult.getIsAllowed()) {
+					if (tagEvalResult.getIsAllowed()) {
 						tagEvalResult.setIsAccessDetermined(true);
 					}
 
@@ -699,27 +699,27 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 						result.setAuditPolicyId(tagEvalResult.getAuditPolicyId());
 					}
 
-					if(!result.getIsAccessDetermined() && tagEvalResult.getIsAccessDetermined()) {
-						if(! tagEvalResult.getIsAllowed()) { // access is denied for this tag
+					if (!result.getIsAccessDetermined() && tagEvalResult.getIsAccessDetermined()) {
+						if (!tagEvalResult.getIsAllowed()) { // access is denied for this tag
 							result.setAccessResultFrom(tagEvalResult);
 						} else { // access is allowed for this tag
 							// if a policy evaluated earlier allowed the access, don't update with current tag result
-							if(! result.getIsAllowed()) {
+							if (!result.getIsAllowed()) {
 								result.setAccessResultFrom(tagEvalResult);
 								result.setIsAccessDetermined(false); // so that evaluation will continue for deny
 							}
 						}
 					}
 
-					if(result.getIsAuditedDetermined() && result.getIsAccessDetermined()) {
-						break;			// Break out of policy-evaluation loop
+					if (result.getIsAuditedDetermined() && result.getIsAccessDetermined()) {
+						break;            // Break out of policy-evaluation loop
 					}
 				}
 			}
 		}
 
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowedForTagPolicies(" + request + ", " + result + ")" );
+			LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowedForTagPolicies(" + request + ", " + result + ")");
 		}
 	}
 
@@ -949,87 +949,3 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 		}
 	}
 }
-class RangerTagResource extends RangerAccessResourceImpl {
-	private static final String KEY_TAG = "tag";
-
-
-	public RangerTagResource(String tagType, RangerServiceDef tagServiceDef) {
-		super.setValue(KEY_TAG, tagType);
-		super.setServiceDef(tagServiceDef);
-	}
-}
-
-class RangerTagAccessRequest extends RangerAccessRequestImpl {
-	public RangerTagAccessRequest(RangerTag resourceTag, RangerServiceDef tagServiceDef, RangerAccessRequest request) {
-		super.setResource(new RangerTagResource(resourceTag.getType(), tagServiceDef));
-		super.setUser(request.getUser());
-		super.setUserGroups(request.getUserGroups());
-		super.setAction(request.getAction());
-		super.setAccessType(request.getAccessType());
-		super.setAccessTime(request.getAccessTime());
-		super.setRequestData(request.getRequestData());
-
-		Map<String, Object> requestContext = request.getContext();
-
-		RangerAccessRequestUtil.setCurrentTagInContext(request.getContext(), resourceTag);
-		RangerAccessRequestUtil.setCurrentResourceInContext(request.getContext(), request.getResource());
-		RangerAccessRequestUtil.setCurrentUserInContext(request.getContext(), request.getUser());
-
-		super.setContext(requestContext);
-
-		super.setClientType(request.getClientType());
-		super.setClientIPAddress(request.getClientIPAddress());
-		super.setRemoteIPAddress(request.getRemoteIPAddress());
-		super.setForwardedAddresses(request.getForwardedAddresses());
-		super.setSessionId(request.getSessionId());
-	}
-}
-
-
-class RangerTagAuditEvent {
-	private final String tagType;
-	private final RangerAccessResult result;
-
-	RangerTagAuditEvent(String tagType, RangerAccessResult result) {
-		this.tagType = tagType;
-		this.result = result;
-	}
-	@Override
-	public String toString( ) {
-		StringBuilder sb = new StringBuilder();
-
-		toString(sb);
-
-		return sb.toString();
-	}
-
-	public void toString(StringBuilder sb) {
-		sb.append("RangerTagAuditEvent={");
-
-		sb.append("tagType={").append(this.tagType).append("} ");
-		sb.append("isAccessDetermined={").append(this.result.getIsAccessDetermined()).append("}");
-		sb.append("isAllowed={").append(this.result.getIsAllowed()).append("}");
-		sb.append("policyId={").append(this.result.getPolicyId()).append("}");
-		sb.append("reason={").append(this.result.getReason()).append("}");
-
-		sb.append("}");
-
-	}
-
-	static void processTagEvents(List<RangerTagAuditEvent> tagAuditEvents, final boolean deniedAccess) {
-		// Process tagAuditEvents to delete unwanted events
-
-		if (CollectionUtils.isEmpty(tagAuditEvents)) return;
-
-		List<RangerTagAuditEvent> unwantedEvents = new ArrayList<RangerTagAuditEvent> ();
-		if (deniedAccess) {
-			for (RangerTagAuditEvent auditEvent : tagAuditEvents) {
-				RangerAccessResult result = auditEvent.result;
-				if (result.getIsAllowed()) {
-					unwantedEvents.add(auditEvent);
-				}
-			}
-			tagAuditEvents.removeAll(unwantedEvents);
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
----------------------------------------------------------------------
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 ad9b23d..b08d4c5 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
@@ -372,13 +372,15 @@ class RangerPolicyRepository {
                 normalizeAndPrunePolicyItems(policy.getAllowExceptions(), componentType);
                 normalizeAndPrunePolicyItems(policy.getDenyExceptions(), componentType);
                 normalizeAndPrunePolicyItems(policy.getDataMaskPolicyItems(), componentType);
+                normalizeAndPrunePolicyItems(policy.getRowFilterPolicyItems(), componentType);
 
                 if (!policy.getIsAuditEnabled() &&
                     CollectionUtils.isEmpty(policy.getPolicyItems()) &&
                     CollectionUtils.isEmpty(policy.getDenyPolicyItems()) &&
                     CollectionUtils.isEmpty(policy.getAllowExceptions()) &&
                     CollectionUtils.isEmpty(policy.getDenyExceptions()) &&
-                    CollectionUtils.isEmpty(policy.getDataMaskPolicyItems())) {
+                    CollectionUtils.isEmpty(policy.getDataMaskPolicyItems()) &&
+                    CollectionUtils.isEmpty(policy.getRowFilterPolicyItems())) {
 
                     if(policiesToPrune == null) {
                         policiesToPrune = new ArrayList<RangerPolicy>();

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagAccessRequest.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagAccessRequest.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagAccessRequest.java
new file mode 100644
index 0000000..dbdcacd
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagAccessRequest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.policyengine;
+
+
+import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
+
+import java.util.Map;
+
+public class RangerTagAccessRequest extends RangerAccessRequestImpl {
+	private final RangerPolicyResourceMatcher.MatchType matchType;
+	public RangerTagAccessRequest(RangerTagForEval resourceTag, RangerServiceDef tagServiceDef, RangerAccessRequest request) {
+		matchType = resourceTag.getMatchType();
+		super.setResource(new RangerTagResource(resourceTag.getType(), tagServiceDef));
+		super.setUser(request.getUser());
+		super.setUserGroups(request.getUserGroups());
+		super.setAction(request.getAction());
+		super.setAccessType(request.getAccessType());
+		super.setAccessTime(request.getAccessTime());
+		super.setRequestData(request.getRequestData());
+
+		Map<String, Object> requestContext = request.getContext();
+
+		RangerAccessRequestUtil.setCurrentTagInContext(request.getContext(), resourceTag);
+		RangerAccessRequestUtil.setCurrentResourceInContext(request.getContext(), request.getResource());
+		RangerAccessRequestUtil.setCurrentUserInContext(request.getContext(), request.getUser());
+
+		super.setContext(requestContext);
+
+		super.setClientType(request.getClientType());
+		super.setClientIPAddress(request.getClientIPAddress());
+		super.setRemoteIPAddress(request.getRemoteIPAddress());
+		super.setForwardedAddresses(request.getForwardedAddresses());
+		super.setSessionId(request.getSessionId());
+	}
+	public RangerPolicyResourceMatcher.MatchType getMatchType() {
+		return matchType;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagResource.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagResource.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagResource.java
new file mode 100644
index 0000000..922f67d
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerTagResource.java
@@ -0,0 +1,33 @@
+/*
+ * 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.policyengine;
+
+
+import org.apache.ranger.plugin.model.RangerServiceDef;
+
+class RangerTagResource extends RangerAccessResourceImpl {
+	private static final String KEY_TAG = "tag";
+
+
+	public RangerTagResource(String tagType, RangerServiceDef tagServiceDef) {
+		super.setValue(KEY_TAG, tagType);
+		super.setServiceDef(tagServiceDef);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
index 7711765..59437a5 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
@@ -19,70 +19,9 @@
 
 package org.apache.ranger.plugin.policyevaluator;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.ranger.plugin.model.RangerPolicy;
-import org.apache.ranger.plugin.model.RangerServiceDef;
-import org.apache.ranger.plugin.policyengine.RangerAccessResource;
-import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
-
-import java.util.Map;
-
+/*
+ * this class is deprecated, as the functionality is moved to base class RangerOptimizedPolicyEvaluator.
+ * Keeping the class simply for backward compatibility, in case this is used anywhere
+ */
 public class RangerCachedPolicyEvaluator extends RangerOptimizedPolicyEvaluator {
-    private static final Log LOG = LogFactory.getLog(RangerCachedPolicyEvaluator.class);
-
-    private RangerResourceAccessCache cache = null;
-
-    @Override
-    public void init(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options) {
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerCachedPolicyEvaluator.init()");
-        }
-
-        super.init(policy, serviceDef, options);
-
-        cache = RangerResourceAccessCacheImpl.getInstance(serviceDef, policy);
-
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerCachedPolicyEvaluator.init()");
-        }
-    }
-
-    @Override
-    public boolean isMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerCachedPolicyEvaluator.isMatch(" + resource + ", " + evalContext + ")");
-        }
-
-        boolean result = false;
-
-        if (needsDynamicEval()) {
-            result = super.isMatch(resource, evalContext);
-        } else {
-            // Check in the evaluator-owned cache for the match, if found return. else call super.isMatch(), add result to cache
-            RangerResourceAccessCache.LookupResult lookup = cache.lookup(resource);
-
-            if (lookup != RangerResourceAccessCache.LookupResult.IN_NOTMATCHED_CACHE) {
-                // We dont know definitely that this previously not matched
-                if (lookup != RangerResourceAccessCache.LookupResult.IN_MATCHED_CACHE) {
-                    result = super.isMatch(resource, evalContext);
-
-                    // update the cache with the result of the match
-                    if (result) {
-                        cache.add(resource, RangerResourceAccessCache.CacheType.MATCHED_CACHE);
-                    } else {
-                        cache.add(resource, RangerResourceAccessCache.CacheType.NOTMATCHED_CACHE);
-                    }
-                } else {
-                    result = true;
-                }
-            }
-        }
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerCachedPolicyEvaluator.isMatch(" + resource + ", " + evalContext + "): " + result);
-        }
-
-        return result;
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
----------------------------------------------------------------------
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 899b216..ffb9523 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
@@ -49,6 +49,7 @@ import org.apache.ranger.plugin.policyengine.RangerDataMaskResult;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
 import org.apache.ranger.plugin.policyengine.RangerRowFilterResult;
+import org.apache.ranger.plugin.policyengine.RangerTagAccessRequest;
 import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
 import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
 import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
@@ -165,60 +166,36 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		}
 
         if (request != null && result != null) {
-            boolean isResourceMatch              = false;
-            boolean isResourceHeadMatch          = false;
-            boolean isResourceMatchAttempted     = false;
-            boolean isResourceHeadMatchAttempted = false;
-            final boolean attemptResourceHeadMatch = request.isAccessTypeAny() || request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS;
-
-            if (!result.getIsAuditedDetermined()) {
-                // Need to match request.resource first. If it matches (or head matches), then only more progress can be made
-                if (!isResourceMatchAttempted) {
-                    isResourceMatch = isMatch(request.getResource(), request.getContext());
-                    isResourceMatchAttempted = true;
-                }
 
-                // Try head match only if match was not found and ANY access was requested
-                if (!isResourceMatch) {
-                    if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-                        isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
-                        isResourceHeadMatchAttempted = true;
-                    }
-                }
-
-                if (isResourceMatch || isResourceHeadMatch) {
-                    // We are done for determining if audit is needed for this policy
-                    if (isAuditEnabled()) {
-                        result.setIsAudited(true);
-                        result.setAuditPolicyId(getPolicy().getId());
-                    }
-                }
-            }
-
-            if (!result.getIsAccessDetermined()) {
-                // Attempt resource matching only if there may be a matchable policyItem
-                if (hasMatchablePolicyItem(request)) {
-                    // Try Match only if it was not attempted as part of evaluating Audit requirement
-                    if (!isResourceMatchAttempted) {
-                        isResourceMatch = isMatch(request.getResource(), request.getContext());
-                        isResourceMatchAttempted = true;
-                    }
+			if (!result.getIsAccessDetermined() || !result.getIsAuditedDetermined()) {
+				RangerPolicyResourceMatcher.MatchType matchType = resourceMatcher != null ? resourceMatcher.getMatchType(request.getResource(), request.getContext()) : RangerPolicyResourceMatcher.MatchType.NONE;
 
-                    // Try Head Match only if no match was found so far AND a head match was not attempted as part of evaluating
-                    // Audit requirement
-                    if (!isResourceMatch) {
-                        if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-                            isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
-                            isResourceHeadMatchAttempted = true;
-                        }
-                    }
+				final boolean isMatched;
+				if (request.isAccessTypeAny()) {
+					isMatched = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
+				} else if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+					isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.DESCENDANT;
+				} else {
+					isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.ANCESTOR;
+				}
 
-                    // Go further to evaluate access only if match or head match was found at this point
-                    if (isResourceMatch || isResourceHeadMatch) {
-                        evaluatePolicyItems(request, result, isResourceMatch);
-                    }
-                }
-            }
+				if (isMatched) {
+					if (RangerTagAccessRequest.class.isInstance(request)) {
+						matchType = ((RangerTagAccessRequest) request).getMatchType();
+					}
+					if (!result.getIsAuditedDetermined()) {
+						if (isAuditEnabled()) {
+							result.setIsAudited(true);
+							result.setAuditPolicyId(getPolicy().getId());
+						}
+					}
+					if (!result.getIsAccessDetermined()) {
+						if (hasMatchablePolicyItem(request)) {
+							evaluatePolicyItems(request, result, matchType != RangerPolicyResourceMatcher.MatchType.DESCENDANT);
+						}
+					}
+				}
+			}
         }
 
 		RangerPerfTracer.log(perf);
@@ -241,48 +218,31 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		}
 
 		if (request != null && result != null && CollectionUtils.isNotEmpty(dataMaskEvaluators)) {
-			boolean isResourceMatchAttempted     = false;
-			boolean isResourceMatch              = false;
-			boolean isResourceHeadMatch          = false;
-			boolean isResourceHeadMatchAttempted = false;
-			final boolean attemptResourceHeadMatch = request.isAccessTypeAny() || request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS;
-
-			if (!result.getIsAuditedDetermined()) {
-				if (!isResourceMatchAttempted) {
-					isResourceMatch = isMatch(request.getResource(), request.getContext());
-					isResourceMatchAttempted = true;
-				}
 
-				if (!isResourceMatch) {
-					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-						isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
-						isResourceHeadMatchAttempted = true;
-					}
-				}
+			if (!result.getIsAccessDetermined() || !result.getIsAuditedDetermined()) {
+				RangerPolicyResourceMatcher.MatchType matchType = resourceMatcher != null ? resourceMatcher.getMatchType(request.getResource(), request.getContext()) : RangerPolicyResourceMatcher.MatchType.NONE;
 
-				if (isResourceMatch || isResourceHeadMatch) {
-					if (isAuditEnabled()) {
-						result.setIsAudited(true);
-						result.setAuditPolicyId(getPolicy().getId());
-					}
+				final boolean isMatched;
+				if (request.isAccessTypeAny()) {
+					isMatched = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
+				} else if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+					isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.DESCENDANT;
+				} else {
+					isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.ANCESTOR;
 				}
-			}
 
-			if (!result.getIsAccessDetermined()) {
-				if (!isResourceMatchAttempted) {
-					isResourceMatch = isMatch(request.getResource(), request.getContext());
-					isResourceMatchAttempted = true;
-				}
-
-				if (!isResourceMatch) {
-					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-						isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
-						isResourceHeadMatchAttempted = true;
+				if (isMatched) {
+					if (!result.getIsAuditedDetermined()) {
+						if (isAuditEnabled()) {
+							result.setIsAudited(true);
+							result.setAuditPolicyId(getPolicy().getId());
+						}
+					}
+					if (!result.getIsAccessDetermined()) {
+						if (hasMatchablePolicyItem(request)) {
+							evaluatePolicyItems(request, result);
+						}
 					}
-				}
-
-				if (isResourceMatch || isResourceHeadMatch) {
-					evaluatePolicyItems(request, result);
 				}
 			}
 
@@ -308,49 +268,31 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		}
 
 		if (request != null && result != null && CollectionUtils.isNotEmpty(rowFilterEvaluators)) {
-			boolean isResourceMatchAttempted     = false;
-			boolean isResourceMatch              = false;
-			boolean isResourceHeadMatch          = false;
-			boolean isResourceHeadMatchAttempted = false;
-			final boolean attemptResourceHeadMatch = request.isAccessTypeAny() || request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS;
-
-			if (!result.getIsAuditedDetermined()) {
-				if (!isResourceMatchAttempted) {
-					isResourceMatch = isMatch(request.getResource(), request.getContext());
-					isResourceMatchAttempted = true;
-				}
-
-				if (!isResourceMatch) {
-					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-						isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
-						isResourceHeadMatchAttempted = true;
-					}
+			if (!result.getIsAccessDetermined() || !result.getIsAuditedDetermined()) {
+				RangerPolicyResourceMatcher.MatchType matchType = resourceMatcher != null ? resourceMatcher.getMatchType(request.getResource(), request.getContext()) : RangerPolicyResourceMatcher.MatchType.NONE;
+
+				final boolean isMatched;
+				if (request.isAccessTypeAny()) {
+					isMatched = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
+				} else if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+					isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.DESCENDANT;
+				} else {
+					isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.ANCESTOR;
 				}
 
-				if (isResourceMatch || isResourceHeadMatch) {
-					if (isAuditEnabled()) {
-						result.setIsAudited(true);
-						result.setAuditPolicyId(getPolicy().getId());
+				if (isMatched) {
+					if (!result.getIsAuditedDetermined()) {
+						if (isAuditEnabled()) {
+							result.setIsAudited(true);
+							result.setAuditPolicyId(getPolicy().getId());
+						}
 					}
-				}
-			}
-
-			if (!result.getIsAccessDetermined()) {
-				if (!isResourceMatchAttempted) {
-					isResourceMatch = isMatch(request.getResource(), request.getContext());
-					isResourceMatchAttempted = true;
-				}
-
-				if (!isResourceMatch) {
-					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-						isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
-						isResourceHeadMatchAttempted = true;
+					if (!result.getIsAccessDetermined()) {
+						if (hasMatchablePolicyItem(request)) {
+							evaluatePolicyItems(request, result);
+						}
 					}
 				}
-
-				if (isResourceMatch || isResourceHeadMatch) {
-					evaluatePolicyItems(request, result);
-				}
 			}
 		}
 
@@ -467,12 +409,19 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("==> RangerDefaultPolicyEvaluator.getResourceAccessInfo(" + request + ", " + result + ")");
 		}
+		RangerPolicyResourceMatcher.MatchType matchType = resourceMatcher != null ? resourceMatcher.getMatchType(request.getResource(), request.getContext()) : RangerPolicyResourceMatcher.MatchType.NONE;
 
-		final boolean isResourceMatch          = isMatch(request.getResource(), request.getContext());
-		final boolean attemptResourceHeadMatch = request.isAccessTypeAny() || request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS;
-		final boolean isResourceHeadMatch      = (!isResourceMatch && attemptResourceHeadMatch) ? matchResourceHead(request.getResource(), request.getContext()) : false;
+		final boolean isMatched;
+		if (request.isAccessTypeAny()) {
+				isMatched = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
+			} else if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+				isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.DESCENDANT;
+			} else {
+			isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.ANCESTOR;
+		}
+
+		if (isMatched) {
 
-		if(isResourceMatch || isResourceHeadMatch) {
 			if (CollectionUtils.isNotEmpty(allowEvaluators)) {
 				Set<String> users = new HashSet<String>();
 				Set<String> groups = new HashSet<String>();
@@ -492,27 +441,26 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 				result.getAllowedUsers().addAll(users);
 				result.getAllowedGroups().addAll(groups);
 			}
-		}
+			if (matchType != RangerPolicyResourceMatcher.MatchType.DESCENDANT) {
+				if (CollectionUtils.isNotEmpty(denyEvaluators)) {
+					Set<String> users = new HashSet<String>();
+					Set<String> groups = new HashSet<String>();
 
-		if(isResourceMatch) {
-			if(CollectionUtils.isNotEmpty(denyEvaluators)) {
-				Set<String> users  = new HashSet<String>();
-				Set<String> groups = new HashSet<String>();
+					getResourceAccessInfo(request, denyEvaluators, users, groups);
 
-				getResourceAccessInfo(request, denyEvaluators, users, groups);
+					if (CollectionUtils.isNotEmpty(denyExceptionEvaluators)) {
+						Set<String> exceptionUsers = new HashSet<String>();
+						Set<String> exceptionGroups = new HashSet<String>();
 
-				if(CollectionUtils.isNotEmpty(denyExceptionEvaluators)) {
-					Set<String> exceptionUsers  = new HashSet<String>();
-					Set<String> exceptionGroups = new HashSet<String>();
+						getResourceAccessInfo(request, denyExceptionEvaluators, exceptionUsers, exceptionGroups);
 
-					getResourceAccessInfo(request, denyExceptionEvaluators, exceptionUsers, exceptionGroups);
+						users.removeAll(exceptionUsers);
+						groups.removeAll(exceptionGroups);
+					}
 
-					users.removeAll(exceptionUsers);
-					groups.removeAll(exceptionGroups);
+					result.getDeniedUsers().addAll(users);
+					result.getDeniedGroups().addAll(groups);
 				}
-
-				result.getDeniedUsers().addAll(users);
-				result.getDeniedGroups().addAll(groups);
 			}
 		}
 
@@ -652,25 +600,6 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		}
 	}
 
-
-	protected boolean matchResourceHead(RangerAccessResource resource, Map<String, Object> evalContext) {
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ", " + evalContext + ")");
-		}
-
-		boolean ret = false;
-
-		if(resourceMatcher != null) {
-			ret = resourceMatcher.isHeadMatch(resource, evalContext);
-		}
-
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ", " + evalContext + "): " + ret);
-		}
-
-		return ret;
-	}
-
 	protected boolean isMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + resources + ", " + evalContext + ")");
@@ -749,6 +678,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		preprocessPolicyItems(policy.getAllowExceptions(), impliedAccessGrants);
 		preprocessPolicyItems(policy.getDenyExceptions(), impliedAccessGrants);
 		preprocessPolicyItems(policy.getDataMaskPolicyItems(), impliedAccessGrants);
+		preprocessPolicyItems(policy.getRowFilterPolicyItems(), impliedAccessGrants);
 	}
 
 	private void preprocessPolicyItems(List<? extends RangerPolicyItem> policyItems, Map<String, Collection<String>> impliedAccessGrants) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
index 6119dbc..cace981 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
@@ -20,6 +20,7 @@ package org.apache.ranger.plugin.policyevaluator;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -52,6 +53,7 @@ public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEv
 
 	private boolean hasCurrentUser = false;
 	private boolean hasResourceOwner = false;
+	private boolean hasAllPerms = false;
 
 	public RangerDefaultPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerPolicyItem policyItem, int policyItemType, int policyItemIndex, RangerPolicyEngineOptions options) {
 		super(serviceDef, policy, policyItem, policyItemType, policyItemIndex, options);
@@ -62,6 +64,26 @@ public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEv
 			LOG.debug("==> RangerDefaultPolicyItemEvaluator(policyId=" + policyId + ", policyItem=" + policyItem + ", serviceType=" + getServiceType() + ", conditionsDisabled=" + getConditionsDisabledOption() + ")");
 		}
 
+		Set<String> accessPerms    = new HashSet<String>();
+
+		List<RangerPolicy.RangerPolicyItemAccess> policyItemAccesses = policyItem.getAccesses();
+		for(RangerPolicy.RangerPolicyItemAccess policyItemAccess : policyItemAccesses) {
+
+			if (policyItemAccess.getIsAllowed()) {
+				accessPerms.add(policyItemAccess.getType());
+			}
+		}
+
+		hasAllPerms = true;
+		List<RangerServiceDef.RangerAccessTypeDef> serviceAccessTypes = serviceDef.getAccessTypes();
+		for (RangerServiceDef.RangerAccessTypeDef serviceAccessType : serviceAccessTypes) {
+			String serviceAccessTypeName = serviceAccessType.getName();
+			if (!accessPerms.contains(serviceAccessTypeName)) {
+				hasAllPerms = false;
+				break;
+			}
+		}
+
 		if (!getConditionsDisabledOption() && policyItem != null && CollectionUtils.isNotEmpty(policyItem.getConditions())) {
 			conditionEvaluators = new ArrayList<RangerConditionEvaluator>();
 
@@ -138,10 +160,16 @@ public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEv
 					boolean isAccessTypeMatched = false;
 
 					if (request.isAccessTypeAny()) {
-						for (RangerPolicy.RangerPolicyItemAccess access : policyItem.getAccesses()) {
-							if (access.getIsAllowed()) {
+						if (getPolicyItemType() == POLICY_ITEM_TYPE_DENY || getPolicyItemType() == POLICY_ITEM_TYPE_DENY_EXCEPTIONS) {
+							if (hasAllPerms) {
 								isAccessTypeMatched = true;
-								break;
+							}
+						} else {
+							for (RangerPolicy.RangerPolicyItemAccess access : policyItem.getAccesses()) {
+								if (access.getIsAllowed()) {
+									isAccessTypeMatched = true;
+									break;
+								}
 							}
 						}
 					} else {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
index 1fcd08e..b8cb864 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
@@ -76,6 +76,7 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
         preprocessPolicyItems(policy.getAllowExceptions());
         preprocessPolicyItems(policy.getDenyExceptions());
         preprocessPolicyItems(policy.getDataMaskPolicyItems());
+        preprocessPolicyItems(policy.getRowFilterPolicyItems());
 
         hasAllPerms = checkIfHasAllPerms();
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
----------------------------------------------------------------------
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 3b831c3..7b1fb8b 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
@@ -50,6 +50,16 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 	private Map<String, RangerResourceMatcher> matchers = null;
 	private boolean                            needsDynamicEval = false;
 	private List<RangerResourceDef> firstValidResourceDefHierarchy;
+	/*
+	 * For hive resource policy:
+	 * 	lastNonAnyMatcherIndex will be set to
+	 * 		0 : if all matchers in policy are '*'; such as database=*, table=*, column=*
+	 * 		1 : database=hr, table=*, column=*
+	 * 		2 : database=<any>, table=employee, column=*
+	 * 		3 : database=<any>, table=<any>, column=ssn
+	 */
+	private int lastNonAnyMatcherIndex = 0;
+
 
 	@Override
 	public void setServiceDef(RangerServiceDef serviceDef) {
@@ -143,6 +153,9 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 									needsDynamicEval = true;
 								}
 								matchers.put(resourceName, matcher);
+								if (!matcher.isMatchAny()) {
+									lastNonAnyMatcherIndex = matchers.size();
+								}
 							} else {
 								LOG.error("failed to find matcher for resource " + resourceName);
 							}
@@ -198,51 +211,6 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 		return matchers != null ? matchers.get(resourceName) : null;
 	}
 
-	public boolean isMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isMatch(" + resource + ", " + evalContext + ")");
-		}
-
-		boolean ret = false;
-
-		if(serviceDef != null && serviceDef.getResources() != null) {
-			Collection<String> resourceKeys = resource == null ? null : resource.getKeys();
-			Collection<String> policyKeys   = matchers == null ? null : matchers.keySet();
-
-			boolean keysMatch = CollectionUtils.isEmpty(resourceKeys) || (policyKeys != null && policyKeys.containsAll(resourceKeys));
-
-			if(keysMatch) {
-				for(RangerResourceDef resourceDef : serviceDef.getResources()) {
-					String                resourceName  = resourceDef.getName();
-					String                resourceValue = resource == null ? null : resource.getValue(resourceName);
-					RangerResourceMatcher matcher       = matchers == null ? null : matchers.get(resourceName);
-
-					// when no value exists for a resourceName, consider it a match only if: policy doesn't have a matcher OR matcher allows no-value resource
-					if(StringUtils.isEmpty(resourceValue)) {
-						ret = matcher == null || matcher.isMatch(resourceValue, evalContext);
-					} else {
-						ret = matcher != null && matcher.isMatch(resourceValue, evalContext);
-					}
-
-					if(! ret) {
-						break;
-					}
-				}
-			} else {
-				if(LOG.isDebugEnabled()) {
-					LOG.debug("isMatch(): keysMatch=false. isMatch=" + resourceKeys + "; policyKeys=" + policyKeys);
-				}
-			}
-		}
-
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isMatch(" + resource  + ", " + evalContext + "): " + ret);
-		}
-
-		return ret;
-	}
-
-
 	@Override
 	public boolean isMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
@@ -343,119 +311,197 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 	}
 
 	@Override
-	public boolean isHeadMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
-
+	public boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isHeadMatch(" + resource + ", " + evalContext + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
 
-		if (matchers == null) {
-
-			LOG.debug("RangerDefaultPolicyResourceMatcher.isHeadMatch(): PolicyResourceMatcher not initialized correctly!!!");
-			ret = false;
+		if(serviceDef != null && serviceDef.getResources() != null) {
+			Collection<String> resourceKeys = resources == null ? null : resources.keySet();
+			Collection<String> policyKeys   = matchers == null ? null : matchers.keySet();
 
-		} else if (resource == null || CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling
+			boolean keysMatch = false;
 
-			LOG.debug("RangerDefaultPolicyResourceMatcher.isHeadMatch: resource was null/empty!");
-			ret = true; // null resource matches anything
+			if (resourceKeys != null && policyKeys != null) {
+				keysMatch = CollectionUtils.isEqualCollection(resourceKeys, policyKeys);
+			}
 
-		} else {
+			if(keysMatch) {
+				for(RangerResourceDef resourceDef : serviceDef.getResources()) {
+					String                resourceName   = resourceDef.getName();
+					RangerPolicyResource  resourceValues = resources == null ? null : resources.get(resourceName);
+					RangerPolicyResource  policyValues   = policyResources == null ? null : policyResources.get(resourceName);
 
-			ret = newIsHeadMatch(resource, evalContext);
+					if(resourceValues == null || CollectionUtils.isEmpty(resourceValues.getValues())) {
+						ret = (policyValues == null || CollectionUtils.isEmpty(policyValues.getValues()));
+					} else if(policyValues != null && CollectionUtils.isNotEmpty(policyValues.getValues())) {
+						ret = CollectionUtils.isEqualCollection(resourceValues.getValues(), policyValues.getValues());
+					}
 
+					if(! ret) {
+						break;
+					}
+				}
+			} else {
+				if(LOG.isDebugEnabled()) {
+					LOG.debug("isCompleteMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys);
+				}
+			}
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.matchResourceHead(" + resource + ", " + evalContext  + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;
 	}
 
 	@Override
-	public boolean isExactHeadMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
-
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ", " + evalContext + ")");
-		}
+	public boolean isMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
+		return isMatch(resource, MatchScope.SELF_OR_ANCESTOR, evalContext);
+	}
 
-		boolean ret = false;
+	@Override
+	public boolean isMatch(RangerAccessResource resource, MatchScope scope, Map<String, Object> evalContext) {
 
-		if (matchers == null) {
+		final boolean ret;
 
-			LOG.debug("RangerDefaultPolicyResourceMatcher.isExactHeadMatch(): PolicyResourceMatcher not initialized correctly!!!");
-			ret = false;
+		MatchType matchType = getMatchType(resource, evalContext);
+		switch(scope) {
+			case SELF_OR_ANCESTOR_OR_DESCENDANT: {
+				ret = matchType != MatchType.NONE;
+				break;
+			}
+			case SELF: {
+				ret = matchType == MatchType.SELF;
+				break;
+			}
+			case SELF_OR_DESCENDANT: {
+				ret = matchType == MatchType.SELF || matchType == MatchType.DESCENDANT;
+				break;
+			}
+			case SELF_OR_ANCESTOR: {
+				ret = matchType == MatchType.SELF || matchType == MatchType.ANCESTOR;
+				break;
+			}
+			case DESCENDANT: {
+				ret = matchType == MatchType.DESCENDANT;
+				break;
+			}
+			case ANCESTOR: {
+				ret = matchType == MatchType.ANCESTOR;
+				break;
+			}
+			default:
+				ret = matchType != MatchType.NONE;
+				break;
+		}
 
-		} else if (resource == null || CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling
+		return ret;
+	}
 
-			LOG.debug("RangerDefaultPolicyResourceMatcher.isExactHeadMatch: resource was null/empty!");
-			ret = false;
+	@Override
+	public MatchType getMatchType(RangerAccessResource resource, Map<String, Object> evalContext) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.getMatchType(" + resource + evalContext + ")");
+		}
 
-		} else if (matchers.size() > resource.getKeys().size()) {
+		int matchersSize = matchers == null ? 0 : matchers.size();
+		int resourceKeysSize = resource == null || resource.getKeys() == null ? 0 : resource.getKeys().size();
 
-			LOG.debug("RangerDefaultPolicyResourceMatcher.isExactHeadMatch: more levels specified in PolicyResourceMatcher than in resource being matched!!");
-			ret = false;
+		MatchType ret = MatchType.NONE;
 
+		if (!isValid(resource)) {
+			ret = MatchType.NONE;
+		} else if (matchersSize == 0) {
+			ret = resourceKeysSize == 0 ? MatchType.SELF : MatchType.ANCESTOR;
+		} else if (lastNonAnyMatcherIndex == 0) {
+			ret = MatchType.ANCESTOR;
+		} else if (resourceKeysSize == 0) {
+			ret = MatchType.DESCENDANT;
 		} else {
-
-			ret = newIsHeadMatch(resource, evalContext);
+			int index = 0;
+			for (RangerResourceDef resourceDef : firstValidResourceDefHierarchy) {
+
+				String resourceName = resourceDef.getName();
+				RangerResourceMatcher matcher = matchers.get(resourceName);
+				String resourceValue = resource.getValue(resourceName);
+
+				if (resourceValue != null) {
+					if (matcher != null) {
+						index++;
+						if (matcher.isMatch(resourceValue, evalContext)) {
+							ret = index == resourceKeysSize && matcher.isMatchAny() ? MatchType.ANCESTOR : MatchType.SELF;
+						} else {
+							ret = MatchType.NONE;
+							break;
+						}
+					} else {
+						// More resource-levels than matchers
+						ret = MatchType.ANCESTOR;
+						break;
+					}
+				} else {
+					if (matcher != null) {
+						// More matchers than resource-levels
+						if (index >= lastNonAnyMatcherIndex) {
+							// All AnyMatch matchers after this
+							ret = MatchType.ANCESTOR;
+						} else {
+							ret = MatchType.DESCENDANT;
+						}
+					}
+					break;
+				}
+			}
 
 		}
 
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ", " + evalContext + ")" + ret);
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.getMatchType(" + resource + evalContext + "): " + ret);
 		}
 
 		return ret;
 	}
 
-	private boolean newIsHeadMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
-
+	private boolean isValid(RangerAccessResource resource) {
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + ", " + evalContext + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isValid(" + resource + ")");
 		}
 
+		boolean ret = true;
 		boolean skipped = false;
-		boolean matched = true;
-
-		for (RangerResourceDef resourceDef : firstValidResourceDefHierarchy) {
-
-			String resourceName = resourceDef.getName();
-			String resourceValue = resource.getValue(resourceName);
-			RangerResourceMatcher matcher = matchers.get(resourceName);
-
-			if (matcher != null) {
 
-				if (StringUtils.isNotBlank(resourceValue)) {
+		if (matchers != null && resource != null && resource.getKeys() != null) {
+			if (matchers.keySet().containsAll(resource.getKeys()) || resource.getKeys().containsAll(matchers.keySet())) {
+				for (RangerResourceDef resourceDef : firstValidResourceDefHierarchy) {
 
-					if (!skipped) {
-
-						matched = matcher.isMatch(resourceValue, evalContext);
+					String resourceName = resourceDef.getName();
+					String resourceValue = resource.getValue(resourceName);
 
+					if (resourceValue == null) {
+						if (!skipped) {
+							skipped = true;
+						}
 					} else {
-
-						matched = false;
-
+						if (skipped) {
+							ret = false;
+							break;
+						}
 					}
-				} else {
-
-					skipped = true;
 
 				}
-			}
-
-			if (!matched) {
-				break;
+			} else {
+				ret = false;
 			}
 		}
-
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + ", " + evalContext + "): " + matched);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isValid(" + resource + "): " + ret);
 		}
 
-		return matched;
+		return ret;
 	}
 
 	@Override
@@ -527,51 +573,4 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 		return ret;
 	}
 
-	@Override
-	public boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext) {
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ", " + evalContext + ")");
-		}
-
-		boolean ret = false;
-
-		if(serviceDef != null && serviceDef.getResources() != null) {
-			Collection<String> resourceKeys = resources == null ? null : resources.keySet();
-			Collection<String> policyKeys   = matchers == null ? null : matchers.keySet();
-
-			boolean keysMatch = false;
-
-			if (resourceKeys != null && policyKeys != null) {
-				keysMatch = CollectionUtils.isEqualCollection(resourceKeys, policyKeys);
-			}
-
-			if(keysMatch) {
-				for(RangerResourceDef resourceDef : serviceDef.getResources()) {
-					String                resourceName   = resourceDef.getName();
-					RangerPolicyResource  resourceValues = resources == null ? null : resources.get(resourceName);
-					RangerPolicyResource  policyValues   = policyResources == null ? null : policyResources.get(resourceName);
-
-					if(resourceValues == null || CollectionUtils.isEmpty(resourceValues.getValues())) {
-						ret = (policyValues == null || CollectionUtils.isEmpty(policyValues.getValues()));
-					} else if(policyValues != null && CollectionUtils.isNotEmpty(policyValues.getValues())) {
-						ret = CollectionUtils.isEqualCollection(resourceValues.getValues(), policyValues.getValues());
-					}
-
-					if(! ret) {
-						break;
-					}
-				}
-			} else {
-				if(LOG.isDebugEnabled()) {
-					LOG.debug("isCompleteMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys);
-				}
-			}
-		}
-
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ", " + evalContext + "): " + ret);
-		}
-
-		return ret;
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
index 00f8f9a..8a784b4 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
@@ -28,6 +28,9 @@ import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
 
 public interface RangerPolicyResourceMatcher {
+	enum MatchScope { SELF_OR_ANCESTOR_OR_DESCENDANT, SELF, SELF_OR_DESCENDANT, SELF_OR_ANCESTOR, DESCENDANT, ANCESTOR };
+	enum MatchType { NONE, SELF, DESCENDANT, ANCESTOR };
+
 	void setServiceDef(RangerServiceDef serviceDef);
 
 	void setPolicy(RangerPolicy policy);
@@ -44,11 +47,11 @@ public interface RangerPolicyResourceMatcher {
 
 	boolean isMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext);
 
-	boolean isCompleteMatch(RangerAccessResource resource, Map<String, Object> evalContext);
+	boolean isMatch(RangerAccessResource resource, MatchScope scope, Map<String, Object> evalContext);
 
-	boolean isHeadMatch(RangerAccessResource resource, Map<String, Object> evalContext);
+	MatchType getMatchType(RangerAccessResource resource, Map<String, Object> evalContext);
 
-	boolean isExactHeadMatch(RangerAccessResource resource, Map<String, Object> evalContext);
+	boolean isCompleteMatch(RangerAccessResource resource, Map<String, Object> evalContext);
 
 	boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
index 9219450..a46d975 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
@@ -27,7 +27,7 @@ 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.RangerTag;
+import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 
 public class RangerAccessRequestUtil {
@@ -40,7 +40,7 @@ public class RangerAccessRequestUtil {
 	public static final String KEY_TOKEN_NAMESPACE = "token:";
 	public static final String KEY_USER = "USER";
 
-	public static void setRequestTagsInContext(Map<String, Object> context, List<RangerTag> tags) {
+	public static void setRequestTagsInContext(Map<String, Object> context, List<RangerTagForEval> tags) {
 		if(CollectionUtils.isEmpty(tags)) {
 			context.remove(KEY_CONTEXT_TAGS);
 		} else {
@@ -48,14 +48,14 @@ public class RangerAccessRequestUtil {
 		}
 	}
 
-	public static List<RangerTag> getRequestTagsFromContext(Map<String, Object> context) {
-		List<RangerTag> ret = null;
+	public static List<RangerTagForEval> getRequestTagsFromContext(Map<String, Object> context) {
+		List<RangerTagForEval> ret = null;
 		Object          val = context.get(RangerAccessRequestUtil.KEY_CONTEXT_TAGS);
 
 		if (val != null && val instanceof List<?>) {
 			try {
 				@SuppressWarnings("unchecked")
-				List<RangerTag> tags = (List<RangerTag>) val;
+				List<RangerTagForEval> tags = (List<RangerTagForEval>) val;
 
 				ret = tags;
 			} catch (Throwable t) {
@@ -66,16 +66,16 @@ public class RangerAccessRequestUtil {
 		return ret;
 	}
 
-	public static void setCurrentTagInContext(Map<String, Object> context, RangerTag tag) {
+	public static void setCurrentTagInContext(Map<String, Object> context, RangerTagForEval tag) {
 		context.put(KEY_CONTEXT_TAG_OBJECT, tag);
 	}
 
-	public static RangerTag getCurrentTagFromContext(Map<String, Object> context) {
-		RangerTag ret = null;
+	public static RangerTagForEval getCurrentTagFromContext(Map<String, Object> context) {
+		RangerTagForEval ret = null;
 		Object    val = context.get(KEY_CONTEXT_TAGS);
 
-		if(val != null && val instanceof RangerTag) {
-			ret = (RangerTag)val;
+		if(val != null && val instanceof RangerTagForEval) {
+			ret = (RangerTagForEval)val;
 		}
 
 		return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java
index 30190ab..3454c30 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java
@@ -102,12 +102,12 @@ public class TestTagEnricher {
 
 
         for (TestData test : testCase.tests) {
-            RangerAccessRequestImpl request = new RangerAccessRequestImpl(test.resource, "", "testUser", null);
+            RangerAccessRequestImpl request = new RangerAccessRequestImpl(test.resource, test.accessType, "testUser", null);
 
             tagEnricher.enrich(request);
 
             List<RangerTag> expected = test.result;
-            List<RangerTag> result   = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
+            List<RangerTagForEval> result   = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
 
             expectedTags.clear();
             if(expected != null) {
@@ -119,7 +119,7 @@ public class TestTagEnricher {
 
             resultTags.clear();
             if(result != null) {
-                for(RangerTag tag : result) {
+                for(RangerTagForEval tag : result) {
                     resultTags.add(tag.getType());
                 }
                 Collections.sort(resultTags);
@@ -142,6 +142,7 @@ public class TestTagEnricher {
         class TestData {
             public String               name;
             public RangerAccessResource resource;
+            public String               accessType;
             public List<RangerTag>      result;
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8b3f0e60/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
----------------------------------------------------------------------
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 2ae280d..71e2eb6 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
@@ -32,8 +32,8 @@ import org.apache.ranger.audit.provider.AuditHandler;
 import org.apache.ranger.audit.provider.AuditProviderFactory;
 import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
 import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
+import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
 import org.apache.ranger.plugin.model.RangerPolicy;
-import org.apache.ranger.plugin.model.RangerTag;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.policyengine.TestPolicyEngine.PolicyEngineTestCase.TestData;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
@@ -250,6 +250,13 @@ public class TestPolicyEngine {
 	}
 
 	@Test
+	public void testPolicyEngine_descendant_tags() {
+		String[] resourceFiles = {"/policyengine/test_policyengine_descendant_tags.json"};
+
+		runTestsFromResourceFiles(resourceFiles);
+	}
+
+	@Test
 	public void testPolicyEngine_hiveMasking() {
 		String[] resourceFiles = {"/policyengine/test_policyengine_hive_mask_filter.json"};
 
@@ -343,9 +350,9 @@ public class TestPolicyEngine {
 
 				if(!StringUtils.isEmpty(tagsJsonString)) {
 					try {
-						Type listType = new TypeToken<List<RangerTag>>() {
+						Type listType = new TypeToken<List<RangerTagForEval>>() {
 						}.getType();
-						List<RangerTag> tagList = gsonBuilder.fromJson(tagsJsonString, listType);
+						List<RangerTagForEval> tagList = gsonBuilder.fromJson(tagsJsonString, listType);
 
 						context.put(RangerAccessRequestUtil.KEY_CONTEXT_TAGS, tagList);
 					} catch (Exception e) {