diff --git a/pkg/engine/rbacValidation.go b/pkg/engine/rbacValidation.go
new file mode 100644
index 0000000000..516ef607d5
--- /dev/null
+++ b/pkg/engine/rbacValidation.go
@@ -0,0 +1,112 @@
+package engine
+
+import (
+	"reflect"
+
+	kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
+	utils "github.com/nirmata/kyverno/pkg/utils"
+	authenticationv1 "k8s.io/api/authentication/v1"
+	rbacv1 "k8s.io/api/rbac/v1"
+)
+
+const (
+	SaPrefix = "system:serviceaccounts:"
+)
+
+// matchAdmissionInfo return true if the rule can be applied to the request
+func matchAdmissionInfo(rule kyverno.Rule, requestInfo RequestInfo) bool {
+	// when processing existing resource, it does not contain requestInfo
+	// skip permission checking
+	if reflect.DeepEqual(requestInfo, RequestInfo{}) {
+		return true
+	}
+
+	if !validateMatch(rule.MatchResources, requestInfo) {
+		return false
+	}
+
+	return validateExclude(rule.ExcludeResources, requestInfo)
+}
+
+// match:
+// 		roles: role1, role2
+// 		clusterRoles: clusterRole1,clusterRole2
+// 		subjects: subject1, subject2
+// validateMatch return true if (role1 || role2) and (clusterRole1 || clusterRole2)
+// and (subject1 || subject2) are found in requestInfo, OR operation for each list
+func validateMatch(match kyverno.MatchResources, requestInfo RequestInfo) bool {
+	if len(match.Roles) > 0 {
+		if !matchRoleRefs(match.Roles, requestInfo.Roles) {
+			return false
+		}
+	}
+
+	if len(match.ClusterRoles) > 0 {
+		if !matchRoleRefs(match.ClusterRoles, requestInfo.ClusterRoles) {
+			return false
+		}
+	}
+
+	if len(match.Subjects) > 0 {
+		if !matchSubjects(match.Subjects, requestInfo.AdmissionUserInfo) {
+			return false
+		}
+	}
+	return true
+}
+
+// exclude:
+// 		roles: role1, role2
+// 		clusterRoles: clusterRole1,clusterRole2
+// 		subjects: subject1, subject2
+// validateExclude return true if none of the above found in requestInfo
+// otherwise return false immediately means rule should not be applied
+func validateExclude(exclude kyverno.ExcludeResources, requestInfo RequestInfo) bool {
+	if len(exclude.Roles) > 0 {
+		if matchRoleRefs(exclude.Roles, requestInfo.Roles) {
+			return false
+		}
+	}
+
+	if len(exclude.ClusterRoles) > 0 {
+		if matchRoleRefs(exclude.ClusterRoles, requestInfo.ClusterRoles) {
+			return false
+		}
+	}
+
+	if len(exclude.Subjects) > 0 {
+		if matchSubjects(exclude.Subjects, requestInfo.AdmissionUserInfo) {
+			return false
+		}
+	}
+	return true
+}
+
+// matchRoleRefs return true if one of ruleRoleRefs exist in resourceRoleRefs
+func matchRoleRefs(ruleRoleRefs, resourceRoleRefs []string) bool {
+	for _, ruleRoleRef := range ruleRoleRefs {
+		if utils.ContainsString(resourceRoleRefs, ruleRoleRef) {
+			return true
+		}
+	}
+	return false
+}
+
+// matchSubjects return true if one of ruleSubjects exist in userInfo
+func matchSubjects(ruleSubjects []rbacv1.Subject, userInfo authenticationv1.UserInfo) bool {
+	userGroups := append(userInfo.Groups, userInfo.Username)
+	for _, subject := range ruleSubjects {
+		switch subject.Kind {
+		case "ServiceAccount":
+			subjectServiceAccount := subject.Namespace + ":" + subject.Name
+			if userInfo.Username[len(SaPrefix):] == subjectServiceAccount {
+				return true
+			}
+		case "User", "Group":
+			if utils.ContainsString(userGroups, subject.Name) {
+				return true
+			}
+		}
+	}
+	return false
+}