Selecting Resources
The match
and exclude
filters control the scope to which rules are applied. They have the same structure and can each contain only one of the two elements:
any
: specify resource filters on which Kyverno will perform the logical OR operation while choosing resourcesall
: specify resource filters on which Kyverno will perform the logical AND operation while choosing resources
Resource Filters
The following resource filters can be specified under an any
or all
clause.
resources
: select resources by names, namespaces, kinds, operations, label selectors, annotations, and namespace selectors.subjects
: select users, user groups, and service accountsroles
: select namespaced rolesclusterRoles
: select cluster wide roles
Note
Specifying resource filters directly undermatch
and exclude
has been marked for deprecation and will be removed in a future release. Matches and exclusions should always use any
or all
blocks.At least one element must be specified in a match.(any/all).resources.kinds
or exclude
block. The kind
attribute is mandatory when working with the resources
element. Wildcards (*
) are supported in the resources.kinds
and subjects
fields.
In addition, a user may specify the group
and apiVersion
with a kind in the match
/ exclude
declarations for a policy rule, known as GVK format.
Supported formats:
Group/Version/Kind
Version/Kind
Kind
To resolve kind naming conflicts, specify the API group and version. For example, the Kubernetes API, Calico, and Antrea all register a Custom Resource with the name NetworkPolicy. These can be distinguished as:
networking.k8s.io/v1/NetworkPolicy
crd.antrea.io/v1alpha1/NetworkPolicy
Wildcards are supported with the following formats when used in the resources.kinds
field:
Group/*/Kind
Group/*/*
*/Kind
*
Note
- A policy using wildcards in
match
orexclude
or that validates subresources is not allowed in background mode. - A policy using wildcards does not support
generate
orverifyImages
rule types, and does not supportforEach
declarations. - For the
validate
rule type, a policy can only deal withdeny
statements and themetadata
object in eitherpattern
oranyPattern
blocks. - For the
mutate
rule type, a policy can only deal with themetadata
object.
Subresources may be specified with either a /
or .
as a separator between parent and subresource. For example, Pods/status
or Pods.status
will match on the /status
subresource for a Pod. They may be combined with previous naming as well, for example apps/v1/Deployment/scale
or v1/Pod.eviction
. Wildcards are also supported when referencing subresources, for example */Node/status
. Some subresources are shared by multiple API resources, for example the Scale
resource. Due to this, matching on Scale
may apply to resources like Deployment
as well as ReplicationController
since Scale
is common between both. Use of a parent resource followed by its subresource is necessary to be explicit in the matching decision. Specifying a subresource in the format PodExecOptions
is not supported.
When Kyverno receives an AdmissionReview request (i.e., from a validation or mutation webhook), it first checks to see if the resource and user information matches or should be excluded from processing. If both checks pass, then the rule logic to mutate, validate, or generate resources is applied.
Match statements
In every rule, there must be a single match
statement to function as the filter to which the rule will apply. Although the match
statement can be complex having many different elements, there must be at least one. The most common type of element in a match
statement is one which filters on categories of Kubernetes resources, for example Pods, Deployments, Services, Namespaces, etc. Variable substitution is not currently supported in match
or exclude
statements. match
statements also require an any
or all
expression allowing greater flexibility in treating multiple conditions.
In this snippet, the match
statement matches on all resources that EITHER have the kind Service with name “staging” OR have the kind Service and are being created in the “prod” Namespace.
1match:
2 any:
3 - resources:
4 kinds:
5 - Service
6 names:
7 - staging
8 operations:
9 - CREATE
10 - resources:
11 kinds:
12 - Service
13 namespaces:
14 - prod
15 operations:
16 - CREATE
The operations[]
list is optional but recommended. When operations[]
is absent, the default behavior is to match on CREATE
and UPDATE
requests.
By combining multiple elements in the match
statement, you can be more selective as to which resources you wish to process. Additionally, wildcards are supported for even greater control. For example, by adding the resources.names
field, the previous match
statement can further filter out Services that begin with the text “prod-” OR have the name “staging”. resources.names
takes in a list of names and would match all resources which have either of those names.
1match:
2 any:
3 - resources:
4 names:
5 - "prod-*"
6 - "staging"
7 kinds:
8 - Service
9 operations:
10 - CREATE
11 - resources:
12 kinds:
13 - Service
14 operations:
15 - CREATE
16 subjects:
17 - kind: User
18 name: dave
match.any[0]
will now match on only Services that begin with the name “prod-” OR have the name “staging” and not those which begin with “dev-” or any other prefix. match.any[1]
will match all Services being created by the dave
user regardless of the name of the Service. And since these two are specified under the any
key, the entire rule will act on all Services with names prod-*
or staging
OR on all services being created by the dave
user. In both match
and exclude
statements, wildcards are supported to make selection more flexible.
In this snippet, the match
statement matches only resources that have the group networking.k8s.io
, version v1
and kind NetworkPolicy
. By adding Group,Version,Kind in the match statement, you can be more selective as to which resources you wish to process.
1match:
2 any:
3 - resources:
4 kinds:
5 - networking.k8s.io/v1/NetworkPolicy
By specifying the kind
in version/kind
format, only specific versions of the resource kind will be matched.
1match:
2 any:
3 - resources:
4 kinds:
5 - v1/NetworkPolicy
Wildcards are supported in the kinds
field allowing you to match on every resource type in the cluster. Selector labels support wildcards (* or ?)
for keys as well as values in the following paths.
match.any.resources.selector.matchLabels
match.all.resources.selector.matchLabels
exclude.any.resources.selector.matchLabels
exclude.all.resources.selector.matchLabels
Supported formats:
*
*pattern*
*pattern
pattern?
patte?rn
In the below policy, all resource kinds are checked for the existence of a label having key app.kubernetes.io/name
.
1apiVersion: kyverno.io/v1
2kind: ClusterPolicy
3metadata:
4 name: require-labels
5spec:
6 background: false
7 rules:
8 - name: check-for-labels
9 match:
10 any:
11 - resources:
12 kinds:
13 - "*"
14 operations:
15 - CREATE
16 validate:
17 failureAction: Audit
18 message: "The label `app.kubernetes.io/name` is required."
19 pattern:
20 metadata:
21 labels:
22 app.kubernetes.io/name: "?*"
Warning
Keep in mind that when matching on all kinds (*
) the policy you write must be applicable across all of them. Typical uses for this type of wildcard matching are elements within the metadata
object. This type of matching should be used sparingly and carefully as it will instruct the API server to send every eligible resource type to Kyverno, greatly increasing the amount of processing performed by Kyverno.Matches for Namespaced resources can also be selected using Namespace labels by using the namespaceSelector
field. This field allows selection in two granular ways: by using matchLabels
or matchExpressions
. When using matchLabels
, a map of Namespace labels can be used to specify the match. For more advanced selection logic, use the matchExpressions
element.
In the below example, Kyverno will only consider matching Pods as those in a Namespace which contains the label organization: engineering
.
1match:
2 any:
3 - resources:
4 kinds:
5 - Pod
6 namespaceSelector:
7 matchLabels:
8 organization: engineering
And in this example, Kyverno will select Pods in a Namespace where the label key namespacekind
does not equal the value platform
or ci
.
1match:
2 any:
3 - resources:
4 kinds:
5 - Pod
6 namespaceSelector:
7 matchExpressions:
8 - key: namespacekind
9 operator: NotIn
10 values:
11 - platform
12 - ci
Here are some other examples of match
statements.
Match a Deployment or StatefulSet with a specific label
This is an example that selects a Deployment OR a StatefulSet with a label app=critical
.
Condition checks inside the resources
block follow the logic “AND across types but an OR within list types”. For example, if a rule match contains a list of kinds and a list of namespaces, the rule will be evaluated if the request contains any one (OR) of the kinds AND any one (OR) of the namespaces. Conditions inside clusterRoles
, roles
, and subjects
are always evaluated using a logical OR operation, as each request can only have a single instance of these values.
In the below snippet, kinds
and selector
are peer/sibling elements, and so they are ANDed together.
1match:
2 any:
3 # AND across kinds and namespaceSelector
4 - resources:
5 # OR inside list of kinds
6 kinds:
7 - Deployment
8 - StatefulSet
9 operations:
10 - CREATE
11 - UPDATE
12 selector:
13 matchLabels:
14 app: critical
This pattern can be leveraged to produce very fine-grained control over the selection of resources, for example the snippet as shown below which combines match
elements that include resources
, subjects
, roles
, and clusterRoles
.
Advanced match statement
1spec:
2 # Each policy has a list of rules applied in declaration order
3 rules:
4 # Rules must have a unique name
5 - name: check-pod-controller-labels
6 # Each rule matches specific resource described by "match" field.
7 match:
8 any:
9 - resources:
10 kinds: # Required, list of kinds
11 - Deployment
12 - StatefulSet
13 # Optional resource names. Supports wildcards (* and ?)
14 names:
15 - "mongo*"
16 - "postgres*"
17 # Optional list of namespaces. Supports wildcards (* and ?)
18 operations:
19 - CREATE
20 - UPDATE
21 namespaces:
22 - "dev*"
23 - test
24 # Optional label selectors. Values support wildcards (* and ?)
25 selector:
26 matchLabels:
27 app: mongodb
28 matchExpressions:
29 - {key: tier, operator: In, values: [database]}
30 # Optional users or service accounts to be matched
31 subjects:
32 - kind: User
33 name: mary@somecorp.com
34 # Optional clusterroles to be matched
35 clusterRoles:
36 - cluster-admin
Note
Although the above snippet is useful for showing the types of matching that you can use, most policies either use one or just a couple different elements within theirmatch
statements.Match Deployments in Namespaces using labels
This example selects Deployments in Namespaces that have a label type=connector
or type=compute
using a namespaceSelector
.
Here, kinds
and namespaceSelector
are peer elements under match.resources
and are evaluated using a logical AND operation.
1spec:
2 rules:
3 - name: check-min-replicas
4 match:
5 any:
6 # AND across resources and selector
7 - resources:
8 # OR inside list of kinds
9 kinds:
10 - Deployment
11 operations:
12 - CREATE
13 - UPDATE
14 namespaceSelector:
15 matchExpressions:
16 - key: type
17 operator: In
18 values:
19 - connector
20 - compute
Combining match and exclude
In cases where a subset of the resources selected in a match
block need to be omitted from processing, you may optionally use an exclude
block. For example, you wish to only process Pods which do not have the label env=prod
. An exclude
block can be used to select those with the label env=prod
. An exclude
block must therefore be a subset of the match
block.
All match
and exclude
conditions must be satisfied for a resource to be selected for the policy rule. In other words, the match
and exclude
conditions are evaluated using a logical AND operation. Elements in the exclude
block follow the same specifications as those in the match
block.
Exclude cluster-admin
ClusterRole
Here is an example of a rule that matches all Pods excluding those created by using the cluster-admin
ClusterRole.
1spec:
2 rules:
3 - name: match-pods-except-cluster-admin
4 match:
5 any:
6 - resources:
7 kinds:
8 - Pod
9 operations:
10 - CREATE
11 - UPDATE
12 exclude:
13 any:
14 - clusterRoles:
15 - cluster-admin
Exclude prod-alpha
Namespace
This rule matches all Pods except those in the prod-alpha
Namespace.
1spec:
2 rules:
3 - name: match-pods-except-admin
4 match:
5 any:
6 - resources:
7 kinds:
8 - Pod
9 operations:
10 - CREATE
11 - UPDATE
12 exclude:
13 any:
14 - resources:
15 namespaces:
16 - prod-alpha
Match a label and exclude users and roles
The following example matches all resources with label app=critical
excluding the resources created by ClusterRole cluster-admin
OR by the user John
.
Note
Sinceroles
and clusterRoles
are built internally by Kyverno from AdmissionReview contents, rules which contain either of these must define background: false
since the AdmissionReview payload is not available in background mode. subjects
are also not allowed in background mode as this information is not available once a resource has been created. 1spec:
2 rules:
3 - name: match-criticals-except-given-rbac
4 match:
5 any:
6 - resources:
7 kind:
8 - Pod
9 operations:
10 - CREATE
11 - UPDATE
12 selector:
13 matchLabels:
14 app: critical
15 exclude:
16 any:
17 - clusterRoles:
18 - cluster-admin
19 - subjects:
20 - kind: User
21 name: John
Match a label and exclude users
A variation on the above sample, this snippet uses any
and all
statements to exclude multiple users.
1spec:
2 background: false
3 rules:
4 - name: match-criticals-except-given-users
5 match:
6 all:
7 - resources:
8 kinds:
9 - Pod
10 operations:
11 - CREATE
12 - UPDATE
13 selector:
14 matchLabels:
15 app: critical
16 exclude:
17 any:
18 - subjects:
19 - kind: User
20 name: susan
21 - kind: User
22 name: dave
Match all Pods using annotations
Here is an example of a rule that matches all Pods having imageregistry: "https://hub.docker.com/"
annotations.
1spec:
2 rules:
3 - name: match-pod-annotations
4 match:
5 any:
6 - resources:
7 annotations:
8 imageregistry: "https://hub.docker.com/"
9 kinds:
10 - Pod
11 operations:
12 - CREATE
13 - UPDATE
Configure webhooks
Webhook configurations can be configured using policies. Webhook operations per resource is dynamically set if there are match/exclude operations mentioned in the policies applied. If for a resource no operations are set in match or exclude blocks, default operations are applied in the webhooks rules. Default operations for validating resources are CONNECT, CREATE, UPDATE, DELETE and for mutating resources are CREATE, UPDATE.
For a policy like this:
1apiVersion: kyverno.io/v1
2kind: ClusterPolicy
3metadata:
4 name: require-labels
5 annotations:
6 pod-policies.kyverno.io/autogen-controllers: none
7spec:
8 background: false
9 rules:
10 - name: require-team
11 match:
12 any:
13 - resources:
14 kinds:
15 - Namespace
16 operations:
17 - CREATE
18 validate:
19 failureAction: Audit
20 message: 'The label `team` is required.'
21 pattern:
22 metadata:
23 labels:
24 team: '?*'
25 - name: require-match
26 match:
27 any:
28 - resources:
29 kinds:
30 - Deployment
31 operations:
32 - UPDATE
33 validate:
34 failureAction: Audit
35 message: 'The label `match` is required.'
36 pattern:
37 metadata:
38 labels:
39 match: '?*'
The webhook rules would look like this:
1 rules:
2 - apiGroups:
3 - ""
4 apiVersions:
5 - v1
6 operations:
7 - CREATE
8 resources:
9 - namespaces
10 scope: '*'
11 - apiGroups:
12 - apps
13 apiVersions:
14 - v1
15 operations:
16 - UPDATE
17 resources:
18 - deployments
19 scope: '*'
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.