Kyverno
Policy Structure
apiVersion: kyverno.io/v1
kind: ClusterPolicy # or Policy (namespaced)
metadata:
name: policy-name
spec:
validationFailureAction: Enforce # Enforce (block) or Audit (warn)
background: true # Scan existing resources
rules:
- name: rule-name
match:
any: # OR logic
- resources:
kinds: [Pod]
namespaces: [prod-*] # Glob patterns supported
exclude: # Optional exclusions
any:
- resources:
namespaces: [kube-system]
validate: {} # or mutate: {} or generate: {}
Validation Patterns
Pattern Matching
validate:
pattern:
metadata:
labels:
app: "?*" # Non-empty string
spec:
containers:
- image: "!*:latest" # Negation
resources:
limits:
memory: "?*" # Required field
Deny with Conditions
validate:
message: "Privileged containers not allowed"
deny:
conditions:
any:
- key: "{{ request.object.spec.containers[].securityContext.privileged || `false` }}"
operator: AnyIn
value: [true]
Operators
Equals,NotEquals,In,AnyIn,AllIn,NotIn,AnyNotIn,AllNotInGreaterThan,LessThan,GreaterThanOrEquals,LessThanOrEquals
Mutation Patterns
Strategic Merge
mutate:
patchStrategicMerge:
metadata:
labels:
+(app): default # + adds only if missing
spec:
containers:
- (name): "*" # Match anchor
imagePullPolicy: Always
JSON Patch
mutate:
patchesJson6902: |
- op: add
path: /metadata/labels/env
value: production
Generation Patterns
generate:
apiVersion: v1
kind: ConfigMap
name: "{{request.object.metadata.name}}-config"
namespace: "{{request.object.metadata.namespace}}"
synchronize: true # Keep in sync with source
data:
kind: ConfigMap
metadata:
labels:
generated: "true"
data:
key: value
synchronize: true means changes to generated resource revert; false means generate once.
Context (External Data)
context:
- name: images
configMap:
name: allowed-images
namespace: kyverno
- name: ns
apiCall:
urlPath: "/api/v1/namespaces/{{request.namespace}}"
jmesPath: "metadata.labels"
Use in expressions: {{ images.data.registries }}, {{ ns.team }}
Common Gotchas
background: trueonly works for validation, not mutation/generationmatch.anyis OR,match.allis ANDexcludetakes precedence overmatch- JMESPath uses backticks for literals:
`true`,`"string"` ||provides defaults:{{ value ||"default"}}- PolicyException (v2beta1) exempts specific resources from policies