1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

chore: apply policy fixes (#8427)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-09-18 00:24:26 +02:00 committed by GitHub
parent 3a61f2c6b7
commit 7562bea6db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 996 additions and 814 deletions

View file

@ -1,25 +1,35 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-image
annotations:
pod-policies.kyverno.io/autogen-controllers: none
name: check-image
spec:
admission: true
background: true
rules:
- name: verify-signature
match:
resources:
- match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "*"
attestors:
- count: 1
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFN8gGjQua2g8N+aLx3Eff+/j5HxL
bV+H2z50/0A4d8XyMUvizPQBtcgei43pqLj1850m3wSwI08z2+6zT1QaEg==
-----END PUBLIC KEY-----
- Pod
name: verify-signature
verifyImages:
- attestors:
- count: 1
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFN8gGjQua2g8N+aLx3Eff+/j5HxL
bV+H2z50/0A4d8XyMUvizPQBtcgei43pqLj1850m3wSwI08z2+6zT1QaEg==
-----END PUBLIC KEY-----
signatureAlgorithm: sha256
imageReferences:
- '*'
mutateDigest: true
required: true
useCache: true
verifyDigest: true
validationFailureAction: Audit

View file

@ -1,21 +1,22 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: limit-configmap-for-sa
annotations:
policies.kyverno.io/title: Limit ConfigMap to ServiceAccounts for a User
policies.kyverno.io/category: Other
policies.kyverno.io/severity: medium
kyverno.io/kubernetes-version: 1.20-1.23
kyverno.io/kyverno-version: 1.6.0
kyverno.io/kubernetes-version: "1.20-1.23"
policies.kyverno.io/category: Other
policies.kyverno.io/description: This policy shows how to restrict certain operations
on specific ConfigMaps by ServiceAccounts.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: ConfigMap, ServiceAccount
policies.kyverno.io/description: This policy shows how to restrict certain operations on specific ConfigMaps by ServiceAccounts.
policies.kyverno.io/title: Limit ConfigMap to ServiceAccounts for a User
name: limit-configmap-for-sa
spec:
admission: true
background: false
validationFailureAction: audit
rules:
- name: limit-configmap-for-sa-developer
match:
- match:
any:
- resources:
kinds:
@ -31,25 +32,28 @@ spec:
- kind: ServiceAccount
name: another-developer
namespace: another-namespace
name: limit-configmap-for-sa-developer
preconditions:
all:
- key: "{{request.object.metadata.namespace}}"
operator: In
- key: '{{request.object.metadata.namespace}}'
operator: AllIn
value:
- "any-namespace"
- "another-namespace"
- key: "{{request.object.metadata.name}}"
operator: In
- any-namespace
- another-namespace
- key: '{{request.object.metadata.name}}'
operator: AllIn
value:
- "any-configmap-name-good"
- "another-configmap-name"
- any-configmap-name-good
- another-configmap-name
validate:
message: "{{request.object.metadata.namespace}}/{{request.object.kind}}/{{request.object.metadata.name}} resource is protected. Admin or allowed users can change the resource"
deny:
conditions:
all:
- key: "{{request.operation}}"
operator: "In"
- key: '{{request.operation}}'
operator: In
value:
- "UPDATE"
- "CREATE"
- UPDATE
- CREATE
message: '{{request.object.metadata.namespace}}/{{request.object.kind}}/{{request.object.metadata.name}}
resource is protected. Admin or allowed users can change the resource'
validationFailureAction: Audit

View file

@ -1,40 +1,44 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: pod-requirements
annotations:
pod-policies.kyverno.io/autogen-controllers: none
policies.kyverno.io/severity: medium
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/severity: medium
name: pod-requirements
spec:
admission: true
background: false
validationFailureAction: audit
rules:
- name: pods-require-account
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: pods-require-account
validate:
message: User pods must include an account for charging
pattern:
metadata:
labels:
account: "*?"
- name: pods-require-limits
match:
resources:
kinds:
- Pod
account: '*?'
- match:
any:
- resources:
kinds:
- Pod
name: pods-require-limits
validate:
message: CPU and memory resource requests and limits are required for user pods
pattern:
spec:
containers:
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
cpu: "?*"
cpu: ?*
memory: ?*
requests:
cpu: ?*
memory: ?*
validationFailureAction: Audit

View file

@ -1,41 +1,45 @@
---
apiVersion: kyverno.io/v1
kind: Policy
metadata:
name: pod-requirements
namespace: test
annotations:
pod-policies.kyverno.io/autogen-controllers: none
policies.kyverno.io/severity: medium
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/severity: medium
name: pod-requirements
namespace: test
spec:
admission: true
background: false
validationFailureAction: audit
rules:
- name: pods-require-account
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: pods-require-account
validate:
message: User pods must include an account for charging
pattern:
metadata:
labels:
account: "*?"
- name: pods-require-limits
match:
resources:
kinds:
- Pod
account: '*?'
- match:
any:
- resources:
kinds:
- Pod
name: pods-require-limits
validate:
message: CPU and memory resource requests and limits are required for user pods
pattern:
spec:
containers:
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
cpu: "?*"
cpu: ?*
memory: ?*
requests:
cpu: ?*
memory: ?*
validationFailureAction: Audit

View file

@ -1,39 +1,44 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-networkpolicy
annotations:
policies.kyverno.io/category: Workload Management
policies.kyverno.io/description: By default, Kubernetes allows communications across
all pods within a cluster. Network policies and, a CNI that supports network policies,
must be used to restrict communinications. A default NetworkPolicy should be configured
for each namespace to default deny all ingress traffic to the pods in the namespace.
Application teams can then configure additional NetworkPolicy resources to allow
desired traffic to application pods from select sources.
policies.kyverno.io/description: By default, Kubernetes allows communications
across all pods within a cluster. Network policies and, a CNI that supports
network policies, must be used to restrict communinications. A default NetworkPolicy
should be configured for each namespace to default deny all ingress traffic
to the pods in the namespace. Application teams can then configure additional
NetworkPolicy resources to allow desired traffic to application pods from select
sources.
name: add-networkpolicy
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: default-deny-ingress
match:
resources:
kinds:
- Namespace
name: "*"
exclude:
resources:
namespaces:
- "kube-system"
- "default"
- "kube-public"
- "kyverno"
- exclude:
any:
- resources:
namespaces:
- kube-system
- default
- kube-public
- kyverno
generate:
kind: NetworkPolicy
name: default-deny-ingress
namespace: "{{request.object.metadata.name}}"
synchronize : true
data:
spec:
# select all pods in the namespace
podSelector: {}
policyTypes:
- Ingress
kind: NetworkPolicy
name: default-deny-ingress
namespace: '{{request.object.metadata.name}}'
synchronize: true
match:
any:
- resources:
kinds:
- Namespace
name: '*'
name: default-deny-ingress
validationFailureAction: Audit

View file

@ -1,50 +1,46 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-ns-quota
annotations:
policies.kyverno.io/category: Workload Isolation
policies.kyverno.io/description: To limit the number of objects, as well as the
total amount of compute that may be consumed by a single namespace, create
a default resource quota for each namespace.
total amount of compute that may be consumed by a single namespace, create a
default resource quota for each namespace.
name: add-ns-quota
spec:
admission: true
background: true
rules:
- name: generate-resourcequota
match:
resources:
kinds:
- Namespace
exclude:
resources:
namespaces:
- "kube-system"
- "default"
- "kube-public"
- "kyverno"
- exclude:
any:
- resources:
namespaces:
- kube-system
- default
- kube-public
- kyverno
generate:
apiVersion: v1
kind: ResourceQuota
name: default-resourcequota
synchronize : true
namespace: "{{request.object.metadata.name}}"
data:
spec:
hard:
requests.cpu: '4'
requests.memory: '16Gi'
limits.cpu: '4'
limits.memory: '16Gi'
- name: generate-limitrange
limits.cpu: "4"
limits.memory: 16Gi
requests.cpu: "4"
requests.memory: 16Gi
kind: ResourceQuota
name: default-resourcequota
namespace: '{{request.object.metadata.name}}'
synchronize: true
match:
resources:
kinds:
- Namespace
generate:
any:
- resources:
kinds:
- Namespace
name: generate-resourcequota
- generate:
apiVersion: v1
kind: LimitRange
name: default-limitrange
synchronize : true
namespace: "{{request.object.metadata.name}}"
data:
spec:
limits:
@ -55,3 +51,14 @@ spec:
cpu: 200m
memory: 256Mi
type: Container
kind: LimitRange
name: default-limitrange
namespace: '{{request.object.metadata.name}}'
synchronize: true
match:
any:
- resources:
kinds:
- Namespace
name: generate-limitrange
validationFailureAction: Audit

View file

@ -1,19 +1,23 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-safe-to-evict
annotations:
policies.kyverno.io/category: Workload Management
policies.kyverno.io/description: The Kubernetes cluster autoscaler does not evict pods that
use hostPath or emptyDir volumes. To allow eviction of these pods, the annotation
cluster-autoscaler.kubernetes.io/safe-to-evict=true must be added to the pods.
policies.kyverno.io/description: The Kubernetes cluster autoscaler does not evict
pods that use hostPath or emptyDir volumes. To allow eviction of these pods,
the annotation cluster-autoscaler.kubernetes.io/safe-to-evict=true must be added
to the pods.
name: add-safe-to-evict
spec:
admission: true
background: true
rules:
- name: annotate-empty-dir
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
metadata:
@ -22,11 +26,12 @@ spec:
spec:
volumes:
- <(emptyDir): {}
- name: annotate-host-path
match:
resources:
kinds:
- Pod
name: annotate-empty-dir
- match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
metadata:
@ -35,4 +40,6 @@ spec:
spec:
volumes:
- hostPath:
<(path): "*"
<(path): '*'
name: annotate-host-path
validationFailureAction: Audit

View file

@ -1,26 +1,31 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-bind-mounts
annotations:
policies.kyverno.io/category: Workload Isolation
policies.kyverno.io/description: The volume of type `hostPath` allows pods to use host bind
mounts (i.e. directories and volumes mounted to a host path) in containers. Using host
resources can be used to access shared data or escalate privileges. Also, this couples pods
to a specific host and data persisted in the `hostPath` volume is coupled to the life of the
node leading to potential pod scheduling failures. It is highly recommended that applications
are designed to be decoupled from the underlying infrastructure (in this case, nodes).
policies.kyverno.io/description: The volume of type `hostPath` allows pods to
use host bind mounts (i.e. directories and volumes mounted to a host path) in
containers. Using host resources can be used to access shared data or escalate
privileges. Also, this couples pods to a specific host and data persisted in
the `hostPath` volume is coupled to the life of the node leading to potential
pod scheduling failures. It is highly recommended that applications are designed
to be decoupled from the underlying infrastructure (in this case, nodes).
name: disallow-bind-mounts
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: validate-hostPath
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-hostPath
validate:
message: "Host path volumes are not allowed"
message: Host path volumes are not allowed
pattern:
spec:
=(volumes):
- X(hostPath): "null"
validationFailureAction: Audit

View file

@ -1,34 +1,40 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-host-network-port
annotations:
policies.kyverno.io/category: Workload Isolation
policies.kyverno.io/description: Using 'hostPort' and 'hostNetwork' allows pods to share
the host network stack, allowing potential snooping of network traffic from an application pod.
policies.kyverno.io/description: Using 'hostPort' and 'hostNetwork' allows pods
to share the host network stack, allowing potential snooping of network traffic
from an application pod.
name: disallow-host-network-port
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: validate-host-network
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-host-network
validate:
message: "Use of hostNetwork is not allowed"
message: Use of hostNetwork is not allowed
pattern:
spec:
=(hostNetwork): false
- name: validate-host-port
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-host-port
validate:
message: "Use of hostPort is not allowed"
message: Use of hostPort is not allowed
pattern:
spec:
containers:
- name: "*"
=(ports):
- X(hostPort): "null"
- =(ports):
- X(hostPort): "null"
name: '*'
validationFailureAction: Audit

View file

@ -1,24 +1,29 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-host-pid-ipc
annotations:
policies.kyverno.io/category: Workload Isolation
policies.kyverno.io/description: Sharing the host's PID namespace allows visibility of process
on the host, potentially exposing process information. Sharing the host's IPC namespace allows
the container process to communicate with processes on the host. To avoid pod container from
having visibility to host process space, validate that 'hostPID' and 'hostIPC' are set to 'false'.
policies.kyverno.io/description: Sharing the host's PID namespace allows visibility
of process on the host, potentially exposing process information. Sharing the
host's IPC namespace allows the container process to communicate with processes
on the host. To avoid pod container from having visibility to host process space,
validate that 'hostPID' and 'hostIPC' are set to 'false'.
name: disallow-host-pid-ipc
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: validate-hostPID-hostIPC
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-hostPID-hostIPC
validate:
message: "Use of host PID and IPC namespaces is not allowed"
message: Use of host PID and IPC namespaces is not allowed
pattern:
spec:
=(hostPID): "false"
=(hostIPC): "false"
=(hostPID): "false"
validationFailureAction: Audit

View file

@ -1,35 +1,40 @@
apiVersion : kyverno.io/v1
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
annotations:
pod-policies.kyverno.io/autogen-controllers: none
policies.kyverno.io/category: Workload Isolation
policies.kyverno.io/description: The ':latest' tag is mutable and can lead to
unexpected errors if the image changes. A best practice is to use an immutable
tag that maps to a specific version of an application pod.
pod-policies.kyverno.io/autogen-controllers: none
name: disallow-latest-tag
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: require-image-tag
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: require-image-tag
validate:
message: "An image tag is required"
message: An image tag is required
pattern:
spec:
containers:
- image: "*:*"
- name: validate-image-tag
match:
resources:
kinds:
- Pod
- image: '*:*'
- match:
any:
- resources:
kinds:
- Pod
name: validate-image-tag
validate:
message: "Using a mutable image tag e.g. 'latest' is not allowed"
message: Using a mutable image tag e.g. 'latest' is not allowed
pattern:
spec:
containers:
- image: "!*:latest"
- image: '!*:latest'
validationFailureAction: Audit

View file

@ -1,39 +1,42 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged
annotations:
policies.kyverno.io/category: Security
policies.kyverno.io/description: Privileged containers are defined as any
container where the container uid 0 is mapped to the hosts uid 0.
A process within a privileged container can get unrestricted host access.
With `securityContext.allowPrivilegeEscalation` enabled, a process can
gain privileges from its parent.
policies.kyverno.io/description: Privileged containers are defined as any container
where the container uid 0 is mapped to the hosts uid 0. A process within a
privileged container can get unrestricted host access. With `securityContext.allowPrivilegeEscalation`
enabled, a process can gain privileges from its parent.
name: disallow-privileged
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: validate-privileged
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-privileged
validate:
message: "Privileged mode is not allowed. Set privileged to false"
message: Privileged mode is not allowed. Set privileged to false
pattern:
spec:
containers:
- =(securityContext):
=(privileged): false
- name: validate-allowPrivilegeEscalation
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-allowPrivilegeEscalation
validate:
message: "Privileged mode is not allowed. Set allowPrivilegeEscalation to false"
message: Privileged mode is not allowed. Set allowPrivilegeEscalation to false
pattern:
spec:
containers:
- securityContext:
allowPrivilegeEscalation: false
validationFailureAction: Audit

View file

@ -1,23 +1,28 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-sysctls
annotations:
policies.kyverno.io/category: Security
policies.kyverno.io/description: The Sysctl interface allows modifications to kernel parameters
at runtime. In a Kubernetes pod these parameters can be specified under `securityContext.sysctls`.
Kernel parameter modifications can be used for exploits and should be restricted.
policies.kyverno.io/description: The Sysctl interface allows modifications to
kernel parameters at runtime. In a Kubernetes pod these parameters can be specified
under `securityContext.sysctls`. Kernel parameter modifications can be used
for exploits and should be restricted.
name: disallow-sysctls
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: validate-sysctls
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-sysctls
validate:
message: "Changes to kernel parameters are not allowed"
message: Changes to kernel parameters are not allowed
pattern:
spec:
=(securityContext):
X(sysctls): null
validationFailureAction: Audit

View file

@ -1,21 +1,26 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-certain-labels
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: validate-certain-labels
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-certain-labels
validate:
message: "The label `app.kubernetes.io/name` or `app.kubernetes.io/component` is required."
anyPattern:
- metadata:
labels:
app.kubernetes.io/name: "?*"
app.kubernetes.io/name: ?*
- metadata:
labels:
app.kubernetes.io/component: "?*"
app.kubernetes.io/component: ?*
message: The label `app.kubernetes.io/name` or `app.kubernetes.io/component`
is required.
validationFailureAction: Audit

View file

@ -1,20 +1,22 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: check-for-labels
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: check-for-labels
validate:
message: "The label `app.kubernetes.io/name` is required."
message: The label `app.kubernetes.io/name` is required.
pattern:
metadata:
labels:
app.kubernetes.io/name: "?*"
# You can add more labels if you wish the policy to validate more than just one is present. Uncomment the below line, or add new ones.
#app.kubernetes.io/component: "?*
app.kubernetes.io/name: ?*
validationFailureAction: Audit

View file

@ -1,29 +1,34 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-pod-requests-limits
annotations:
policies.kyverno.io/category: Workload Management
policies.kyverno.io/description: As application workloads share cluster resources, it is important
to limit resources requested and consumed by each pod. It is recommended to require
'resources.requests' and 'resources.limits.memory' per pod. If a namespace level request or limit is
specified, defaults will automatically be applied to each pod based on the 'LimitRange' configuration.
policies.kyverno.io/description: As application workloads share cluster resources,
it is important to limit resources requested and consumed by each pod. It is
recommended to require 'resources.requests' and 'resources.limits.memory' per
pod. If a namespace level request or limit is specified, defaults will automatically
be applied to each pod based on the 'LimitRange' configuration.
name: require-pod-requests-limits
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: validate-resources
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-resources
validate:
message: "CPU and memory resource requests and limits are required"
message: CPU and memory resource requests and limits are required
pattern:
spec:
containers:
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
memory: ?*
requests:
cpu: ?*
memory: ?*
validationFailureAction: Audit

View file

@ -1,28 +1,34 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: select-secrets
spec:
admission: true
background: false
validationFailureAction: enforce
rules:
- name: select-secrets-from-volumes
- context:
- apiCall:
jmesPath: metadata.labels.foo
method: GET
urlPath: /api/v1/namespaces/{{request.object.metadata.namespace}}/secrets/{{request.object.spec.volumes[0].secret.secretName}}
name: volsecret
match:
resources:
kinds:
- Pod
context:
- name: volsecret
apiCall:
urlPath: "/api/v1/namespaces/{{request.object.metadata.namespace}}/secrets/{{request.object.spec.volumes[0].secret.secretName}}"
jmesPath: "metadata.labels.foo"
any:
- resources:
kinds:
- Pod
name: select-secrets-from-volumes
preconditions:
- key: "{{ request.operation }}"
operator: Equals
value: "CREATE"
all:
- key: '{{ request.operation }}'
operator: Equals
value: CREATE
validate:
message: "The Secret named {{request.object.spec.volumes[0].secret.secretName}} is restricted and may not be used."
message: The Secret named {{request.object.spec.volumes[0].secret.secretName}}
is restricted and may not be used.
pattern:
spec:
containers:
- image: "registry.domain.com/*"
- image: registry.domain.com/*
validationFailureAction: Enforce

View file

@ -1,56 +1,60 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
annotations:
policies.kyverno.io/category: Best Practices
policies.kyverno.io/description: >-
The ':latest' tag is mutable and can lead to unexpected errors if the
image changes. A best practice is to use an immutable tag that maps to
a specific version of an application pod.
spec:
validationFailureAction: audit
rules:
- name: validate-image-tag
match:
resources:
kinds:
- Pod
validate:
message: "Using a mutable image tag e.g. 'latest' is not allowed."
pattern:
spec:
containers:
- image: "!*:latest"
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: drop-all-capabilities
annotations:
policies.kyverno.io/category: Best Practices
policies.kyverno.io/description: The ':latest' tag is mutable and can lead to
unexpected errors if the image changes. A best practice is to use an immutable
tag that maps to a specific version of an application pod.
name: disallow-latest-tag
spec:
admission: true
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: validate-image-tag
validate:
message: Using a mutable image tag e.g. 'latest' is not allowed.
pattern:
spec:
containers:
- image: '!*:latest'
validationFailureAction: Audit
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
annotations:
policies.kyverno.io/scored: "false"
name: drop-all-capabilities
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: require-drop-all
match:
any:
- resources:
kinds:
- Pod
preconditions:
all:
- key: "{{ request.operation }}"
operator: NotEquals
value: DELETE
validate:
message: >-
Containers must drop `ALL` capabilities.
foreach:
- list: request.object.spec.[ephemeralContainers, initContainers, containers][]
deny:
conditions:
all:
- key: ALL
operator: AnyNotIn
value: "{{ element.securityContext.capabilities.drop || '' }}"
- match:
any:
- resources:
kinds:
- Pod
name: require-drop-all
preconditions:
all:
- key: '{{ request.operation }}'
operator: NotEquals
value: DELETE
validate:
foreach:
- deny:
conditions:
all:
- key: ALL
operator: AnyNotIn
value: '{{ element.securityContext.capabilities.drop || '''' }}'
list: request.object.spec.[ephemeralContainers, initContainers, containers][]
message: Containers must drop `ALL` capabilities.
validationFailureAction: Audit

View file

@ -1,21 +1,23 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: validate-default-proc-mount
spec:
validationFailureAction: "audit"
admission: true
background: true
rules:
- name: validate-default-proc-mount
match:
- match:
all:
- resources:
kinds:
- Pod
- resources:
kinds:
- Pod
name: validate-default-proc-mount
validate:
message: "Default proc mount should set to Unmasked"
message: Default proc mount should set to Unmasked
pattern:
spec:
containers:
- securityContext:
procMount: Unmasked
# used by rootless containers
validationFailureAction: Audit

View file

@ -1,24 +1,24 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: validate-selinux-options
spec:
validationFailureAction: "audit"
admission: true
background: true
rules:
- name: validate-selinux-options
match:
any:
- resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-selinux-options
validate:
message: "SELinux level is required"
message: SELinux level is required
pattern:
spec:
containers:
- securityContext:
seLinuxOptions:
level: "?*"
# level: "s0:c25,c968"
# If SELinux security module is loaded on the host operating system,
# we can make sure pods only have access to specified configured level
level: ?*
validationFailureAction: Audit

View file

@ -1,25 +1,28 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: validate-volumes-whitelist
spec:
validationFailureAction: "audit"
admission: true
background: true
rules:
- name: validate-volumes-whitelist
match:
- match:
any:
- resources:
kinds:
- Pod
- resources:
kinds:
- Pod
name: validate-volumes-whitelist
validate:
message: "Volume type is not of type hostPath, emptyDir, or configMap."
anyPattern:
- spec:
volumes:
- hostPath: "*"
- hostPath: '*'
- spec:
volumes:
- emptyDir: "*"
- emptyDir: '*'
- spec:
volumes:
- configMap: "*"
- configMap: '*'
message: Volume type is not of type hostPath, emptyDir, or configMap.
validationFailureAction: Audit

View file

@ -1,29 +1,26 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: bug-demo
annotations:
pod-policies.kyverno.io/autogen-controllers: "none"
pod-policies.kyverno.io/autogen-controllers: none
name: bug-demo
spec:
admission: true
background: false
validationFailureAction: enforce
rules:
- name: mutate1
match:
- match:
all:
- resources:
kinds:
- v1/Pod
mutate:
foreach:
- list: |-
request.object.spec.containers || `[]`
context:
- context:
- name: container_path
variable:
value: "/spec/containers/{{ elementIndex }}"
value: /spec/containers/{{ elementIndex }}
list: request.object.spec.containers || `[]`
patchesJson6902: |-
{{
[
@ -82,3 +79,5 @@ spec:
|
to_string(@)
}}
name: mutate1
validationFailureAction: Enforce

View file

@ -1,50 +1,52 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disable-connection-draining
annotations:
policies.kyverno.io/title: Configure Connection Draining
policies.kyverno.io/category: Best Practices
policies.kyverno.io/subject: Service
policies.kyverno.io/title: Configure Connection Draining
name: disable-connection-draining
spec:
admission: true
background: true
rules:
- name: clb
match:
resources:
kinds:
- Service
context:
- context:
- name: connection_draining_check
variable:
default: "empty"
default: empty
jmesPath: request.object.metadata.annotations."service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled"
- name: nlb_check
variable:
default: "false"
jmesPath: request.object.metadata.annotations."service.beta.kubernetes.io/aws-load-balancer-type"
preconditions:
all:
- key: "{{ request.object.spec.type }}"
operator: Equals
value: "LoadBalancer"
- key: "{{ connection_draining_check }}"
operator: AnyIn
value: ["true", "empty"]
- key: "{{ nlb_check }}"
operator: AnyNotIn
value: ["external", "nlb"]
match:
any:
- resources:
kinds:
- Service
mutate:
patchStrategicMerge:
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled: "false"
- name: nlb-no-attributes
match:
resources:
kinds:
- Service
context:
name: clb
preconditions:
all:
- key: '{{ request.object.spec.type }}'
operator: Equals
value: LoadBalancer
- key: '{{ connection_draining_check }}'
operator: AnyIn
value:
- "true"
- empty
- key: '{{ nlb_check }}'
operator: AnyNotIn
value:
- external
- nlb
- context:
- name: nlb_check
variable:
default: "false"
@ -53,19 +55,26 @@ spec:
variable:
default: "false"
jmesPath: request.object.metadata.annotations."service.beta.kubernetes.io/aws-load-balancer-target-group-attributes"
preconditions:
all:
- key: "{{ request.object.spec.type }}"
operator: Equals
value: "LoadBalancer"
- key: "{{ nlb_check }}"
operator: Equals
value: "external"
- key: "{{ tg_attributes }}"
operator: Equals
value: "false"
match:
any:
- resources:
kinds:
- Service
mutate:
patchStrategicMerge:
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: "deregistration_delay.connection_termination.enabled=true,deregistration_delay.timeout_seconds=0"
service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: deregistration_delay.connection_termination.enabled=true,deregistration_delay.timeout_seconds=0
name: nlb-no-attributes
preconditions:
all:
- key: '{{ request.object.spec.type }}'
operator: Equals
value: LoadBalancer
- key: '{{ nlb_check }}'
operator: Equals
value: external
- key: '{{ tg_attributes }}'
operator: Equals
value: "false"
validationFailureAction: Audit

View file

@ -1,22 +1,27 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: mutate-emptydir
spec:
admission: true
background: true
rules:
- name: setDefault
match:
resources:
- match:
any:
- resources:
kinds:
- Deployment
mutate:
foreach:
- list: "request.object.spec.template.spec.volumes"
patchStrategicMerge:
- Deployment
mutate:
foreach:
- list: request.object.spec.template.spec.volumes
patchStrategicMerge:
spec:
template:
spec:
template:
spec:
volumes:
- name: "{{ element.name }}"
(emptyDir):
+(sizeLimit): "20Mi"
volumes:
- (emptyDir):
+(sizeLimit): 20Mi
name: '{{ element.name }}'
name: setDefault
validationFailureAction: Audit

View file

@ -1,26 +1,30 @@
apiVersion : kyverno.io/v1
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-resources
annotations:
pod-policies.kyverno.io/autogen-controllers: "none"
pod-policies.kyverno.io/autogen-controllers: none
name: add-default-resources
spec:
admission: true
background: false
rules:
- name: add-default-requests
match:
resources:
- match:
any:
- resources:
kinds:
- Pod
mutate:
foreach:
- list: "request.object.spec.containers"
patchesJson6902: |-
- path: /spec/containers/{{elementIndex}}/resources/requests/memory
op: add
value: "100Mi"
- list: "request.object.spec.containers"
patchesJson6902: |-
- path: /spec/containers/{{elementIndex}}/resources/requests/cpu
op: add
value: "100m"
- Pod
mutate:
foreach:
- list: request.object.spec.containers
patchesJson6902: |-
- path: /spec/containers/{{elementIndex}}/resources/requests/memory
op: add
value: "100Mi"
- list: request.object.spec.containers
patchesJson6902: |-
- path: /spec/containers/{{elementIndex}}/resources/requests/cpu
op: add
value: "100m"
name: add-default-requests
validationFailureAction: Audit

View file

@ -1,47 +1,56 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: foreach-json-patch
annotations:
pod-policies.kyverno.io/autogen-controllers: none
spec:
rules:
- name: add-security-context
match:
resources:
kinds:
- Pod
preconditions:
- key: "{{ request.operation }}"
operator: Equals
value: "CREATE"
mutate:
foreach:
- list: "request.object.spec.containers"
patchesJson6902: |-
- path: /spec/containers/{{elementIndex}}/securityContext
op: add
value: {"runAsNonRoot" : true}
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: mutate-images
annotations:
pod-policies.kyverno.io/autogen-controllers: none
name: foreach-json-patch
spec:
background: false
admission: true
background: true
rules:
- name: test
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
mutate:
foreach:
- list: "request.object.spec.containers"
- list: request.object.spec.containers
patchesJson6902: |-
- path: /spec/containers/{{elementIndex}}/securityContext
op: add
value: {"runAsNonRoot" : true}
name: add-security-context
preconditions:
all:
- key: '{{ request.operation }}'
operator: Equals
value: CREATE
validationFailureAction: Audit
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
annotations:
pod-policies.kyverno.io/autogen-controllers: none
name: mutate-images
spec:
admission: true
background: false
rules:
- match:
any:
- resources:
kinds:
- Pod
mutate:
foreach:
- list: request.object.spec.containers
patchStrategicMerge:
spec:
containers:
- name: "{{ element.name }}"
image: registry.digitalocean.com/runlevl4/{{ images.containers."{{element.name}}".name}}:{{images.containers."{{element.name}}".tag}}
- image: registry.digitalocean.com/runlevl4/{{ images.containers."{{element.name}}".name}}:{{images.containers."{{element.name}}".tag}}
name: '{{ element.name }}'
name: test
validationFailureAction: Audit

View file

@ -1,29 +1,32 @@
apiVersion : kyverno.io/v1
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-resources
spec:
admission: true
background: false
rules:
- name: add-default-requests
match:
- match:
any:
- resources:
kinds:
- Pod
preconditions:
any:
- key: "{{request.operation}}"
operator: In
value:
- CREATE
- UPDATE
mutate:
patchStrategicMerge:
spec:
containers:
- (name): "*"
resources:
requests:
+(memory): "100Mi"
+(cpu): "100m"
- (name): '*'
resources:
requests:
+(cpu): 100m
+(memory): 100Mi
name: add-default-requests
preconditions:
any:
- key: '{{request.operation}}'
operator: AllIn
value:
- CREATE
- UPDATE
validationFailureAction: Audit

View file

@ -1,100 +1,107 @@
# Below there are both type of policies: ClusterPolicy and Policy(Namespaced-Policy)
#ClusterPolicy
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-label
annotations:
policies.kyverno.io/title: Add nodeSelector
policies.kyverno.io/category: Sample
policies.kyverno.io/description: Labels are used as an important source of metadata
describing objects in various ways or triggering other functionality. Labels
are also a very basic concept and should be used throughout Kubernetes. This
policy performs a simple mutation which adds a label `color=orange` to Pods,
Services, ConfigMaps, and Secrets.
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
Labels are used as an important source of metadata describing objects in various ways
or triggering other functionality. Labels are also a very basic concept and should be
used throughout Kubernetes. This policy performs a simple mutation which adds a label
`color=orange` to Pods, Services, ConfigMaps, and Secrets.
policies.kyverno.io/title: Add nodeSelector
name: add-label
spec:
admission: true
background: false
rules:
- name: add-label
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
metadata:
labels:
color: orange
- name: "impossible-rule"
match:
resources:
kinds:
name: add-label
- match:
any:
- resources:
kinds:
- Pod
preconditions:
all:
- key: "not-the-name" # This precondition should always fail!
operator: In
value: "{{ request.object.metadata.labels | keys(@) }}"
mutate:
patchStrategicMerge:
metadata:
labels:
something: "something"
something: something
name: impossible-rule
preconditions:
all:
- key: not-the-name
operator: AllIn
value: '{{ request.object.metadata.labels | keys(@) }}'
validationFailureAction: Audit
---
# Policy ( In testing namespace )
apiVersion: kyverno.io/v1
kind: Policy
metadata:
annotations:
policies.kyverno.io/category: Sample
policies.kyverno.io/description: The ndots value controls where DNS lookups are
first performed in a cluster and needs to be set to a lower value than the default
of 5 in some cases. This policy mutates all Pods to add the ndots option with
a value of 1.
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Add ndots
name: add-ndots
namespace: testing
annotations:
policies.kyverno.io/title: Add ndots
policies.kyverno.io/category: Sample
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
The ndots value controls where DNS lookups are first performed in a cluster
and needs to be set to a lower value than the default of 5 in some cases.
This policy mutates all Pods to add the ndots option with a value of 1.
spec:
admission: true
background: false
rules:
- name: add-ndots
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
spec:
dnsConfig:
options:
- name: ndots
value: "1"
- name: ndots
value: "1"
name: add-ndots
validationFailureAction: Audit
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: example
spec:
admission: true
background: true
rules:
- name: object_from_lists
context:
- name: annotations
variable:
jmesPath: items(request.object.metadata.annotations, 'key', 'value')[?starts_with(key, 'key')]
- name: annotations
variable:
jmesPath: object_from_lists(annotations[].key, annotations[].value)
- context:
- name: annotations
variable:
jmesPath: items(request.object.metadata.annotations, 'key', 'value')[?starts_with(key,
'key')]
- name: annotations
variable:
jmesPath: object_from_lists(annotations[].key, annotations[].value)
match:
resources:
kinds:
- Pod
any:
- resources:
kinds:
- Pod
mutate:
patchesJson6902: |-
- path: "/metadata/annotations"
op: replace
value: {{ annotations }}
name: object_from_lists
validationFailureAction: Audit

View file

@ -1,19 +1,23 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-labels
spec:
admission: true
background: false
rules:
- name: add-default-labels
match:
resources:
kinds:
- Pod
- Service
- Namespace
- match:
any:
- resources:
kinds:
- Pod
- Service
- Namespace
mutate:
patchStrategicMerge:
metadata:
labels:
custom-foo-label: my-bar-default
name: add-default-labels
validationFailureAction: Audit

View file

@ -1,34 +1,39 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-pod-default-seccompprofile
annotations:
policies.kyverno.io/category: Security
policies.kyverno.io/description: Seccomp Profiles restrict the system calls that can be made
from a process. The Linux kernel has a few hundred system calls, but most of them are not
needed by any given process. If a process can be compromised and tricked into making other
system calls, though, it may lead to a security vulnerability that could result in the
compromise of the whole system. By restricting what system calls can be made, seccomp is
a key component for building application sandboxes.
policies.kyverno.io/description: Seccomp Profiles restrict the system calls that
can be made from a process. The Linux kernel has a few hundred system calls,
but most of them are not needed by any given process. If a process can be compromised
and tricked into making other system calls, though, it may lead to a security
vulnerability that could result in the compromise of the whole system. By restricting
what system calls can be made, seccomp is a key component for building application
sandboxes.
name: add-pod-default-seccompprofile
spec:
admission: true
background: false
validationFailureAction: audit
rules:
- name: add-pod-default-seccompprofile
- exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- default
- kyverno
match:
resources:
kinds:
- Pod
exclude:
resources:
namespaces:
- "kube-system"
- "kube-public"
- "default"
- "kyverno"
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
name: add-pod-default-seccompprofile
validationFailureAction: Audit

View file

@ -1,35 +1,38 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: insert-podantiaffinity
spec:
admission: true
background: true
rules:
- name: insert-podantiaffinity
match:
resources:
- match:
any:
- resources:
kinds:
- Deployment
preconditions:
# This precondition ensures that the label `app` is applied to Pods within the Deployment resource.
- key: "{{request.object.metadata.labels.app}}"
- Deployment
mutate:
patchStrategicMerge:
spec:
template:
spec:
+(affinity):
+(podAntiAffinity):
+(preferredDuringSchedulingIgnoredDuringExecution):
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- '{{request.object.metadata.labels.app}}'
topologyKey: kubernetes.io/hostname
weight: 1
name: insert-podantiaffinity
preconditions:
all:
- key: '{{request.object.metadata.labels.app}}'
operator: NotEquals
value: ""
# Mutates the Deployment resource to add fields.
mutate:
patchStrategicMerge:
spec:
template:
spec:
# Add the `affinity` key and others if not already specified in the Deployment manifest.
+(affinity):
+(podAntiAffinity):
+(preferredDuringSchedulingIgnoredDuringExecution):
- weight: 1
podAffinityTerm:
topologyKey: "kubernetes.io/hostname"
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- "{{request.object.metadata.labels.app}}"
validationFailureAction: Audit

View file

@ -1,22 +1,25 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: secrets-not-from-env-vars
spec:
admission: true
background: false
validationFailureAction: audit
rules:
- name: secrets-not-from-env-vars
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: secrets-not-from-env-vars
validate:
message: "Secrets must be mounted as volumes, not as environment variables."
message: Secrets must be mounted as volumes, not as environment variables.
pattern:
spec:
containers:
- name: "*"
=(env):
- =(env):
- =(valueFrom):
X(secretKeyRef): "null"
name: '*'
validationFailureAction: Audit

View file

@ -1,66 +1,64 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: validate-probes
annotations:
# Only applies to pods originating from DaemonSet, Deployment, or StatefulSet.
pod-policies.kyverno.io/autogen-controllers: DaemonSet,Deployment,StatefulSet
name: validate-probes
spec:
validationFailureAction: enforce
admission: true
background: false
rules:
# Checks the first container in a Pod.
- name: validate-probes-c0
match:
resources:
- match:
any:
- resources:
kinds:
- Pod
validate:
message: "Liveness and readiness probes cannot be the same."
# A `deny` rule is different in structure than a `validate` rule and inverts the check. It uses `conditions` written in JMESPath notation upon which to base its decisions.
deny:
conditions:
# In this condition, it checks the entire map structure of the `readinessProbe` against that of the `livenessProbe`. If both are found to be equal, the Pod creation
# request will be denied.
- key: "{{ request.object.spec.containers[0].readinessProbe }}"
operator: Equals
value: "{{ request.object.spec.containers[0].livenessProbe }}"
# Checks the second container in a Pod.
- name: validate-probes-c1
match:
resources:
- Pod
name: validate-probes-c0
validate:
deny:
conditions:
- key: '{{ request.object.spec.containers[0].readinessProbe }}'
operator: Equals
value: '{{ request.object.spec.containers[0].livenessProbe }}'
message: Liveness and readiness probes cannot be the same.
- match:
any:
- resources:
kinds:
- Pod
validate:
message: "Liveness and readiness probes cannot be the same."
deny:
conditions:
- key: "{{ request.object.spec.containers[1].readinessProbe }}"
operator: Equals
value: "{{ request.object.spec.containers[1].livenessProbe }}"
# Checks the third container in a Pod.
- name: validate-probes-c2
match:
resources:
- Pod
name: validate-probes-c1
validate:
deny:
conditions:
- key: '{{ request.object.spec.containers[1].readinessProbe }}'
operator: Equals
value: '{{ request.object.spec.containers[1].livenessProbe }}'
message: Liveness and readiness probes cannot be the same.
- match:
any:
- resources:
kinds:
- Pod
validate:
message: "Liveness and readiness probes cannot be the same."
deny:
conditions:
- key: "{{ request.object.spec.containers[2].readinessProbe }}"
operator: Equals
value: "{{ request.object.spec.containers[2].livenessProbe }}"
# Checks the fourth container in a Pod.
- name: validate-probes-c3
match:
resources:
- Pod
name: validate-probes-c2
validate:
deny:
conditions:
- key: '{{ request.object.spec.containers[2].readinessProbe }}'
operator: Equals
value: '{{ request.object.spec.containers[2].livenessProbe }}'
message: Liveness and readiness probes cannot be the same.
- match:
any:
- resources:
kinds:
- Pod
validate:
message: "Liveness and readiness probes cannot be the same."
deny:
conditions:
- key: "{{ request.object.spec.containers[3].readinessProbe }}"
operator: Equals
value: "{{ request.object.spec.containers[3].livenessProbe }}"
- Pod
name: validate-probes-c3
validate:
deny:
conditions:
- key: '{{ request.object.spec.containers[3].readinessProbe }}'
operator: Equals
value: '{{ request.object.spec.containers[3].livenessProbe }}'
message: Liveness and readiness probes cannot be the same.
validationFailureAction: Enforce

View file

@ -1,24 +1,29 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: deployment-has-multiple-replicas
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: deployment-has-multiple-replicas
match:
resources:
kinds:
- Deployment
exclude:
resources:
- exclude:
any:
- resources:
namespaces:
- kyverno
- kube-system
- kube-node-lease
- kube-public
validate:
message: "Deployments must have more than one replica to ensure availability."
pattern:
spec:
replicas: ">1"
match:
any:
- resources:
kinds:
- Deployment
name: deployment-has-multiple-replicas
validate:
message: Deployments must have more than one replica to ensure availability.
pattern:
spec:
replicas: '>1'
validationFailureAction: Audit

View file

@ -1,33 +1,40 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: drop-all-capabilities
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: drop-all-containers
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: drop-all-containers
validate:
message: "Drop all must be defined for every container in the Pod."
message: Drop all must be defined for every container in the Pod.
pattern:
spec:
containers:
- securityContext:
capabilities:
drop: ["ALL"]
- name: drop-all-initcontainers
match:
resources:
kinds:
- Pod
drop:
- ALL
- match:
any:
- resources:
kinds:
- Pod
name: drop-all-initcontainers
validate:
message: "Drop all must be defined for every container in the Pod."
message: Drop all must be defined for every container in the Pod.
pattern:
spec:
initContainers:
- securityContext:
capabilities:
drop: ["ALL"]
drop:
- ALL
validationFailureAction: Audit

View file

@ -1,22 +1,27 @@
apiVersion : kyverno.io/v1
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-automount-sa-token
annotations:
policies.kyverno.io/category: Security
policies.kyverno.io/description: Kubernetes automatically mounts service account
credentials in each pod. The service account may be assigned roles allowing pods
to access API resources. To restrict access, opt out of auto-mounting tokens by
setting automountServiceAccountToken to false.
credentials in each pod. The service account may be assigned roles allowing
pods to access API resources. To restrict access, opt out of auto-mounting tokens
by setting automountServiceAccountToken to false.
name: restrict-automount-sa-token
spec:
admission: true
background: true
rules:
- name: validate-automountServiceAccountToken
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-automountServiceAccountToken
validate:
message: "Auto-mounting of Service Account tokens is not allowed"
message: Auto-mounting of Service Account tokens is not allowed
pattern:
spec:
automountServiceAccountToken: false
validationFailureAction: Audit

View file

@ -1,22 +1,27 @@
apiVersion : kyverno.io/v1
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-ingress-classes
annotations:
policies.kyverno.io/category: Workload Management
policies.kyverno.io/description: It can be useful to restrict Ingress resources to a set of
known ingress classes that are allowed in the cluster. You can customize this policy to
allow ingress classes that are configured in the cluster.
policies.kyverno.io/description: It can be useful to restrict Ingress resources
to a set of known ingress classes that are allowed in the cluster. You can customize
this policy to allow ingress classes that are configured in the cluster.
name: restrict-ingress-classes
spec:
admission: true
background: true
rules:
- name: validate-ingress
match:
resources:
kinds:
- Ingress
- match:
any:
- resources:
kinds:
- Ingress
name: validate-ingress
validate:
message: "Unknown ingress class"
message: Unknown ingress class
pattern:
metadata:
annotations:
kubernetes.io/ingress.class: "F5 | nginx"
kubernetes.io/ingress.class: F5 | nginx
validationFailureAction: Audit

View file

@ -1,17 +1,21 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: no-loadbalancers
spec:
validationFailureAction: audit
admission: true
background: true
rules:
- name: no-LoadBalancer
match:
resources:
kinds:
- Service
- match:
any:
- resources:
kinds:
- Service
name: no-LoadBalancer
validate:
message: "Service of type LoadBalancer is not allowed."
message: Service of type LoadBalancer is not allowed.
pattern:
spec:
type: "!LoadBalancer"
type: '!LoadBalancer'
validationFailureAction: Audit

View file

@ -1,45 +1,53 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: validate-userid-groupid-fsgroup
annotations:
policies.kyverno.io/category: Security Context
policies.kyverno.io/description: All processes inside the pod can be made to run with specific user
and groupID by setting 'runAsUser' and 'runAsGroup' respectively. 'fsGroup' can be specified
to make sure any file created in the volume with have the specified groupID. These options can be
used to validate the IDs used for user and group.
policies.kyverno.io/description: All processes inside the pod can be made to run
with specific user and groupID by setting 'runAsUser' and 'runAsGroup' respectively.
'fsGroup' can be specified to make sure any file created in the volume with
have the specified groupID. These options can be used to validate the IDs used
for user and group.
name: validate-userid-groupid-fsgroup
spec:
admission: true
background: true
rules:
- name: validate-userid
match:
resources:
kinds:
- Pod
- match:
any:
- resources:
kinds:
- Pod
name: validate-userid
validate:
message: "User ID should be 1000"
message: User ID should be 1000
pattern:
spec:
securityContext:
runAsUser: '1000'
- name: validate-groupid
match:
resources:
kinds:
- Pod
runAsUser: "1000"
- match:
any:
- resources:
kinds:
- Pod
name: validate-groupid
validate:
message: "Group ID should be 3000"
message: Group ID should be 3000
pattern:
spec:
securityContext:
runAsGroup: '3000'
- name: validate-fsgroup
match:
resources:
kinds:
- Pod
runAsGroup: "3000"
- match:
any:
- resources:
kinds:
- Pod
name: validate-fsgroup
validate:
message: "fsgroup should be 2000"
message: fsgroup should be 2000
pattern:
spec:
securityContext:
fsGroup: '2000'
fsGroup: "2000"
validationFailureAction: Audit

View file

@ -1,29 +1,31 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: spread-pods
spec:
admission: true
background: true
rules:
- name: spread-pods-across-nodes
# Matches any Deployment with the label `distributed=required`
match:
resources:
- match:
any:
- resources:
kinds:
- Deployment
selector:
matchLabels:
distributed: required
# Mutates the incoming Deployment.
mutate:
patchStrategicMerge:
spec:
template:
spec:
# Adds the topologySpreadConstraints field if non-existent in the request.
+(topologySpreadConstraints):
- maxSkew: 1
topologyKey: zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
distributed: required
mutate:
patchStrategicMerge:
spec:
template:
spec:
+(topologySpreadConstraints):
- labelSelector:
matchLabels:
distributed: required
maxSkew: 1
topologyKey: zone
whenUnsatisfiable: DoNotSchedule
name: spread-pods-across-nodes
validationFailureAction: Audit