diff --git a/pkg/engine/anchor/anchor.go b/pkg/engine/anchor/anchor.go
index 95d1f9d15a..5dc175e47e 100644
--- a/pkg/engine/anchor/anchor.go
+++ b/pkg/engine/anchor/anchor.go
@@ -1,277 +1,123 @@
 package anchor
 
 import (
-	"fmt"
-	"strconv"
-
-	"github.com/go-logr/logr"
-	"github.com/kyverno/kyverno/pkg/logging"
+	"regexp"
+	"strings"
 )
 
-// ValidationHandler for element processes
-type ValidationHandler interface {
-	Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorKey) (string, error)
+type AnchorType string
+
+const (
+	Condition       AnchorType = ""
+	Global          AnchorType = "<"
+	Negation        AnchorType = "X"
+	AddIfNotPresent AnchorType = "+"
+	Equality        AnchorType = "="
+	Existence       AnchorType = "^"
+)
+
+var regex = regexp.MustCompile(`^(?P<modifier>[+<=X^])?\((?P<key>.+)\)$`)
+
+// Anchor interface
+type Anchor interface {
+	// Type returns the anchor type
+	Type() AnchorType
+	// Key returns the anchor key
+	Key() string
+	// String returns the anchor string
+	String() string
 }
 
-type resourceElementHandler = func(log logr.Logger, resourceElement, patternElement, originPattern interface{}, path string, ac *AnchorKey) (string, error)
+type anchor struct {
+	modifier AnchorType
+	key      string
+}
 
-// CreateElementHandler factory to process elements
-func CreateElementHandler(element string, pattern interface{}, path string) ValidationHandler {
-	switch {
-	case IsConditionAnchor(element):
-		return NewConditionAnchorHandler(element, pattern, path)
-	case IsGlobalAnchor(element):
-		return NewGlobalAnchorHandler(element, pattern, path)
-	case IsExistenceAnchor(element):
-		return NewExistenceHandler(element, pattern, path)
-	case IsEqualityAnchor(element):
-		return NewEqualityHandler(element, pattern, path)
-	case IsNegationAnchor(element):
-		return NewNegationHandler(element, pattern, path)
-	default:
-		return NewDefaultHandler(element, pattern, path)
+// Parse parses a string, returns nil if not an anchor
+func Parse(str string) Anchor {
+	str = strings.TrimSpace(str)
+	values := regex.FindStringSubmatch(str)
+	if len(values) == 0 {
+		return nil
+	}
+	return New(AnchorType(values[1]), values[2])
+}
+
+// New creates an anchor
+func New(modifier AnchorType, key string) Anchor {
+	if key == "" {
+		return nil
+	}
+	return anchor{
+		modifier: modifier,
+		key:      key,
 	}
 }
 
-// NewNegationHandler returns instance of negation handler
-func NewNegationHandler(anchor string, pattern interface{}, path string) ValidationHandler {
-	return NegationHandler{
-		anchor:  anchor,
-		pattern: pattern,
-		path:    path,
+// String returns the anchor string.
+// Will return an empty string if key is empty.
+func String(modifier AnchorType, key string) string {
+	if key == "" {
+		return ""
 	}
+	return string(modifier) + "(" + key + ")"
 }
 
-// NegationHandler provides handler for check if the tag in anchor is not defined
-type NegationHandler struct {
-	anchor  string
-	pattern interface{}
-	path    string
+func (a anchor) Type() AnchorType {
+	return a.modifier
 }
 
-// Handle process negation handler
-func (nh NegationHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorKey) (string, error) {
-	anchorKey, _ := RemoveAnchor(nh.anchor)
-	currentPath := nh.path + anchorKey + "/"
-	// if anchor is present in the resource then fail
-	if _, ok := resourceMap[anchorKey]; ok {
-		// no need to process elements in value as key cannot be present in resource
-		ac.AnchorError = NewNegationAnchorError(fmt.Sprintf("%s is not allowed", currentPath))
-		return currentPath, ac.AnchorError.Error()
-	}
-	// key is not defined in the resource
-	return "", nil
+func (a anchor) Key() string {
+	return a.key
 }
 
-// NewEqualityHandler returens instance of equality handler
-func NewEqualityHandler(anchor string, pattern interface{}, path string) ValidationHandler {
-	return EqualityHandler{
-		anchor:  anchor,
-		pattern: pattern,
-		path:    path,
-	}
+func (a anchor) String() string {
+	return String(a.modifier, a.key)
 }
 
-// EqualityHandler provides handler for non anchor element
-type EqualityHandler struct {
-	anchor  string
-	pattern interface{}
-	path    string
-}
-
-// Handle processed condition anchor
-func (eh EqualityHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorKey) (string, error) {
-	anchorKey, _ := RemoveAnchor(eh.anchor)
-	currentPath := eh.path + anchorKey + "/"
-	// check if anchor is present in resource
-	if value, ok := resourceMap[anchorKey]; ok {
-		// validate the values of the pattern
-		returnPath, err := handler(logging.GlobalLogger(), value, eh.pattern, originPattern, currentPath, ac)
-		if err != nil {
-			return returnPath, err
-		}
-		return "", nil
-	}
-	return "", nil
-}
-
-// NewDefaultHandler returns handler for non anchor elements
-func NewDefaultHandler(element string, pattern interface{}, path string) ValidationHandler {
-	return DefaultHandler{
-		element: element,
-		pattern: pattern,
-		path:    path,
-	}
-}
-
-// DefaultHandler provides handler for non anchor element
-type DefaultHandler struct {
-	element string
-	pattern interface{}
-	path    string
-}
-
-// Handle process non anchor element
-func (dh DefaultHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorKey) (string, error) {
-	currentPath := dh.path + dh.element + "/"
-	if dh.pattern == "*" && resourceMap[dh.element] != nil {
-		return "", nil
-	} else if dh.pattern == "*" && resourceMap[dh.element] == nil {
-		return dh.path, fmt.Errorf("%s/%s not found", dh.path, dh.element)
-	} else {
-		path, err := handler(logging.GlobalLogger(), resourceMap[dh.element], dh.pattern, originPattern, currentPath, ac)
-		if err != nil {
-			return path, err
-		}
-	}
-	return "", nil
-}
-
-// NewConditionAnchorHandler returns an instance of condition acnhor handler
-func NewConditionAnchorHandler(anchor string, pattern interface{}, path string) ValidationHandler {
-	return ConditionAnchorHandler{
-		anchor:  anchor,
-		pattern: pattern,
-		path:    path,
-	}
-}
-
-// ConditionAnchorHandler provides handler for condition anchor
-type ConditionAnchorHandler struct {
-	anchor  string
-	pattern interface{}
-	path    string
-}
-
-// Handle processed condition anchor
-func (ch ConditionAnchorHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorKey) (string, error) {
-	anchorKey, _ := RemoveAnchor(ch.anchor)
-	currentPath := ch.path + anchorKey + "/"
-	// check if anchor is present in resource
-	if value, ok := resourceMap[anchorKey]; ok {
-		// validate the values of the pattern
-		returnPath, err := handler(logging.GlobalLogger(), value, ch.pattern, originPattern, currentPath, ac)
-		if err != nil {
-			ac.AnchorError = NewConditionalAnchorError(err.Error())
-			return returnPath, ac.AnchorError.Error()
-		}
-		return "", nil
-	} else {
-		msg := "conditional anchor key doesn't exist in the resource"
-		return currentPath, NewConditionalAnchorError(msg).Error()
-	}
-}
-
-// NewGlobalAnchorHandler returns an instance of condition acnhor handler
-func NewGlobalAnchorHandler(anchor string, pattern interface{}, path string) ValidationHandler {
-	return GlobalAnchorHandler{
-		anchor:  anchor,
-		pattern: pattern,
-		path:    path,
-	}
-}
-
-// GlobalAnchorHandler provides handler for global condition anchor
-type GlobalAnchorHandler struct {
-	anchor  string
-	pattern interface{}
-	path    string
-}
-
-// Handle processed global condition anchor
-func (gh GlobalAnchorHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorKey) (string, error) {
-	anchorKey, _ := RemoveAnchor(gh.anchor)
-	currentPath := gh.path + anchorKey + "/"
-	// check if anchor is present in resource
-	if value, ok := resourceMap[anchorKey]; ok {
-		// validate the values of the pattern
-		returnPath, err := handler(logging.GlobalLogger(), value, gh.pattern, originPattern, currentPath, ac)
-		if err != nil {
-			ac.AnchorError = NewGlobalAnchorError(err.Error())
-			return returnPath, ac.AnchorError.Error()
-		}
-		return "", nil
-	}
-	return "", nil
-}
-
-// NewExistenceHandler returns existence handler
-func NewExistenceHandler(anchor string, pattern interface{}, path string) ValidationHandler {
-	return ExistenceHandler{
-		anchor:  anchor,
-		pattern: pattern,
-		path:    path,
-	}
-}
-
-// ExistenceHandler provides handlers to process exitence anchor handler
-type ExistenceHandler struct {
-	anchor  string
-	pattern interface{}
-	path    string
-}
-
-// Handle processes the existence anchor handler
-func (eh ExistenceHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorKey) (string, error) {
-	// skip is used by existence anchor to not process further if condition is not satisfied
-	anchorKey, _ := RemoveAnchor(eh.anchor)
-	currentPath := eh.path + anchorKey + "/"
-	// check if anchor is present in resource
-	if value, ok := resourceMap[anchorKey]; ok {
-		// Existence anchor can only exist on resource value type of list
-		switch typedResource := value.(type) {
-		case []interface{}:
-			typedPattern, ok := eh.pattern.([]interface{})
-			if !ok {
-				return currentPath, fmt.Errorf("invalid pattern type %T: Pattern has to be of list to compare against resource", eh.pattern)
+// IsOneOf returns checks if anchor is one of the given types
+func IsOneOf(a Anchor, types ...AnchorType) bool {
+	if a != nil {
+		for _, t := range types {
+			if t == a.Type() {
+				return true
 			}
-			// loop all item in the pattern array
-			errorPath := ""
-			var err error
-			for _, patternMap := range typedPattern {
-				typedPatternMap, ok := patternMap.(map[string]interface{})
-				if !ok {
-					return currentPath, fmt.Errorf("invalid pattern type %T: Pattern has to be of type map to compare against items in resource", eh.pattern)
-				}
-				errorPath, err = validateExistenceListResource(handler, typedResource, typedPatternMap, originPattern, currentPath, ac)
-				if err != nil {
-					return errorPath, err
-				}
-			}
-			return errorPath, err
-		default:
-			return currentPath, fmt.Errorf("invalid resource type %T: Existence ^ () anchor can be used only on list/array type resource", value)
 		}
 	}
-	return "", nil
+	return false
 }
 
-func validateExistenceListResource(handler resourceElementHandler, resourceList []interface{}, patternMap map[string]interface{}, originPattern interface{}, path string, ac *AnchorKey) (string, error) {
-	// the idea is all the element in the pattern array should be present atleast once in the resource list
-	// if non satisfy then throw an error
-	for i, resourceElement := range resourceList {
-		currentPath := path + strconv.Itoa(i) + "/"
-		_, err := handler(logging.GlobalLogger(), resourceElement, patternMap, originPattern, currentPath, ac)
-		if err == nil {
-			// condition is satisfied, dont check further
-			return "", nil
-		}
-	}
-	// none of the existence checks worked, so thats a failure sceanario
-	return path, fmt.Errorf("existence anchor validation failed at path %s", path)
+// ContainsCondition returns true if anchor is either condition anchor or global condition anchor
+func ContainsCondition(a Anchor) bool {
+	return IsOneOf(a, Condition, Global)
 }
 
-// GetAnchorsResourcesFromMap returns map of anchors
-func GetAnchorsResourcesFromMap(patternMap map[string]interface{}) (map[string]interface{}, map[string]interface{}) {
-	anchors := map[string]interface{}{}
-	resources := map[string]interface{}{}
-	for key, value := range patternMap {
-		if IsConditionAnchor(key) || IsExistenceAnchor(key) || IsEqualityAnchor(key) || IsNegationAnchor(key) {
-			anchors[key] = value
-			continue
-		}
-		resources[key] = value
-	}
-
-	return anchors, resources
+// IsCondition checks for condition anchor
+func IsCondition(a Anchor) bool {
+	return IsOneOf(a, Condition)
+}
+
+// IsGlobal checks for global condition anchor
+func IsGlobal(a Anchor) bool {
+	return IsOneOf(a, Global)
+}
+
+// IsNegation checks for negation anchor
+func IsNegation(a Anchor) bool {
+	return IsOneOf(a, Negation)
+}
+
+// IsAddIfNotPresent checks for addition anchor
+func IsAddIfNotPresent(a Anchor) bool {
+	return IsOneOf(a, AddIfNotPresent)
+}
+
+// IsEquality checks for equality anchor
+func IsEquality(a Anchor) bool {
+	return IsOneOf(a, Equality)
+}
+
+// IsExistence checks for existence anchor
+func IsExistence(a Anchor) bool {
+	return IsOneOf(a, Existence)
 }
diff --git a/pkg/engine/anchor/anchorKey.go b/pkg/engine/anchor/anchorKey.go
deleted file mode 100644
index 44c50c4ea1..0000000000
--- a/pkg/engine/anchor/anchorKey.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package anchor
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-)
-
-// IsNegationAnchorError checks if error message has negation anchor error string
-func IsNegationAnchorError(msg string) bool {
-	return strings.Contains(msg, NegationAnchorErrMsg)
-}
-
-// IsConditionalAnchorError checks if error message has conditional anchor error string
-func IsConditionalAnchorError(msg string) bool {
-	return strings.Contains(msg, ConditionalAnchorErrMsg)
-}
-
-// IsGlobalAnchorError checks if error message has global anchor error string
-func IsGlobalAnchorError(msg string) bool {
-	return strings.Contains(msg, GlobalAnchorErrMsg)
-}
-
-// NewNegationAnchorError returns a new instance of NegationAnchorError
-func NewNegationAnchorError(msg string) ValidateAnchorError {
-	return ValidateAnchorError{
-		Err:     NegationAnchorErr,
-		Message: fmt.Sprintf("%s: %s", NegationAnchorErrMsg, msg),
-	}
-}
-
-// IsNegationAnchorError checks if the error is a negation anchor error
-func (e ValidateAnchorError) IsNegationAnchorError() bool {
-	return e.Err == NegationAnchorErr
-}
-
-// NewConditionalAnchorError returns a new instance of ConditionalAnchorError
-func NewConditionalAnchorError(msg string) ValidateAnchorError {
-	return ValidateAnchorError{
-		Err:     ConditionalAnchorErr,
-		Message: fmt.Sprintf("%s: %s", ConditionalAnchorErrMsg, msg),
-	}
-}
-
-// IsConditionAnchorError checks if the error is a conditional anchor error
-func (e ValidateAnchorError) IsConditionAnchorError() bool {
-	return e.Err == ConditionalAnchorErr
-}
-
-// NewGlobalAnchorError returns a new instance of GlobalAnchorError
-func NewGlobalAnchorError(msg string) ValidateAnchorError {
-	return ValidateAnchorError{
-		Err:     GlobalAnchorErr,
-		Message: fmt.Sprintf("%s: %s", GlobalAnchorErrMsg, msg),
-	}
-}
-
-// IsGlobalAnchorError checks if the error is a global anchor error
-func (e ValidateAnchorError) IsGlobalAnchorError() bool {
-	return e.Err == GlobalAnchorErr
-}
-
-// IsNil checks if the error isn't populated
-func (e ValidateAnchorError) IsNil() bool {
-	return e == ValidateAnchorError{}
-}
-
-// Error returns an error instance of the anchor error
-func (e ValidateAnchorError) Error() error {
-	return errors.New(e.Message)
-}
-
-// AnchorError is the const specification of anchor errors
-type AnchorError int
-
-const (
-	// ConditionalAnchorErr refers to condition violation
-	ConditionalAnchorErr AnchorError = iota
-
-	// GlobalAnchorErr refers to global condition violation
-	GlobalAnchorErr
-
-	// NegationAnchorErr refers to negation violation
-	NegationAnchorErr
-)
-
-// ValidateAnchorError represents the error type of validation anchors
-type ValidateAnchorError struct {
-	Err     AnchorError
-	Message string
-}
-
-// NegationAnchorErrMsg - the error message for negation anchor error
-var NegationAnchorErrMsg = "negation anchor matched in resource"
-
-// ConditionalAnchorErrMsg - the error message for conditional anchor error
-var ConditionalAnchorErrMsg = "conditional anchor mismatch"
-
-// GlobalAnchorErrMsg - the error message for global anchor error
-var GlobalAnchorErrMsg = "global anchor mismatch"
-
-// AnchorKey - contains map of anchors
-type AnchorKey struct {
-	// anchorMap - for each anchor key in the patterns it will maintain information if the key exists in the resource
-	// if anchor key of the pattern exists in the resource then (key)=true else (key)=false
-	anchorMap map[string]bool
-	// AnchorError - used in validate to break execution of the recursion when if condition fails
-	AnchorError ValidateAnchorError
-}
-
-// NewAnchorMap -initialize anchorMap
-func NewAnchorMap() *AnchorKey {
-	return &AnchorKey{anchorMap: make(map[string]bool)}
-}
-
-// IsAnchorError - if any of the anchor key doesn't exists in the resource then it will return true
-// if any of (key)=false then return IsAnchorError() as true
-// if all the keys exists in the pattern exists in resource then return IsAnchorError() as false
-func (ac *AnchorKey) IsAnchorError() bool {
-	for _, v := range ac.anchorMap {
-		if !v {
-			return true
-		}
-	}
-	return false
-}
-
-// CheckAnchorInResource checks if condition anchor key has values
-func (ac *AnchorKey) CheckAnchorInResource(pattern interface{}, resource interface{}) {
-	switch typed := pattern.(type) {
-	case map[string]interface{}:
-		for key := range typed {
-			if IsConditionAnchor(key) || IsExistenceAnchor(key) || IsNegationAnchor(key) {
-				val, ok := ac.anchorMap[key]
-				if !ok {
-					ac.anchorMap[key] = false
-				} else if ok && val {
-					continue
-				}
-				if doesAnchorsKeyHasValue(key, resource) {
-					ac.anchorMap[key] = true
-				}
-			}
-		}
-	}
-}
-
-// Checks if anchor key has value in resource
-func doesAnchorsKeyHasValue(key string, resource interface{}) bool {
-	akey, _ := RemoveAnchor(key)
-	switch typed := resource.(type) {
-	case map[string]interface{}:
-		if _, ok := typed[akey]; ok {
-			return true
-		}
-		return false
-	case []interface{}:
-		for _, value := range typed {
-			if doesAnchorsKeyHasValue(key, value) {
-				return true
-			}
-		}
-		return false
-	default:
-		return false
-	}
-}
diff --git a/pkg/engine/anchor/anchor_test.go b/pkg/engine/anchor/anchor_test.go
new file mode 100644
index 0000000000..4f540e512c
--- /dev/null
+++ b/pkg/engine/anchor/anchor_test.go
@@ -0,0 +1,653 @@
+package anchor
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestNew(t *testing.T) {
+	type args struct {
+		modifier AnchorType
+		key      string
+	}
+	tests := []struct {
+		name string
+		args args
+		want Anchor
+	}{{
+		args: args{Condition, ""},
+		want: nil,
+	}, {
+		args: args{Global, ""},
+		want: nil,
+	}, {
+		args: args{Negation, ""},
+		want: nil,
+	}, {
+		args: args{AddIfNotPresent, ""},
+		want: nil,
+	}, {
+		args: args{Equality, ""},
+		want: nil,
+	}, {
+		args: args{Existence, ""},
+		want: nil,
+	}, {
+		args: args{Condition, "test"},
+		want: anchor{Condition, "test"},
+	}, {
+		args: args{Global, "test"},
+		want: anchor{Global, "test"},
+	}, {
+		args: args{Negation, "test"},
+		want: anchor{Negation, "test"},
+	}, {
+		args: args{AddIfNotPresent, "test"},
+		want: anchor{AddIfNotPresent, "test"},
+	}, {
+		args: args{Equality, "test"},
+		want: anchor{Equality, "test"},
+	}, {
+		args: args{Existence, "test"},
+		want: anchor{Existence, "test"},
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := New(tt.args.modifier, tt.args.key); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("New() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestString(t *testing.T) {
+	type args struct {
+		modifier AnchorType
+		key      string
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{{
+		args: args{Condition, ""},
+		want: "",
+	}, {
+		args: args{Global, ""},
+		want: "",
+	}, {
+		args: args{Negation, ""},
+		want: "",
+	}, {
+		args: args{AddIfNotPresent, ""},
+		want: "",
+	}, {
+		args: args{Equality, ""},
+		want: "",
+	}, {
+		args: args{Existence, ""},
+		want: "",
+	}, {
+		args: args{Condition, "test"},
+		want: "(test)",
+	}, {
+		args: args{Global, "test"},
+		want: "<(test)",
+	}, {
+		args: args{Negation, "test"},
+		want: "X(test)",
+	}, {
+		args: args{AddIfNotPresent, "test"},
+		want: "+(test)",
+	}, {
+		args: args{Equality, "test"},
+		want: "=(test)",
+	}, {
+		args: args{Existence, "test"},
+		want: "^(test)",
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := String(tt.args.modifier, tt.args.key); got != tt.want {
+				t.Errorf("String() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsOneOf(t *testing.T) {
+	type args struct {
+		a     Anchor
+		types []AnchorType
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{},
+		want: false,
+	}, {
+		args: args{nil, []AnchorType{Condition, Negation}},
+		want: false,
+	}, {
+		args: args{New(Condition, "test"), nil},
+		want: false,
+	}, {
+		args: args{New(Condition, "test"), []AnchorType{}},
+		want: false,
+	}, {
+		args: args{New(Condition, "test"), []AnchorType{Condition}},
+		want: true,
+	}, {
+		args: args{New(Condition, "test"), []AnchorType{Condition, Negation}},
+		want: true,
+	}, {
+		args: args{New(Condition, "test"), []AnchorType{Negation, Global}},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsOneOf(tt.args.a, tt.args.types...); got != tt.want {
+				t.Errorf("IsOneOf() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestParse(t *testing.T) {
+	type args struct {
+		str string
+	}
+	tests := []struct {
+		name string
+		args args
+		want Anchor
+	}{
+		{
+			args: args{"(something)"},
+			want: anchor{Condition, "something"},
+		}, {
+			args: args{"()"},
+			want: nil,
+		}, {
+			args: args{"something"},
+			want: nil,
+		}, {
+			args: args{"(something"},
+			want: nil,
+		}, {
+			args: args{"something)"},
+			want: nil,
+		}, {
+			args: args{"so)m(et(hin)g"},
+			want: nil,
+		}, {
+			args: args{""},
+			want: nil,
+		}, {
+			args: args{"^(abc)"},
+			want: anchor{Existence, "abc"},
+		}, {
+			args: args{"^(abc"},
+			want: nil,
+		}, {
+			args: args{"^abc"},
+			want: nil,
+		}, {
+			args: args{"^()"},
+			want: nil,
+		}, {
+			args: args{"(abc)"},
+			want: anchor{Condition, "abc"},
+		}, {
+			args: args{"=(abc)"},
+			want: anchor{Equality, "abc"},
+		}, {
+			args: args{"=(abc"},
+			want: nil,
+		}, {
+			args: args{"=abc"},
+			want: nil,
+		}, {
+			args: args{"+(abc)"},
+			want: anchor{AddIfNotPresent, "abc"},
+		}, {
+			args: args{"+(abc"},
+			want: nil,
+		}, {
+			args: args{"+abc"},
+			want: nil,
+		}, {
+			args: args{"X(abc)"},
+			want: anchor{Negation, "abc"},
+		}, {
+			args: args{"X(abc"},
+			want: nil,
+		}, {
+			args: args{"Xabc"},
+			want: nil,
+		}, {
+			args: args{"<(abc)"},
+			want: anchor{Global, "abc"},
+		}, {
+			args: args{"<(abc"},
+			want: nil,
+		}, {
+			args: args{"<abc"},
+			want: nil,
+		}, {
+			args: args{"(abc)"},
+			want: anchor{Condition, "abc"},
+		}, {
+			args: args{"(abc"},
+			want: nil,
+		}, {
+			args: args{"abc"},
+			want: nil,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := Parse(tt.args.str); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("Parse() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_anchor_Type(t *testing.T) {
+	type fields struct {
+		modifier AnchorType
+		key      string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   AnchorType
+	}{{
+		fields: fields{Condition, "abc"},
+		want:   Condition,
+	}, {
+		fields: fields{Global, "abc"},
+		want:   Global,
+	}, {
+		fields: fields{Negation, "abc"},
+		want:   Negation,
+	}, {
+		fields: fields{AddIfNotPresent, "abc"},
+		want:   AddIfNotPresent,
+	}, {
+		fields: fields{Equality, "abc"},
+		want:   Equality,
+	}, {
+		fields: fields{Existence, "abc"},
+		want:   Existence,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			a := anchor{
+				modifier: tt.fields.modifier,
+				key:      tt.fields.key,
+			}
+			if got := a.Type(); got != tt.want {
+				t.Errorf("anchor.Type() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_anchor_Key(t *testing.T) {
+	type fields struct {
+		modifier AnchorType
+		key      string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{{
+		fields: fields{Condition, "abc"},
+		want:   "abc",
+	}, {
+		fields: fields{Global, "abc"},
+		want:   "abc",
+	}, {
+		fields: fields{Negation, "abc"},
+		want:   "abc",
+	}, {
+		fields: fields{AddIfNotPresent, "abc"},
+		want:   "abc",
+	}, {
+		fields: fields{Equality, "abc"},
+		want:   "abc",
+	}, {
+		fields: fields{Existence, "abc"},
+		want:   "abc",
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			a := anchor{
+				modifier: tt.fields.modifier,
+				key:      tt.fields.key,
+			}
+			if got := a.Key(); got != tt.want {
+				t.Errorf("anchor.Key() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_anchor_String(t *testing.T) {
+	type fields struct {
+		modifier AnchorType
+		key      string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{{
+		fields: fields{Condition, "abc"},
+		want:   "(abc)",
+	}, {
+		fields: fields{Global, "abc"},
+		want:   "<(abc)",
+	}, {
+		fields: fields{Negation, "abc"},
+		want:   "X(abc)",
+	}, {
+		fields: fields{AddIfNotPresent, "abc"},
+		want:   "+(abc)",
+	}, {
+		fields: fields{Equality, "abc"},
+		want:   "=(abc)",
+	}, {
+		fields: fields{Existence, "abc"},
+		want:   "^(abc)",
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			a := anchor{
+				modifier: tt.fields.modifier,
+				key:      tt.fields.key,
+			}
+			if got := a.String(); got != tt.want {
+				t.Errorf("anchor.String() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsCondition(t *testing.T) {
+	type args struct {
+		a Anchor
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{nil},
+		want: false,
+	}, {
+		args: args{New(Condition, "abc")},
+		want: true,
+	}, {
+		args: args{New(Global, "abc")},
+		want: false,
+	}, {
+		args: args{New(Negation, "abc")},
+		want: false,
+	}, {
+		args: args{New(AddIfNotPresent, "abc")},
+		want: false,
+	}, {
+		args: args{New(Equality, "abc")},
+		want: false,
+	}, {
+		args: args{New(Existence, "abc")},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsCondition(tt.args.a); got != tt.want {
+				t.Errorf("IsCondition() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsGlobal(t *testing.T) {
+	type args struct {
+		a Anchor
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{nil},
+		want: false,
+	}, {
+		args: args{New(Condition, "abc")},
+		want: false,
+	}, {
+		args: args{New(Global, "abc")},
+		want: true,
+	}, {
+		args: args{New(Negation, "abc")},
+		want: false,
+	}, {
+		args: args{New(AddIfNotPresent, "abc")},
+		want: false,
+	}, {
+		args: args{New(Equality, "abc")},
+		want: false,
+	}, {
+		args: args{New(Existence, "abc")},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsGlobal(tt.args.a); got != tt.want {
+				t.Errorf("IsGlobal() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsNegation(t *testing.T) {
+	type args struct {
+		a Anchor
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{nil},
+		want: false,
+	}, {
+		args: args{New(Condition, "abc")},
+		want: false,
+	}, {
+		args: args{New(Global, "abc")},
+		want: false,
+	}, {
+		args: args{New(Negation, "abc")},
+		want: true,
+	}, {
+		args: args{New(AddIfNotPresent, "abc")},
+		want: false,
+	}, {
+		args: args{New(Equality, "abc")},
+		want: false,
+	}, {
+		args: args{New(Existence, "abc")},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsNegation(tt.args.a); got != tt.want {
+				t.Errorf("IsNegation() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsAddIfNotPresent(t *testing.T) {
+	type args struct {
+		a Anchor
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{nil},
+		want: false,
+	}, {
+		args: args{New(Condition, "abc")},
+		want: false,
+	}, {
+		args: args{New(Global, "abc")},
+		want: false,
+	}, {
+		args: args{New(Negation, "abc")},
+		want: false,
+	}, {
+		args: args{New(AddIfNotPresent, "abc")},
+		want: true,
+	}, {
+		args: args{New(Equality, "abc")},
+		want: false,
+	}, {
+		args: args{New(Existence, "abc")},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsAddIfNotPresent(tt.args.a); got != tt.want {
+				t.Errorf("IsAddIfNotPresent() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsEquality(t *testing.T) {
+	type args struct {
+		a Anchor
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{nil},
+		want: false,
+	}, {
+		args: args{New(Condition, "abc")},
+		want: false,
+	}, {
+		args: args{New(Global, "abc")},
+		want: false,
+	}, {
+		args: args{New(Negation, "abc")},
+		want: false,
+	}, {
+		args: args{New(AddIfNotPresent, "abc")},
+		want: false,
+	}, {
+		args: args{New(Equality, "abc")},
+		want: true,
+	}, {
+		args: args{New(Existence, "abc")},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsEquality(tt.args.a); got != tt.want {
+				t.Errorf("IsEquality() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsExistence(t *testing.T) {
+	type args struct {
+		a Anchor
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{nil},
+		want: false,
+	}, {
+		args: args{New(Condition, "abc")},
+		want: false,
+	}, {
+		args: args{New(Global, "abc")},
+		want: false,
+	}, {
+		args: args{New(Negation, "abc")},
+		want: false,
+	}, {
+		args: args{New(AddIfNotPresent, "abc")},
+		want: false,
+	}, {
+		args: args{New(Equality, "abc")},
+		want: false,
+	}, {
+		args: args{New(Existence, "abc")},
+		want: true,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsExistence(tt.args.a); got != tt.want {
+				t.Errorf("IsExistence() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestContainsCondition(t *testing.T) {
+	type args struct {
+		a Anchor
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{nil},
+		want: false,
+	}, {
+		args: args{New(Condition, "abc")},
+		want: true,
+	}, {
+		args: args{New(Global, "abc")},
+		want: true,
+	}, {
+		args: args{New(Negation, "abc")},
+		want: false,
+	}, {
+		args: args{New(AddIfNotPresent, "abc")},
+		want: false,
+	}, {
+		args: args{New(Equality, "abc")},
+		want: false,
+	}, {
+		args: args{New(Existence, "abc")},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := ContainsCondition(tt.args.a); got != tt.want {
+				t.Errorf("ContainsCondition() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/pkg/engine/anchor/anchormap.go b/pkg/engine/anchor/anchormap.go
new file mode 100644
index 0000000000..9e45f2d45b
--- /dev/null
+++ b/pkg/engine/anchor/anchormap.go
@@ -0,0 +1,44 @@
+package anchor
+
+// AnchorMap - contains map of anchors
+type AnchorMap struct {
+	// anchorMap - for each anchor key in the patterns it will maintain information if the key exists in the resource
+	// if anchor key of the pattern exists in the resource then (key)=true else (key)=false
+	anchorMap map[string]bool
+	// AnchorError - used in validate to break execution of the recursion when if condition fails
+	AnchorError validateAnchorError
+}
+
+// NewAnchorMap -initialize anchorMap
+func NewAnchorMap() *AnchorMap {
+	return &AnchorMap{anchorMap: map[string]bool{}}
+}
+
+// KeysAreMissing - if any of the anchor key doesn't exists in the resource then it will return true
+// if any of (key)=false then return KeysAreMissing() as true
+// if all the keys exists in the pattern exists in resource then return KeysAreMissing() as false
+func (ac *AnchorMap) KeysAreMissing() bool {
+	for _, v := range ac.anchorMap {
+		if !v {
+			return true
+		}
+	}
+	return false
+}
+
+// CheckAnchorInResource checks if condition anchor key has values
+func (ac *AnchorMap) CheckAnchorInResource(pattern map[string]interface{}, resource interface{}) {
+	for key := range pattern {
+		if a := Parse(key); IsCondition(a) || IsExistence(a) || IsNegation(a) {
+			val, ok := ac.anchorMap[key]
+			if !ok {
+				ac.anchorMap[key] = false
+			} else if ok && val {
+				continue
+			}
+			if resourceHasValueForKey(resource, a.Key()) {
+				ac.anchorMap[key] = true
+			}
+		}
+	}
+}
diff --git a/pkg/engine/anchor/anchormap_test.go b/pkg/engine/anchor/anchormap_test.go
new file mode 100644
index 0000000000..7c4e86c0b8
--- /dev/null
+++ b/pkg/engine/anchor/anchormap_test.go
@@ -0,0 +1,66 @@
+package anchor
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestNewAnchorMap(t *testing.T) {
+	tests := []struct {
+		name string
+		want *AnchorMap
+	}{{
+		want: &AnchorMap{anchorMap: map[string]bool{}},
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := NewAnchorMap(); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("NewAnchorMap() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestAnchorMap_KeysAreMissing(t *testing.T) {
+	type fields struct {
+		anchorMap   map[string]bool
+		AnchorError validateAnchorError
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   bool
+	}{{
+		fields: fields{
+			anchorMap: map[string]bool{},
+		},
+		want: false,
+	}, {
+		fields: fields{
+			anchorMap: map[string]bool{
+				"a": true,
+				"b": false,
+			},
+		},
+		want: true,
+	}, {
+		fields: fields{
+			anchorMap: map[string]bool{
+				"a": true,
+				"b": true,
+			},
+		},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ac := &AnchorMap{
+				anchorMap:   tt.fields.anchorMap,
+				AnchorError: tt.fields.AnchorError,
+			}
+			if got := ac.KeysAreMissing(); got != tt.want {
+				t.Errorf("AnchorMap.KeysAreMissing() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/pkg/engine/anchor/common.go b/pkg/engine/anchor/common.go
deleted file mode 100644
index 5500a26d55..0000000000
--- a/pkg/engine/anchor/common.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package anchor
-
-import (
-	"path"
-	"strings"
-)
-
-// IsAnchor is a function handler
-type IsAnchor func(str string) bool
-
-// IsConditionAnchor checks for condition anchor
-func IsConditionAnchor(str string) bool {
-	if len(str) < 2 {
-		return false
-	}
-
-	return (str[0] == '(' && str[len(str)-1] == ')')
-}
-
-// IsGlobalAnchor checks for global condition anchor
-func IsGlobalAnchor(str string) bool {
-	left := "<("
-	right := ")"
-	if len(str) < len(left)+len(right) {
-		return false
-	}
-
-	leftMatch := strings.TrimSpace(str[:len(left)]) == left
-	rightMatch := strings.TrimSpace(str[len(str)-len(right):]) == right
-	return leftMatch && rightMatch
-}
-
-// ContainsCondition returns true, if str is either condition anchor or
-// global condition anchor
-func ContainsCondition(str string) bool {
-	return IsConditionAnchor(str) || IsGlobalAnchor(str)
-}
-
-// IsNegationAnchor checks for negation anchor
-func IsNegationAnchor(str string) bool {
-	left := "X("
-	right := ")"
-	if len(str) < len(left)+len(right) {
-		return false
-	}
-	// TODO: trim spaces ?
-	return (str[:len(left)] == left && str[len(str)-len(right):] == right)
-}
-
-// IsAddIfNotPresentAnchor checks for addition anchor
-func IsAddIfNotPresentAnchor(key string) bool {
-	const left = "+("
-	const right = ")"
-
-	if len(key) < len(left)+len(right) {
-		return false
-	}
-
-	return left == key[:len(left)] && right == key[len(key)-len(right):]
-}
-
-// IsEqualityAnchor checks for equality anchor
-func IsEqualityAnchor(str string) bool {
-	left := "=("
-	right := ")"
-	if len(str) < len(left)+len(right) {
-		return false
-	}
-	// TODO: trim spaces ?
-	return (str[:len(left)] == left && str[len(str)-len(right):] == right)
-}
-
-// IsExistenceAnchor checks for existence anchor
-func IsExistenceAnchor(str string) bool {
-	left := "^("
-	right := ")"
-
-	if len(str) < len(left)+len(right) {
-		return false
-	}
-
-	return (str[:len(left)] == left && str[len(str)-len(right):] == right)
-}
-
-// IsNonAnchor checks that key does not have any anchor
-func IsNonAnchor(str string) bool {
-	key, _ := RemoveAnchor(str)
-	return str == key
-}
-
-// RemoveAnchor remove anchor from the given key. It returns
-// the anchor-free tag value and the prefix of the anchor.
-func RemoveAnchor(key string) (string, string) {
-	if IsConditionAnchor(key) {
-		return key[1 : len(key)-1], key[0:1]
-	}
-
-	if IsExistenceAnchor(key) || IsAddIfNotPresentAnchor(key) || IsEqualityAnchor(key) || IsNegationAnchor(key) || IsGlobalAnchor(key) {
-		return key[2 : len(key)-1], key[0:2]
-	}
-
-	return key, ""
-}
-
-// RemoveAnchorsFromPath removes all anchor from path string
-func RemoveAnchorsFromPath(str string) string {
-	components := strings.Split(str, "/")
-	if components[0] == "" {
-		components = components[1:]
-	}
-
-	for i, component := range components {
-		components[i], _ = RemoveAnchor(component)
-	}
-
-	newPath := path.Join(components...)
-	if path.IsAbs(str) {
-		newPath = "/" + newPath
-	}
-	return newPath
-}
-
-// AddAnchor adds an anchor with the supplied prefix.
-// The suffix is assumed to be ")".
-func AddAnchor(key, anchorPrefix string) string {
-	return anchorPrefix + key + ")"
-}
diff --git a/pkg/engine/anchor/common_test.go b/pkg/engine/anchor/common_test.go
deleted file mode 100644
index 66ce5869b7..0000000000
--- a/pkg/engine/anchor/common_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package anchor
-
-import (
-	"testing"
-
-	"gotest.tools/assert"
-)
-
-func TestWrappedWithParentheses_StringIsWrappedWithParentheses(t *testing.T) {
-	str := "(something)"
-	assert.Assert(t, IsConditionAnchor(str))
-}
-
-func TestWrappedWithParentheses_StringHasOnlyParentheses(t *testing.T) {
-	str := "()"
-	assert.Assert(t, IsConditionAnchor(str))
-}
-
-func TestWrappedWithParentheses_StringHasNoParentheses(t *testing.T) {
-	str := "something"
-	assert.Assert(t, !IsConditionAnchor(str))
-}
-
-func TestWrappedWithParentheses_StringHasLeftParentheses(t *testing.T) {
-	str := "(something"
-	assert.Assert(t, !IsConditionAnchor(str))
-}
-
-func TestWrappedWithParentheses_StringHasRightParentheses(t *testing.T) {
-	str := "something)"
-	assert.Assert(t, !IsConditionAnchor(str))
-}
-
-func TestWrappedWithParentheses_StringParenthesesInside(t *testing.T) {
-	str := "so)m(et(hin)g"
-	assert.Assert(t, !IsConditionAnchor(str))
-}
-
-func TestWrappedWithParentheses_Empty(t *testing.T) {
-	str := ""
-	assert.Assert(t, !IsConditionAnchor(str))
-}
-
-func TestIsExistenceAnchor_Yes(t *testing.T) {
-	assert.Assert(t, IsExistenceAnchor("^(abc)"))
-}
-
-func TestIsExistenceAnchor_NoRightBracket(t *testing.T) {
-	assert.Assert(t, !IsExistenceAnchor("^(abc"))
-}
-
-func TestIsExistenceAnchor_OnlyHat(t *testing.T) {
-	assert.Assert(t, !IsExistenceAnchor("^abc"))
-}
-
-func TestIsExistenceAnchor_ConditionAnchor(t *testing.T) {
-	assert.Assert(t, !IsExistenceAnchor("(abc)"))
-}
-
-func TestRemoveAnchorsFromPath_WorksWithAbsolutePath(t *testing.T) {
-	newPath := RemoveAnchorsFromPath("/path/(to)/X(anchors)")
-	assert.Equal(t, newPath, "/path/to/anchors")
-}
-
-func TestRemoveAnchorsFromPath_WorksWithRelativePath(t *testing.T) {
-	newPath := RemoveAnchorsFromPath("path/(to)/X(anchors)")
-	assert.Equal(t, newPath, "path/to/anchors")
-}
diff --git a/pkg/engine/anchor/error.go b/pkg/engine/anchor/error.go
new file mode 100644
index 0000000000..732a2d1400
--- /dev/null
+++ b/pkg/engine/anchor/error.go
@@ -0,0 +1,89 @@
+package anchor
+
+import (
+	"fmt"
+	"strings"
+)
+
+// anchorError is the const specification of anchor errors
+type anchorError int
+
+const (
+	// conditionalAnchorErr refers to condition violation
+	conditionalAnchorErr anchorError = iota
+	// globalAnchorErr refers to global condition violation
+	globalAnchorErr
+	// negationAnchorErr refers to negation violation
+	negationAnchorErr
+)
+
+const (
+	// negationAnchorErrMsg - the error message for negation anchor error
+	negationAnchorErrMsg = "negation anchor matched in resource"
+	// conditionalAnchorErrMsg - the error message for conditional anchor error
+	conditionalAnchorErrMsg = "conditional anchor mismatch"
+	// globalAnchorErrMsg - the error message for global anchor error
+	globalAnchorErrMsg = "global anchor mismatch"
+)
+
+// validateAnchorError represents the error type of validation anchors
+type validateAnchorError struct {
+	err     anchorError
+	message string
+}
+
+// Error implements error interface
+func (e validateAnchorError) Error() string {
+	return e.message
+}
+
+// newNegationAnchorError returns a new instance of validateAnchorError
+func newValidateAnchorError(err anchorError, prefix, msg string) validateAnchorError {
+	return validateAnchorError{
+		err:     err,
+		message: fmt.Sprintf("%s: %s", prefix, msg),
+	}
+}
+
+// newNegationAnchorError returns a new instance of NegationAnchorError
+func newNegationAnchorError(msg string) validateAnchorError {
+	return newValidateAnchorError(negationAnchorErr, negationAnchorErrMsg, msg)
+}
+
+// newConditionalAnchorError returns a new instance of ConditionalAnchorError
+func newConditionalAnchorError(msg string) validateAnchorError {
+	return newValidateAnchorError(conditionalAnchorErr, conditionalAnchorErrMsg, msg)
+}
+
+// newGlobalAnchorError returns a new instance of GlobalAnchorError
+func newGlobalAnchorError(msg string) validateAnchorError {
+	return newValidateAnchorError(globalAnchorErr, globalAnchorErrMsg, msg)
+}
+
+// isError checks if error matches the given error type
+func isError(err error, code anchorError, msg string) bool {
+	if err != nil {
+		if t, ok := err.(validateAnchorError); ok {
+			return t.err == code
+		} else {
+			// TODO: we shouldn't need this, error is not properly propagated
+			return strings.Contains(err.Error(), msg)
+		}
+	}
+	return false
+}
+
+// IsNegationAnchorError checks if error is a negation anchor error
+func IsNegationAnchorError(err error) bool {
+	return isError(err, negationAnchorErr, negationAnchorErrMsg)
+}
+
+// IsConditionalAnchorError checks if error is a conditional anchor error
+func IsConditionalAnchorError(err error) bool {
+	return isError(err, conditionalAnchorErr, conditionalAnchorErrMsg)
+}
+
+// IsGlobalAnchorError checks if error is a global global anchor error
+func IsGlobalAnchorError(err error) bool {
+	return isError(err, globalAnchorErr, globalAnchorErrMsg)
+}
diff --git a/pkg/engine/anchor/error_test.go b/pkg/engine/anchor/error_test.go
new file mode 100644
index 0000000000..be1c9e175e
--- /dev/null
+++ b/pkg/engine/anchor/error_test.go
@@ -0,0 +1,276 @@
+package anchor
+
+import (
+	"errors"
+	"reflect"
+	"testing"
+)
+
+func Test_validateAnchorError_Error(t *testing.T) {
+	type fields struct {
+		err     anchorError
+		message string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{{
+		fields: fields{
+			err:     negationAnchorErr,
+			message: "test",
+		},
+		want: "test",
+	}, {
+		fields: fields{
+			err:     conditionalAnchorErr,
+			message: "test",
+		},
+		want: "test",
+	}, {
+		fields: fields{
+			err:     globalAnchorErr,
+			message: "test",
+		},
+		want: "test",
+	}, {
+		fields: fields{
+			err:     globalAnchorErr,
+			message: "",
+		},
+		want: "",
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := validateAnchorError{
+				err:     tt.fields.err,
+				message: tt.fields.message,
+			}
+			if got := e.Error(); got != tt.want {
+				t.Errorf("validateAnchorError.Error() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_newNegationAnchorError(t *testing.T) {
+	type args struct {
+		msg string
+	}
+	tests := []struct {
+		name string
+		args args
+		want validateAnchorError
+	}{{
+		args: args{
+			msg: "test",
+		},
+		want: validateAnchorError{
+			err:     negationAnchorErr,
+			message: "negation anchor matched in resource: test",
+		},
+	}, {
+		want: validateAnchorError{
+			err:     negationAnchorErr,
+			message: "negation anchor matched in resource: ",
+		},
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := newNegationAnchorError(tt.args.msg); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("newNegationAnchorError() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_newConditionalAnchorError(t *testing.T) {
+	type args struct {
+		msg string
+	}
+	tests := []struct {
+		name string
+		args args
+		want validateAnchorError
+	}{{
+		args: args{
+			msg: "test",
+		},
+		want: validateAnchorError{
+			err:     conditionalAnchorErr,
+			message: "conditional anchor mismatch: test",
+		},
+	}, {
+		want: validateAnchorError{
+			err:     conditionalAnchorErr,
+			message: "conditional anchor mismatch: ",
+		},
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := newConditionalAnchorError(tt.args.msg); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("newConditionalAnchorError() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_newGlobalAnchorError(t *testing.T) {
+	type args struct {
+		msg string
+	}
+	tests := []struct {
+		name string
+		args args
+		want validateAnchorError
+	}{{
+		args: args{
+			msg: "test",
+		},
+		want: validateAnchorError{
+			err:     globalAnchorErr,
+			message: "global anchor mismatch: test",
+		},
+	}, {
+		want: validateAnchorError{
+			err:     globalAnchorErr,
+			message: "global anchor mismatch: ",
+		},
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := newGlobalAnchorError(tt.args.msg); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("newGlobalAnchorError() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsNegationAnchorError(t *testing.T) {
+	type args struct {
+		err error
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{
+			err: nil,
+		},
+		want: false,
+	}, {
+		args: args{
+			err: errors.New("negation anchor matched in resource: test"),
+		},
+		want: true,
+	}, {
+		args: args{
+			err: newConditionalAnchorError("test"),
+		},
+		want: false,
+	}, {
+		args: args{
+			err: newGlobalAnchorError("test"),
+		},
+		want: false,
+	}, {
+		args: args{
+			err: newNegationAnchorError("test"),
+		},
+		want: true,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsNegationAnchorError(tt.args.err); got != tt.want {
+				t.Errorf("IsNegationAnchorError() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsConditionalAnchorError(t *testing.T) {
+	type args struct {
+		err error
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{
+			err: nil,
+		},
+		want: false,
+	}, {
+		args: args{
+			err: errors.New("conditional anchor mismatch: test"),
+		},
+		want: true,
+	}, {
+		args: args{
+			err: newConditionalAnchorError("test"),
+		},
+		want: true,
+	}, {
+		args: args{
+			err: newGlobalAnchorError("test"),
+		},
+		want: false,
+	}, {
+		args: args{
+			err: newNegationAnchorError("test"),
+		},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsConditionalAnchorError(tt.args.err); got != tt.want {
+				t.Errorf("IsConditionalAnchorError() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsGlobalAnchorError(t *testing.T) {
+	type args struct {
+		err error
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{
+			err: nil,
+		},
+		want: false,
+	}, {
+		args: args{
+			err: errors.New("global anchor mismatch: test"),
+		},
+		want: true,
+	}, {
+		args: args{
+			err: newConditionalAnchorError("test"),
+		},
+		want: false,
+	}, {
+		args: args{
+			err: newGlobalAnchorError("test"),
+		},
+		want: true,
+	}, {
+		args: args{
+			err: newNegationAnchorError("test"),
+		},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsGlobalAnchorError(tt.args.err); got != tt.want {
+				t.Errorf("IsGlobalAnchorError() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/pkg/engine/anchor/handlers.go b/pkg/engine/anchor/handlers.go
new file mode 100644
index 0000000000..fa9cfe4a56
--- /dev/null
+++ b/pkg/engine/anchor/handlers.go
@@ -0,0 +1,275 @@
+package anchor
+
+import (
+	"fmt"
+	"strconv"
+
+	"github.com/go-logr/logr"
+	"github.com/kyverno/kyverno/pkg/logging"
+)
+
+type resourceElementHandler = func(
+	log logr.Logger,
+	resourceElement interface{},
+	patternElement interface{},
+	originPattern interface{},
+	path string,
+	ac *AnchorMap,
+) (string, error)
+
+// ValidationHandler for element processes
+type ValidationHandler interface {
+	Handle(
+		handler resourceElementHandler,
+		resourceMap map[string]interface{},
+		originPattern interface{},
+		ac *AnchorMap,
+	) (string, error)
+}
+
+// CreateElementHandler factory to process elements
+func CreateElementHandler(element string, pattern interface{}, path string) ValidationHandler {
+	if anchor := Parse(element); anchor != nil {
+		switch {
+		case IsCondition(anchor):
+			return newConditionAnchorHandler(anchor, pattern, path)
+		case IsGlobal(anchor):
+			return newGlobalAnchorHandler(anchor, pattern, path)
+		case IsExistence(anchor):
+			return newExistenceHandler(anchor, pattern, path)
+		case IsEquality(anchor):
+			return newEqualityHandler(anchor, pattern, path)
+		case IsNegation(anchor):
+			return newNegationHandler(anchor, pattern, path)
+		}
+	}
+	return newDefaultHandler(element, pattern, path)
+}
+
+// negationHandler provides handler for check if the tag in anchor is not defined
+type negationHandler struct {
+	anchor  Anchor
+	pattern interface{}
+	path    string
+}
+
+// newNegationHandler returns instance of negation handler
+func newNegationHandler(anchor Anchor, pattern interface{}, path string) ValidationHandler {
+	return negationHandler{
+		anchor:  anchor,
+		pattern: pattern,
+		path:    path,
+	}
+}
+
+// Handle process negation handler
+func (nh negationHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorMap) (string, error) {
+	anchorKey := nh.anchor.Key()
+	currentPath := nh.path + anchorKey + "/"
+	// if anchor is present in the resource then fail
+	if _, ok := resourceMap[anchorKey]; ok {
+		// no need to process elements in value as key cannot be present in resource
+		ac.AnchorError = newNegationAnchorError(fmt.Sprintf("%s is not allowed", currentPath))
+		return currentPath, ac.AnchorError
+	}
+	// key is not defined in the resource
+	return "", nil
+}
+
+// equalityHandler provides handler for non anchor element
+type equalityHandler struct {
+	anchor  Anchor
+	pattern interface{}
+	path    string
+}
+
+// newEqualityHandler returens instance of equality handler
+func newEqualityHandler(anchor Anchor, pattern interface{}, path string) ValidationHandler {
+	return equalityHandler{
+		anchor:  anchor,
+		pattern: pattern,
+		path:    path,
+	}
+}
+
+// Handle processed condition anchor
+func (eh equalityHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorMap) (string, error) {
+	anchorKey := eh.anchor.Key()
+	currentPath := eh.path + anchorKey + "/"
+	// check if anchor is present in resource
+	if value, ok := resourceMap[anchorKey]; ok {
+		// validate the values of the pattern
+		returnPath, err := handler(logging.GlobalLogger(), value, eh.pattern, originPattern, currentPath, ac)
+		if err != nil {
+			return returnPath, err
+		}
+		return "", nil
+	}
+	return "", nil
+}
+
+// defaultHandler provides handler for non anchor element
+type defaultHandler struct {
+	element string
+	pattern interface{}
+	path    string
+}
+
+// newDefaultHandler returns handler for non anchor elements
+func newDefaultHandler(element string, pattern interface{}, path string) ValidationHandler {
+	return defaultHandler{
+		element: element,
+		pattern: pattern,
+		path:    path,
+	}
+}
+
+// Handle process non anchor element
+func (dh defaultHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorMap) (string, error) {
+	currentPath := dh.path + dh.element + "/"
+	if dh.pattern == "*" && resourceMap[dh.element] != nil {
+		return "", nil
+	} else if dh.pattern == "*" && resourceMap[dh.element] == nil {
+		return dh.path, fmt.Errorf("%s/%s not found", dh.path, dh.element)
+	} else {
+		path, err := handler(logging.GlobalLogger(), resourceMap[dh.element], dh.pattern, originPattern, currentPath, ac)
+		if err != nil {
+			return path, err
+		}
+	}
+	return "", nil
+}
+
+// conditionAnchorHandler provides handler for condition anchor
+type conditionAnchorHandler struct {
+	anchor  Anchor
+	pattern interface{}
+	path    string
+}
+
+// newConditionAnchorHandler returns an instance of condition acnhor handler
+func newConditionAnchorHandler(anchor Anchor, pattern interface{}, path string) ValidationHandler {
+	return conditionAnchorHandler{
+		anchor:  anchor,
+		pattern: pattern,
+		path:    path,
+	}
+}
+
+// Handle processed condition anchor
+func (ch conditionAnchorHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorMap) (string, error) {
+	anchorKey := ch.anchor.Key()
+	currentPath := ch.path + anchorKey + "/"
+	// check if anchor is present in resource
+	if value, ok := resourceMap[anchorKey]; ok {
+		// validate the values of the pattern
+		returnPath, err := handler(logging.GlobalLogger(), value, ch.pattern, originPattern, currentPath, ac)
+		if err != nil {
+			ac.AnchorError = newConditionalAnchorError(err.Error())
+			return returnPath, ac.AnchorError
+		}
+		return "", nil
+	} else {
+		msg := "conditional anchor key doesn't exist in the resource"
+		return currentPath, newConditionalAnchorError(msg)
+	}
+}
+
+// globalAnchorHandler provides handler for global condition anchor
+type globalAnchorHandler struct {
+	anchor  Anchor
+	pattern interface{}
+	path    string
+}
+
+// newGlobalAnchorHandler returns an instance of condition acnhor handler
+func newGlobalAnchorHandler(anchor Anchor, pattern interface{}, path string) ValidationHandler {
+	return globalAnchorHandler{
+		anchor:  anchor,
+		pattern: pattern,
+		path:    path,
+	}
+}
+
+// Handle processed global condition anchor
+func (gh globalAnchorHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorMap) (string, error) {
+	anchorKey := gh.anchor.Key()
+	currentPath := gh.path + anchorKey + "/"
+	// check if anchor is present in resource
+	if value, ok := resourceMap[anchorKey]; ok {
+		// validate the values of the pattern
+		returnPath, err := handler(logging.GlobalLogger(), value, gh.pattern, originPattern, currentPath, ac)
+		if err != nil {
+			ac.AnchorError = newGlobalAnchorError(err.Error())
+			return returnPath, ac.AnchorError
+		}
+		return "", nil
+	}
+	return "", nil
+}
+
+// existenceHandler provides handlers to process exitence anchor handler
+type existenceHandler struct {
+	anchor  Anchor
+	pattern interface{}
+	path    string
+}
+
+// newExistenceHandler returns existence handler
+func newExistenceHandler(anchor Anchor, pattern interface{}, path string) ValidationHandler {
+	return existenceHandler{
+		anchor:  anchor,
+		pattern: pattern,
+		path:    path,
+	}
+}
+
+// Handle processes the existence anchor handler
+func (eh existenceHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}, ac *AnchorMap) (string, error) {
+	// skip is used by existence anchor to not process further if condition is not satisfied
+	anchorKey := eh.anchor.Key()
+	currentPath := eh.path + anchorKey + "/"
+	// check if anchor is present in resource
+	if value, ok := resourceMap[anchorKey]; ok {
+		// Existence anchor can only exist on resource value type of list
+		switch typedResource := value.(type) {
+		case []interface{}:
+			typedPattern, ok := eh.pattern.([]interface{})
+			if !ok {
+				return currentPath, fmt.Errorf("invalid pattern type %T: Pattern has to be of list to compare against resource", eh.pattern)
+			}
+			// loop all item in the pattern array
+			errorPath := ""
+			var err error
+			for _, patternMap := range typedPattern {
+				typedPatternMap, ok := patternMap.(map[string]interface{})
+				if !ok {
+					return currentPath, fmt.Errorf("invalid pattern type %T: Pattern has to be of type map to compare against items in resource", eh.pattern)
+				}
+				errorPath, err = validateExistenceListResource(handler, typedResource, typedPatternMap, originPattern, currentPath, ac)
+				if err != nil {
+					return errorPath, err
+				}
+			}
+			return errorPath, err
+		default:
+			return currentPath, fmt.Errorf("invalid resource type %T: Existence ^ () anchor can be used only on list/array type resource", value)
+		}
+	}
+	return "", nil
+}
+
+func validateExistenceListResource(handler resourceElementHandler, resourceList []interface{}, patternMap map[string]interface{}, originPattern interface{}, path string, ac *AnchorMap) (string, error) {
+	// the idea is all the element in the pattern array should be present atleast once in the resource list
+	// if non satisfy then throw an error
+	for i, resourceElement := range resourceList {
+		currentPath := path + strconv.Itoa(i) + "/"
+		_, err := handler(logging.GlobalLogger(), resourceElement, patternMap, originPattern, currentPath, ac)
+		if err == nil {
+			// condition is satisfied, dont check further
+			return "", nil
+		}
+	}
+	// none of the existence checks worked, so thats a failure sceanario
+	return path, fmt.Errorf("existence anchor validation failed at path %s", path)
+}
diff --git a/pkg/engine/anchor/utils.go b/pkg/engine/anchor/utils.go
new file mode 100644
index 0000000000..79063bc35f
--- /dev/null
+++ b/pkg/engine/anchor/utils.go
@@ -0,0 +1,60 @@
+package anchor
+
+import (
+	"path"
+	"strings"
+)
+
+// GetAnchorsResourcesFromMap returns maps of anchors and resources
+func GetAnchorsResourcesFromMap(patternMap map[string]interface{}) (map[string]interface{}, map[string]interface{}) {
+	anchors := map[string]interface{}{}
+	resources := map[string]interface{}{}
+	for key, value := range patternMap {
+		if a := Parse(key); IsCondition(a) || IsExistence(a) || IsEquality(a) || IsNegation(a) {
+			anchors[key] = value
+		} else {
+			resources[key] = value
+		}
+	}
+	return anchors, resources
+}
+
+// RemoveAnchorsFromPath removes all anchor from path string
+func RemoveAnchorsFromPath(str string) string {
+	parts := strings.Split(str, "/")
+	if parts[0] == "" {
+		parts = parts[1:]
+	}
+	for i, part := range parts {
+		if a := Parse(part); a != nil {
+			parts[i] = a.Key()
+		} else {
+			parts[i] = part
+		}
+	}
+	newPath := path.Join(parts...)
+	if path.IsAbs(str) {
+		newPath = "/" + newPath
+	}
+	return newPath
+}
+
+// resourceHasValueForKey checks if a resource has value for a given key
+func resourceHasValueForKey(resource interface{}, key string) bool {
+	switch typed := resource.(type) {
+	case map[string]interface{}:
+		if _, ok := typed[key]; ok {
+			return true
+		}
+		return false
+	case []interface{}:
+		for _, value := range typed {
+			if resourceHasValueForKey(value, key) {
+				return true
+			}
+		}
+		return false
+	default:
+		return false
+	}
+}
diff --git a/pkg/engine/anchor/utils_test.go b/pkg/engine/anchor/utils_test.go
new file mode 100644
index 0000000000..d47c143780
--- /dev/null
+++ b/pkg/engine/anchor/utils_test.go
@@ -0,0 +1,126 @@
+package anchor
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestRemoveAnchorsFromPath(t *testing.T) {
+	tests := []struct {
+		name string
+		str  string
+		want string
+	}{{
+		str:  "/path/(to)/X(anchors)",
+		want: "/path/to/anchors",
+	}, {
+		str:  "path/(to)/X(anchors)",
+		want: "path/to/anchors",
+	}, {
+		str:  "../(to)/X(anchors)",
+		want: "../to/anchors",
+	}, {
+		str:  "/path/(to)/X(anchors)",
+		want: "/path/to/anchors",
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := RemoveAnchorsFromPath(tt.str); got != tt.want {
+				t.Errorf("RemoveAnchorsFromPath() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGetAnchorsResourcesFromMap(t *testing.T) {
+	tests := []struct {
+		name          string
+		patternMap    map[string]interface{}
+		wantAnchors   map[string]interface{}
+		wantResources map[string]interface{}
+	}{{
+		patternMap: map[string]interface{}{
+			"spec": "test",
+		},
+		wantAnchors: map[string]interface{}{},
+		wantResources: map[string]interface{}{
+			"spec": "test",
+		},
+	}, {
+		patternMap: map[string]interface{}{
+			"(spec)": "test",
+		},
+		wantAnchors: map[string]interface{}{
+			"(spec)": "test",
+		},
+		wantResources: map[string]interface{}{},
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			anchors, resources := GetAnchorsResourcesFromMap(tt.patternMap)
+			if !reflect.DeepEqual(anchors, tt.wantAnchors) {
+				t.Errorf("GetAnchorsResourcesFromMap() anchors = %v, want %v", anchors, tt.wantAnchors)
+			}
+			if !reflect.DeepEqual(resources, tt.wantResources) {
+				t.Errorf("GetAnchorsResourcesFromMap() resources = %v, want %v", resources, tt.wantResources)
+			}
+		})
+	}
+}
+
+func Test_resourceHasValueForKey(t *testing.T) {
+	type args struct {
+		resource interface{}
+		key      string
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{{
+		args: args{
+			resource: map[string]interface{}{
+				"spec": 123,
+			},
+			key: "spec",
+		},
+		want: true,
+	}, {
+		args: args{
+			resource: map[string]interface{}{
+				"spec": 123,
+			},
+			key: "metadata",
+		},
+		want: false,
+	}, {
+		args: args{
+			resource: []interface{}{1, 2, 3},
+			key:      "spec",
+		},
+		want: false,
+	}, {
+		args: args{
+			resource: []interface{}{
+				map[string]interface{}{
+					"spec": 123,
+				},
+			},
+			key: "spec",
+		},
+		want: true,
+	}, {
+		args: args{
+			resource: 123,
+			key:      "spec",
+		},
+		want: false,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := resourceHasValueForKey(tt.args.resource, tt.args.key); got != tt.want {
+				t.Errorf("resourceHasValueForKey() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/pkg/engine/mutate/patch/strategicPreprocessing.go b/pkg/engine/mutate/patch/strategicPreprocessing.go
index cdf473ce58..3d0d07cb5f 100644
--- a/pkg/engine/mutate/patch/strategicPreprocessing.go
+++ b/pkg/engine/mutate/patch/strategicPreprocessing.go
@@ -73,12 +73,10 @@ func walkMap(logger logr.Logger, pattern, resource *yaml.RNode) error {
 	if err := validateConditions(logger, pattern, resource); err != nil {
 		return err // do not wrap condition errors
 	}
-
-	isNotAnchor := func(key string) bool {
-		return !hasAnchor(key)
+	isNotAnchor := func(a anchor.Anchor) bool {
+		return !hasAnchor(a)
 	}
-
-	nonAnchors, err := filterKeys(pattern, isNotAnchor)
+	nonAnchors, err := nonAnchorKeys(pattern, isNotAnchor)
 	if err != nil {
 		return err
 	}
@@ -133,7 +131,7 @@ func processListOfMaps(logger logr.Logger, pattern, resource *yaml.RNode) error
 	for _, patternElement := range patternElements {
 		// If pattern has conditions, look for matching elements and process them
 		hasAnyAnchor := hasAnchors(patternElement, hasAnchor)
-		hasGlobalConditions := hasAnchors(patternElement, anchor.IsGlobalAnchor)
+		hasGlobalConditions := hasAnchors(patternElement, anchor.IsGlobal)
 		if hasAnyAnchor {
 			anyGlobalConditionPassed := false
 			var lastGlobalAnchorError error = nil
@@ -238,12 +236,12 @@ func isGlobalConditionError(err error) bool {
 // If caller handles map, it must stop processing and skip entire rule.
 func validateConditions(logger logr.Logger, pattern, resource *yaml.RNode) error {
 	var err error
-	err = validateConditionsInternal(logger, pattern, resource, anchor.IsGlobalAnchor)
+	err = validateConditionsInternal(logger, pattern, resource, anchor.IsGlobal)
 	if err != nil {
 		return NewGlobalConditionError(err)
 	}
 
-	err = validateConditionsInternal(logger, pattern, resource, anchor.IsConditionAnchor)
+	err = validateConditionsInternal(logger, pattern, resource, anchor.IsCondition)
 	if err != nil {
 		return NewConditionError(err)
 	}
@@ -255,62 +253,72 @@ func validateConditions(logger logr.Logger, pattern, resource *yaml.RNode) error
 // Remove anchor from pattern, if field already exists.
 // Remove anchor wrapping from key, if field does not exist in the resource.
 func handleAddIfNotPresentAnchor(pattern, resource *yaml.RNode) (int, error) {
-	anchors, err := filterKeys(pattern, anchor.IsAddIfNotPresentAnchor)
+	anchors, err := filterKeys(pattern, anchor.IsAddIfNotPresent)
 	if err != nil {
 		return 0, err
 	}
 
 	for _, a := range anchors {
-		key, _ := anchor.RemoveAnchor(a)
+		key := a.Key()
 		if resource != nil && resource.Field(key) != nil {
 			// Resource already has this field.
 			// Delete the field with addIfNotPresent anchor from patch.
-			err = pattern.PipeE(yaml.Clear(a))
+			err = pattern.PipeE(yaml.Clear(a.String()))
 			if err != nil {
 				return 0, err
 			}
 		} else {
 			// Remove anchor tags from patch field key.
-			renameField(a, key, pattern)
+			renameField(a.String(), key, pattern)
 		}
 	}
 
 	return len(anchors), nil
 }
 
-func filterKeys(pattern *yaml.RNode, condition func(string) bool) ([]string, error) {
+func filterKeys(pattern *yaml.RNode, condition func(anchor.Anchor) bool) ([]anchor.Anchor, error) {
 	if !isMappingNode(pattern) {
 		return nil, nil
 	}
-
-	keys := make([]string, 0)
 	fields, err := pattern.Fields()
 	if err != nil {
-		return keys, err
+		return nil, err
 	}
+	var anchors []anchor.Anchor
+	for _, field := range fields {
+		if a := anchor.Parse(field); a != nil && condition(a) {
+			anchors = append(anchors, a)
+		}
+	}
+	return anchors, nil
+}
 
-	for _, key := range fields {
-		if condition(key) {
-			keys = append(keys, key)
-			continue
+func nonAnchorKeys(pattern *yaml.RNode, condition func(anchor.Anchor) bool) ([]string, error) {
+	if !isMappingNode(pattern) {
+		return nil, nil
+	}
+	fields, err := pattern.Fields()
+	if err != nil {
+		return nil, err
+	}
+	var keys []string
+	for _, field := range fields {
+		if a := anchor.Parse(field); a == nil || condition(a) {
+			keys = append(keys, field)
 		}
 	}
 	return keys, nil
 }
 
 func isMappingNode(node *yaml.RNode) bool {
-	if err := yaml.ErrorIfInvalid(node, yaml.MappingNode); err != nil {
-		return false
-	}
-
-	return true
+	return yaml.ErrorIfInvalid(node, yaml.MappingNode) == nil
 }
 
-func hasAnchor(key string) bool {
-	return anchor.ContainsCondition(key) || anchor.IsAddIfNotPresentAnchor(key)
+func hasAnchor(a anchor.Anchor) bool {
+	return anchor.ContainsCondition(a) || anchor.IsAddIfNotPresent(a)
 }
 
-func hasAnchors(pattern *yaml.RNode, isAnchor func(key string) bool) bool {
+func hasAnchors(pattern *yaml.RNode, isAnchor func(anchor.Anchor) bool) bool {
 	ynode := pattern.YNode() //nolint:ifshort
 	if ynode.Kind == yaml.MappingNode {
 		fields, err := pattern.Fields()
@@ -319,10 +327,9 @@ func hasAnchors(pattern *yaml.RNode, isAnchor func(key string) bool) bool {
 		}
 
 		for _, key := range fields {
-			if isAnchor(key) {
+			if a := anchor.Parse(key); a != nil && isAnchor(a) {
 				return true
 			}
-
 			patternNode := pattern.Field(key)
 			if !patternNode.IsNilOrEmpty() {
 				if hasAnchors(patternNode.Value, isAnchor) {
@@ -331,8 +338,7 @@ func hasAnchors(pattern *yaml.RNode, isAnchor func(key string) bool) bool {
 			}
 		}
 	} else if ynode.Kind == yaml.ScalarNode {
-		v := ynode.Value
-		return anchor.ContainsCondition(v)
+		return anchor.ContainsCondition(anchor.Parse(ynode.Value))
 	} else if ynode.Kind == yaml.SequenceNode {
 		elements, _ := pattern.Elements()
 		for _, e := range elements {
@@ -352,7 +358,6 @@ func renameField(name, newName string, pattern *yaml.RNode) {
 	if field == nil {
 		return
 	}
-
 	field.Key.YNode().Value = newName
 }
 
@@ -402,7 +407,7 @@ func deleteConditionElements(pattern *yaml.RNode) error {
 	}
 
 	for _, field := range fields {
-		deleteScalar := anchor.ContainsCondition(field)
+		deleteScalar := anchor.ContainsCondition(anchor.Parse(field))
 		canDelete, err := deleteAnchors(pattern.Field(field).Value, deleteScalar, false)
 		if err != nil {
 			return err
@@ -438,22 +443,20 @@ func deleteAnchors(node *yaml.RNode, deleteScalar, traverseMappingNodes bool) (b
 }
 
 func deleteAnchorsInMap(node *yaml.RNode, traverseMappingNodes bool) (bool, error) {
-	conditions, err := filterKeys(node, anchor.ContainsCondition)
+	anchors, err := filterKeys(node, anchor.ContainsCondition)
 	if err != nil {
 		return false, err
 	}
-
 	// remove all conditional anchors with no child nodes first
 	anchorsExist := false
-	for _, condition := range conditions {
-		field := node.Field(condition)
+	for _, a := range anchors {
+		field := node.Field(a.String())
 		shouldDelete, err := deleteAnchors(field.Value, true, traverseMappingNodes)
 		if err != nil {
 			return false, err
 		}
-
 		if shouldDelete {
-			if err := node.PipeE(yaml.Clear(condition)); err != nil {
+			if err := node.PipeE(yaml.Clear(a.String())); err != nil {
 				return false, err
 			}
 		} else {
@@ -502,14 +505,12 @@ func stripAnchorsFromNode(node *yaml.RNode, key string) error {
 	if err != nil {
 		return err
 	}
-
 	for _, a := range anchors {
-		k, _ := anchor.RemoveAnchor(a)
+		k := a.Key()
 		if key == "" || k == key {
-			renameField(a, k, node)
+			renameField(a.String(), k, node)
 		}
 	}
-
 	return nil
 }
 
@@ -562,19 +563,17 @@ func deleteListElement(list *yaml.RNode, i int) {
 	list.YNode().Content = append(content[:i], content[i+1:]...)
 }
 
-func validateConditionsInternal(logger logr.Logger, pattern, resource *yaml.RNode, filter func(string) bool) error {
-	conditions, err := filterKeys(pattern, filter)
+func validateConditionsInternal(logger logr.Logger, pattern, resource *yaml.RNode, filter func(anchor.Anchor) bool) error {
+	anchors, err := filterKeys(pattern, filter)
 	if err != nil {
 		return err
 	}
-
-	for _, condition := range conditions {
-		conditionKey, _ := anchor.RemoveAnchor(condition)
+	for _, a := range anchors {
+		conditionKey := a.Key()
 		if resource == nil || resource.Field(conditionKey) == nil {
 			return fmt.Errorf("could not found \"%s\" key in the resource", conditionKey)
 		}
-
-		patternValue := pattern.Field(condition).Value
+		patternValue := pattern.Field(a.String()).Value
 		resourceValue := resource.Field(conditionKey).Value
 		if count, err := handleAddIfNotPresentAnchor(patternValue, resourceValue); err != nil {
 			return err
diff --git a/pkg/engine/mutate/patch/strategicPreprocessing_test.go b/pkg/engine/mutate/patch/strategicPreprocessing_test.go
index 628bbea94e..41e638a4fe 100644
--- a/pkg/engine/mutate/patch/strategicPreprocessing_test.go
+++ b/pkg/engine/mutate/patch/strategicPreprocessing_test.go
@@ -986,7 +986,7 @@ func Test_FilterKeys_NoConditions(t *testing.T) {
 	}`)
 
 	pattern := yaml.MustParse(string(patternRaw))
-	conditions, err := filterKeys(pattern, anchor.IsConditionAnchor)
+	conditions, err := filterKeys(pattern, anchor.IsCondition)
 
 	assert.NilError(t, err)
 	assert.Equal(t, len(conditions), 0)
@@ -1000,18 +1000,18 @@ func Test_FilterKeys_ConditionsArePresent(t *testing.T) {
 	}`)
 
 	pattern := yaml.MustParse(string(patternRaw))
-	conditions, err := filterKeys(pattern, anchor.IsConditionAnchor)
+	conditions, err := filterKeys(pattern, anchor.IsCondition)
 
 	assert.NilError(t, err)
 	assert.Equal(t, len(conditions), 2)
-	assert.Equal(t, conditions[0], "(key2)")
-	assert.Equal(t, conditions[1], "(key3)")
+	assert.Equal(t, conditions[0].String(), "(key2)")
+	assert.Equal(t, conditions[1].String(), "(key3)")
 }
 
 func Test_FilterKeys_EmptyList(t *testing.T) {
 	patternRaw := []byte(`{}`)
 	pattern := yaml.MustParse(string(patternRaw))
-	conditions, err := filterKeys(pattern, anchor.IsConditionAnchor)
+	conditions, err := filterKeys(pattern, anchor.IsCondition)
 
 	assert.NilError(t, err)
 	assert.Equal(t, len(conditions), 0)
diff --git a/pkg/engine/utils/utils.go b/pkg/engine/utils/utils.go
index e3ea8afb74..e8f40a66ac 100644
--- a/pkg/engine/utils/utils.go
+++ b/pkg/engine/utils/utils.go
@@ -2,7 +2,7 @@ package utils
 
 import (
 	jsonpatch "github.com/evanphx/json-patch/v5"
-	commonAnchor "github.com/kyverno/kyverno/pkg/engine/anchor"
+	"github.com/kyverno/kyverno/pkg/engine/anchor"
 	"github.com/kyverno/kyverno/pkg/logging"
 	jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
 )
@@ -48,12 +48,10 @@ func ApplyPatchNew(resource, patch []byte) ([]byte, error) {
 // GetAnchorsFromMap gets the conditional anchor map
 func GetAnchorsFromMap(anchorsMap map[string]interface{}) map[string]interface{} {
 	result := make(map[string]interface{})
-
 	for key, value := range anchorsMap {
-		if commonAnchor.IsConditionAnchor(key) {
+		if anchor.IsCondition(anchor.Parse(key)) {
 			result[key] = value
 		}
 	}
-
 	return result
 }
diff --git a/pkg/engine/validate/utils.go b/pkg/engine/validate/utils.go
index ee369bf1b6..4cbc5fce9f 100644
--- a/pkg/engine/validate/utils.go
+++ b/pkg/engine/validate/utils.go
@@ -4,7 +4,7 @@ import (
 	"container/list"
 	"sort"
 
-	commonAnchors "github.com/kyverno/kyverno/pkg/engine/anchor"
+	"github.com/kyverno/kyverno/pkg/engine/anchor"
 )
 
 // Checks if pattern has anchors
@@ -44,7 +44,7 @@ func getSortedNestedAnchorResource(resources map[string]interface{}) *list.List
 
 	for _, k := range keys {
 		v := resources[k]
-		if commonAnchors.IsGlobalAnchor(k) {
+		if anchor.IsGlobal(anchor.Parse(k)) {
 			sortedResourceKeys.PushFront(k)
 			continue
 		}
@@ -61,7 +61,7 @@ func getSortedNestedAnchorResource(resources map[string]interface{}) *list.List
 func getAnchorsFromMap(anchorsMap map[string]interface{}) map[string]interface{} {
 	result := make(map[string]interface{})
 	for key, value := range anchorsMap {
-		if commonAnchors.IsConditionAnchor(key) || commonAnchors.IsExistenceAnchor(key) || commonAnchors.IsEqualityAnchor(key) || commonAnchors.IsNegationAnchor(key) || commonAnchors.IsGlobalAnchor(key) {
+		if a := anchor.Parse(key); anchor.IsCondition(a) || anchor.IsExistence(a) || anchor.IsEquality(a) || anchor.IsNegation(a) || anchor.IsGlobal(a) {
 			result[key] = value
 		}
 	}
diff --git a/pkg/engine/validate/validate.go b/pkg/engine/validate/validate.go
index ba78926445..58cb965f2d 100644
--- a/pkg/engine/validate/validate.go
+++ b/pkg/engine/validate/validate.go
@@ -44,7 +44,7 @@ func MatchPattern(logger logr.Logger, resource, pattern interface{}) error {
 		}
 
 		// check if an anchor defined in the policy rule is missing in the resource
-		if ac.IsAnchorError() {
+		if ac.KeysAreMissing() {
 			logger.V(3).Info("missing anchor in resource")
 			return &PatternError{err, "", false}
 		}
@@ -57,18 +57,18 @@ func MatchPattern(logger logr.Logger, resource, pattern interface{}) error {
 
 func skip(err error) bool {
 	// if conditional or global anchors report errors, the rule does not apply to the resource
-	return anchor.IsConditionalAnchorError(err.Error()) || anchor.IsGlobalAnchorError(err.Error())
+	return anchor.IsConditionalAnchorError(err) || anchor.IsGlobalAnchorError(err)
 }
 
 func fail(err error) bool {
 	// if negation anchors report errors, the rule will fail
-	return anchor.IsNegationAnchorError(err.Error())
+	return anchor.IsNegationAnchorError(err)
 }
 
 // validateResourceElement detects the element type (map, array, nil, string, int, bool, float)
 // and calls corresponding handler
 // Pattern tree and resource tree can have different structure. In this case validation fails
-func validateResourceElement(log logr.Logger, resourceElement, patternElement, originPattern interface{}, path string, ac *anchor.AnchorKey) (string, error) {
+func validateResourceElement(log logr.Logger, resourceElement, patternElement, originPattern interface{}, path string, ac *anchor.AnchorMap) (string, error) {
 	switch typedPatternElement := patternElement.(type) {
 	// map
 	case map[string]interface{}:
@@ -115,7 +115,7 @@ func validateResourceElement(log logr.Logger, resourceElement, patternElement, o
 
 // If validateResourceElement detects map element inside resource and pattern trees, it goes to validateMap
 // For each element of the map we must detect the type again, so we pass these elements to validateResourceElement
-func validateMap(log logr.Logger, resourceMap, patternMap map[string]interface{}, origPattern interface{}, path string, ac *anchor.AnchorKey) (string, error) {
+func validateMap(log logr.Logger, resourceMap, patternMap map[string]interface{}, origPattern interface{}, path string, ac *anchor.AnchorMap) (string, error) {
 	patternMap = wildcards.ExpandInMetadata(patternMap, resourceMap)
 	// check if there is anchor in pattern
 	// Phase 1 : Evaluate all the anchors
@@ -160,7 +160,7 @@ func validateMap(log logr.Logger, resourceMap, patternMap map[string]interface{}
 	return "", nil
 }
 
-func validateArray(log logr.Logger, resourceArray, patternArray []interface{}, originPattern interface{}, path string, ac *anchor.AnchorKey) (string, error) {
+func validateArray(log logr.Logger, resourceArray, patternArray []interface{}, originPattern interface{}, path string, ac *anchor.AnchorMap) (string, error) {
 	if len(patternArray) == 0 {
 		return path, fmt.Errorf("pattern Array empty")
 	}
@@ -215,7 +215,7 @@ func validateArray(log logr.Logger, resourceArray, patternArray []interface{}, o
 
 // validateArrayOfMaps gets anchors from pattern array map element, applies anchors logic
 // and then validates each map due to the pattern
-func validateArrayOfMaps(log logr.Logger, resourceMapArray []interface{}, patternMap map[string]interface{}, originPattern interface{}, path string, ac *anchor.AnchorKey) (string, error) {
+func validateArrayOfMaps(log logr.Logger, resourceMapArray []interface{}, patternMap map[string]interface{}, originPattern interface{}, path string, ac *anchor.AnchorMap) (string, error) {
 	applyCount := 0
 	skipErrors := make([]error, 0)
 	for i, resourceElement := range resourceMapArray {
diff --git a/pkg/engine/wildcards/wildcards.go b/pkg/engine/wildcards/wildcards.go
index 1919a01c1e..45706799c4 100644
--- a/pkg/engine/wildcards/wildcards.go
+++ b/pkg/engine/wildcards/wildcards.go
@@ -3,7 +3,7 @@ package wildcards
 import (
 	"strings"
 
-	commonAnchor "github.com/kyverno/kyverno/pkg/engine/anchor"
+	"github.com/kyverno/kyverno/pkg/engine/anchor"
 	wildcard "github.com/kyverno/kyverno/pkg/utils/wildcard"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
@@ -27,7 +27,6 @@ func replaceWildcardsInMapKeyValues(patternMap map[string]string, resourceMap ma
 			result[k] = v
 		}
 	}
-
 	return result
 }
 
@@ -41,12 +40,10 @@ func expandWildcards(k, v string, resourceMap map[string]string, matchValue, rep
 			}
 		}
 	}
-
 	if replace {
 		k = replaceWildCardChars(k)
 		v = replaceWildCardChars(v)
 	}
-
 	return k, v
 }
 
@@ -78,23 +75,22 @@ func ExpandInMetadata(patternMap, resourceMap map[string]interface{}) map[string
 	if labels != nil {
 		metadata[labelsKey] = labels
 	}
-
 	annotationsKey, annotations := expandWildcardsInTag("annotations", patternMetadata, resourceMetadata)
 	if annotations != nil {
 		metadata[annotationsKey] = annotations
 	}
-
 	return patternMap
 }
 
 func getPatternValue(tag string, pattern map[string]interface{}) (string, interface{}) {
 	for k, v := range pattern {
-		k2, _ := commonAnchor.RemoveAnchor(k)
-		if k2 == tag {
+		if k == tag {
+			return k, v
+		}
+		if a := anchor.Parse(k); a != nil && a.Key() == tag {
 			return k, v
 		}
 	}
-
 	return "", nil
 }
 
@@ -140,17 +136,16 @@ func replaceWildcardsInMapKeys(patternData, resourceData map[string]string) map[
 	results := map[string]interface{}{}
 	for k, v := range patternData {
 		if wildcard.ContainsWildcard(k) {
-			anchorFreeKey, anchorPrefix := commonAnchor.RemoveAnchor(k)
-			matchK, _ := expandWildcards(anchorFreeKey, v, resourceData, false, false)
-			if anchorPrefix != "" {
-				matchK = commonAnchor.AddAnchor(matchK, anchorPrefix)
+			if a := anchor.Parse(k); a != nil {
+				matchK, _ := expandWildcards(a.Key(), v, resourceData, false, false)
+				results[anchor.String(a.Type(), matchK)] = v
+			} else {
+				matchK, _ := expandWildcards(k, v, resourceData, false, false)
+				results[matchK] = v
 			}
-
-			results[matchK] = v
 		} else {
 			results[k] = v
 		}
 	}
-
 	return results
 }
diff --git a/pkg/policy/common/validate_pattern.go b/pkg/policy/common/validate_pattern.go
index de34838830..cd4c008582 100644
--- a/pkg/policy/common/validate_pattern.go
+++ b/pkg/policy/common/validate_pattern.go
@@ -2,19 +2,18 @@ package common
 
 import (
 	"fmt"
-	"regexp"
 	"strconv"
 
-	commonAnchors "github.com/kyverno/kyverno/pkg/engine/anchor"
+	"github.com/kyverno/kyverno/pkg/engine/anchor"
 )
 
 // ValidatePattern validates the pattern
-func ValidatePattern(patternElement interface{}, path string, supportedAnchors []commonAnchors.IsAnchor) (string, error) {
+func ValidatePattern(patternElement interface{}, path string, isSupported func(anchor.Anchor) bool) (string, error) {
 	switch typedPatternElement := patternElement.(type) {
 	case map[string]interface{}:
-		return validateMap(typedPatternElement, path, supportedAnchors)
+		return validateMap(typedPatternElement, path, isSupported)
 	case []interface{}:
-		return validateArray(typedPatternElement, path, supportedAnchors)
+		return validateArray(typedPatternElement, path, isSupported)
 	case string, float64, int, int64, bool, nil:
 		// TODO: check operator
 		return "", nil
@@ -23,30 +22,21 @@ func ValidatePattern(patternElement interface{}, path string, supportedAnchors [
 	}
 }
 
-func validateMap(patternMap map[string]interface{}, path string, supportedAnchors []commonAnchors.IsAnchor) (string, error) {
+func validateMap(patternMap map[string]interface{}, path string, isSupported func(anchor.Anchor) bool) (string, error) {
 	// check if anchors are defined
 	for key, value := range patternMap {
 		// if key is anchor
-		// check regex () -> this is anchor
-		// ()
-		// single char ()
-		re, err := regexp.Compile(`^.?\(.+\)$`)
-		if err != nil {
-			return path + "/" + key, fmt.Errorf("unable to parse the field %s: %v", key, err)
-		}
-
-		matched := re.MatchString(key)
+		a := anchor.Parse(key)
 		// check the type of anchor
-		if matched {
+		if a != nil {
 			// some type of anchor
 			// check if valid anchor
-			if !checkAnchors(key, supportedAnchors) {
+			if !checkAnchors(a, isSupported) {
 				return path + "/" + key, fmt.Errorf("unsupported anchor %s", key)
 			}
-
 			// addition check for existence anchor
 			// value must be of type list
-			if commonAnchors.IsExistenceAnchor(key) {
+			if anchor.IsExistence(a) {
 				typedValue, ok := value.([]interface{})
 				if !ok {
 					return path + "/" + key, fmt.Errorf("existence anchor should have value of type list")
@@ -58,29 +48,27 @@ func validateMap(patternMap map[string]interface{}, path string, supportedAnchor
 			}
 		}
 		// lets validate the values now :)
-		if errPath, err := ValidatePattern(value, path+"/"+key, supportedAnchors); err != nil {
+		if errPath, err := ValidatePattern(value, path+"/"+key, isSupported); err != nil {
 			return errPath, err
 		}
 	}
 	return "", nil
 }
 
-func validateArray(patternArray []interface{}, path string, supportedAnchors []commonAnchors.IsAnchor) (string, error) {
+func validateArray(patternArray []interface{}, path string, isSupported func(anchor.Anchor) bool) (string, error) {
 	for i, patternElement := range patternArray {
 		currentPath := path + strconv.Itoa(i) + "/"
 		// lets validate the values now :)
-		if errPath, err := ValidatePattern(patternElement, currentPath, supportedAnchors); err != nil {
+		if errPath, err := ValidatePattern(patternElement, currentPath, isSupported); err != nil {
 			return errPath, err
 		}
 	}
 	return "", nil
 }
 
-func checkAnchors(key string, supportedAnchors []commonAnchors.IsAnchor) bool {
-	for _, f := range supportedAnchors {
-		if f(key) {
-			return true
-		}
+func checkAnchors(a anchor.Anchor, isSupported func(anchor.Anchor) bool) bool {
+	if isSupported == nil {
+		return false
 	}
-	return false
+	return isSupported(a)
 }
diff --git a/pkg/policy/generate/validate.go b/pkg/policy/generate/validate.go
index 0d1e2875c5..2f4a29a94d 100644
--- a/pkg/policy/generate/validate.go
+++ b/pkg/policy/generate/validate.go
@@ -8,7 +8,6 @@ import (
 	"github.com/go-logr/logr"
 	kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
 	"github.com/kyverno/kyverno/pkg/clients/dclient"
-	commonAnchors "github.com/kyverno/kyverno/pkg/engine/anchor"
 	"github.com/kyverno/kyverno/pkg/engine/variables"
 	"github.com/kyverno/kyverno/pkg/policy/common"
 	kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@@ -79,7 +78,7 @@ func (g *Generate) Validate() (string, error) {
 	if target := rule.GetData(); target != nil {
 		// TODO: is this required ?? as anchors can only be on pattern and not resource
 		// we can add this check by not sure if its needed here
-		if path, err := common.ValidatePattern(target, "/", []commonAnchors.IsAnchor{}); err != nil {
+		if path, err := common.ValidatePattern(target, "/", nil); err != nil {
 			return fmt.Sprintf("data.%s", path), fmt.Errorf("anchors not supported on generate resources: %v", err)
 		}
 	}
diff --git a/pkg/policy/validate/validate.go b/pkg/policy/validate/validate.go
index 5d0d88e6a2..7c9d792a03 100644
--- a/pkg/policy/validate/validate.go
+++ b/pkg/policy/validate/validate.go
@@ -4,7 +4,7 @@ import (
 	"fmt"
 
 	kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
-	commonAnchors "github.com/kyverno/kyverno/pkg/engine/anchor"
+	"github.com/kyverno/kyverno/pkg/engine/anchor"
 	"github.com/kyverno/kyverno/pkg/policy/common"
 )
 
@@ -30,7 +30,13 @@ func (v *Validate) Validate() (string, error) {
 	}
 
 	if target := v.rule.GetPattern(); target != nil {
-		if path, err := common.ValidatePattern(target, "/", []commonAnchors.IsAnchor{commonAnchors.IsConditionAnchor, commonAnchors.IsExistenceAnchor, commonAnchors.IsEqualityAnchor, commonAnchors.IsNegationAnchor, commonAnchors.IsGlobalAnchor}); err != nil {
+		if path, err := common.ValidatePattern(target, "/", func(a anchor.Anchor) bool {
+			return anchor.IsCondition(a) ||
+				anchor.IsExistence(a) ||
+				anchor.IsEquality(a) ||
+				anchor.IsNegation(a) ||
+				anchor.IsGlobal(a)
+		}); err != nil {
 			return fmt.Sprintf("pattern.%s", path), err
 		}
 	}
@@ -41,7 +47,13 @@ func (v *Validate) Validate() (string, error) {
 			return "anyPattern", fmt.Errorf("failed to deserialize anyPattern, expect array: %v", err)
 		}
 		for i, pattern := range anyPattern {
-			if path, err := common.ValidatePattern(pattern, "/", []commonAnchors.IsAnchor{commonAnchors.IsConditionAnchor, commonAnchors.IsExistenceAnchor, commonAnchors.IsEqualityAnchor, commonAnchors.IsNegationAnchor, commonAnchors.IsGlobalAnchor}); err != nil {
+			if path, err := common.ValidatePattern(pattern, "/", func(a anchor.Anchor) bool {
+				return anchor.IsCondition(a) ||
+					anchor.IsExistence(a) ||
+					anchor.IsEquality(a) ||
+					anchor.IsNegation(a) ||
+					anchor.IsGlobal(a)
+			}); err != nil {
 				return fmt.Sprintf("anyPattern[%d].%s", i, path), err
 			}
 		}