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:
parent
3a61f2c6b7
commit
7562bea6db
40 changed files with 996 additions and 814 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 host’s 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 host’s 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue