Adds further kyverno policies

Signed-off-by: Sebastian Kawelke <sebastian.kawelke@l3montree.com>
This commit is contained in:
Sebastian Kawelke
2025-12-03 11:48:43 +01:00
parent 56ddb422ca
commit ac712f4063
35 changed files with 1169 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
labels:
opendesk.eu/security-id: image-sec-001
annotations:
policies.kyverno.io/title: Disallow Latest Tag
policies.kyverno.io/category: Best Practices
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
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. This policy validates that the image
specifies a tag and that it is not called `latest`.
spec:
validationFailureAction: Audit
background: true
rules:
- name: require-image-tag
match:
any:
- resources:
kinds:
- Pod
validate:
message: "An image tag is required."
foreach:
- list: "request.object.spec.containers"
pattern:
image: "*:*"
- list: "request.object.spec.initContainers"
pattern:
image: "*:*"
- list: "request.object.spec.ephemeralContainers"
pattern:
image: "*:*"
- name: validate-image-tag
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Using a mutable image tag e.g. 'latest' is not allowed."
foreach:
- list: "request.object.spec.containers"
pattern:
image: "!*:latest"
- list: "request.object.spec.initContainers"
pattern:
image: "!*:latest"
- list: "request.object.spec.ephemeralContainers"
pattern:
image: "!*:latest"

View File

@@ -0,0 +1,40 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-image-registries
labels:
opendesk.eu/security-id: image-sec-002
annotations:
policies.kyverno.io/title: Restrict Image Registries
policies.kyverno.io/category: Best Practices, EKS Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/minversion: 1.6.0
kyverno.io/kubernetes-version: "1.26"
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
Images from unknown, public registries can be of dubious quality and may not be
scanned and secured, representing a high degree of risk. Requiring use of known, approved
registries helps reduce threat exposure by ensuring image pulls only come from them. This
policy validates that container images only originate from the registry `registry.opencode.de`.
spec:
validationFailureAction: Audit
background: true
rules:
- name: validate-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Unknown image registry."
pattern:
spec:
=(ephemeralContainers):
- image: "registry.opencode.de/*"
=(initContainers):
- image: "registry.opencode.de/*"
containers:
- image: "registry.opencode.de/*"

View File

@@ -0,0 +1,54 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-image-checksum
labels:
opendesk.eu/security-id: image-sec-003
annotations:
policies.kyverno.io/title: Require Images Use SHA-256 Checksums
policies.kyverno.io/category: Supply Chain Security
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/description: >-
Use of a SHA-256 checksum when pulling an image is often preferable because
tags are mutable and can be overwritten. This policy checks to ensure that
all images use SHA-256 digests in the format image@sha256:<64-character-hex>.
spec:
validationFailureAction: Audit
background: true
rules:
- name: require-image-checksum
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Images must use SHA-256 checksums rather than tags.
Expected format: registry/image:tag@sha256:<64-character-hex> or registry/image@sha256:<64-character-hex>
foreach:
- list: "request.object.spec.containers"
deny:
conditions:
any:
- key: "{{ regex_match('^.*@sha256:[a-f0-9]{64}$', element.image) }}"
operator: NotEquals
value: true
- list: "request.object.spec.initContainers || `[]`"
deny:
conditions:
any:
- key: "{{ regex_match('^.*@sha256:[a-f0-9]{64}$', element.image) }}"
operator: NotEquals
value: true
- list: "request.object.spec.ephemeralContainers || `[]`"
deny:
conditions:
any:
- key: "{{ regex_match('^.*@sha256:[a-f0-9]{64}$', element.image) }}"
operator: NotEquals
value: true

View File

@@ -0,0 +1,40 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image
labels:
opendesk.eu/security-id: image-sec-004
annotations:
policies.kyverno.io/title: Verify Image
policies.kyverno.io/category: Software Supply Chain Security, EKS Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/minversion: 1.7.0
policies.kyverno.io/description: >-
Using the Cosign project, OCI images may be signed to ensure supply chain
security is maintained. Those signatures can be verified before pulling into
a cluster.
spec:
validationFailureAction: Audit
background: false
rules:
- name: verify-image
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "registry.opencode.de/*"
mutateDigest: true
attestors:
- entries:
- keys:
publicKeys: |
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXdVDz6n39PDj9ZezqYgmZ/qCDV4h
bQwmuDfxix8BMRTZB9UHcOX4EgmAHWyXsbANB6tG8XWoqFpYRReNUvsG6g==
-----END PUBLIC KEY-----

View File

@@ -0,0 +1,53 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
###
# TODO
###
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-sbom-cyclonedx
labels:
opendesk.eu/security-id: image-sec-005
annotations:
policies.kyverno.io/title: Verify CycloneDX SBOM (Keyless)
policies.kyverno.io/category: Software Supply Chain Security
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/minversion: 1.8.3
kyverno.io/kyverno-version: 1.9.0
kyverno.io/kubernetes-version: "1.24"
policies.kyverno.io/description: >-
Software Bill of Materials (SBOM) provide details on the composition of a given
container image and may be represented in a couple different standards.
Having an SBOM can be important to ensuring images are built using verified
processes. This policy verifies that an image has an SBOM in CycloneDX format
and was signed by the expected subject and issuer when produced through GitHub Actions
and using Cosign's keyless signing. It requires configuration based upon your own values.
spec:
validationFailureAction: Audit
webhookTimeoutSeconds: 30
rules:
- name: check-sbom
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "registry.opencode.de/*"
attestations:
- predicateType: https://cyclonedx.org/schema
attestors:
- entries:
- keyless:
subject: "mysubject"
issuer: "https://token.actions.githubusercontent.com"
rekor:
url: https://rekor.sigstore.dev
conditions:
- all:
- key: "{{ Data.bomFormat }}"
operator: Equals
value: CycloneDX

View File

@@ -0,0 +1,56 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
###
# TODO
###
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-slsa-provenance-keyless
labels:
opendesk.eu/security-id: image-sec-006
annotations:
policies.kyverno.io/title: Verify SLSA Provenance (Keyless)
policies.kyverno.io/category: Software Supply Chain Security
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/minversion: 1.8.3
kyverno.io/kyverno-version: 1.9.0
kyverno.io/kubernetes-version: "1.24"
policies.kyverno.io/description: >-
Provenance is used to identify how an artifact was produced
and from where it originated. SLSA provenance is an industry-standard
method of representing that provenance. This policy verifies that an
image has SLSA provenance and was signed by the expected subject and issuer
when produced through GitHub Actions.
spec:
validationFailureAction: Audit
webhookTimeoutSeconds: 30
rules:
- name: check-slsa-keyless
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "registry.opencode.de/*"
attestations:
- predicateType: https://slsa.dev/provenance/v0.2
attestors:
- count: 1
entries:
- keyless:
subject: "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@refs/tags/v*"
issuer: "https://token.actions.githubusercontent.com"
rekor:
url: https://rekor.sigstore.dev
conditions:
- all:
# This expression uses a regex pattern to ensure the builder.id in the attestation is equal to the official
# SLSA provenance generator workflow and uses a tagged release in semver format. If using a specific SLSA
# provenance generation workflow, you may need to adjust the first input as necessary.
- key: "{{ regex_match('^https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@refs/tags/v[0-9].[0-9].[0-9]$','{{ builder.id}}') }}"
operator: Equals
value: true

View File

@@ -0,0 +1 @@
# TODO

View File

@@ -0,0 +1,7 @@
## Image Security
...
### Status
{{ .image-sec.status }}

View File

@@ -0,0 +1,42 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
name: image-sec
policies:
- image-sec-001_latest-tag.yaml
- image-sec-002_trusted-registry.yaml
- image-sec-003_digest.yaml
- image-sec-004_signature.yaml
- image-sec-005_sbom.yaml
- image-sec-006_provenance.yaml
resources:
- ../../../rendered.yaml
exceptions: []
results:
# image-sec-001
- policy: disallow-latest-tag
rule: require-image-tag
result: pass
- policy: disallow-latest-tag
rule: validate-image-tag
result: pass
# image-sec-002
- policy: restrict-image-registries
rule: validate-registries
result: pass
# image-sec-003
- policy: require-image-checksum
rule: require-image-checksum
result: pass
# image-sec-004
- policy: verify-image
rule: verify-image
result: pass
# image-sec-005
#- policy: verify-sbom-cyclonedx
# rule: verify-sbom-cyclonedx
# result: pass
# image-sec-006
#- policy: verify-slsa-provenance-keyless
# rule: verify-slsa-provenance-keyless
# result: pass

View File

@@ -0,0 +1,24 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
name: net-mgt
policies:
- net-mgt-001_service-external-ips.yaml
- net-mgt-002_service-node-port.yaml
- net-mgt-003_ingress-host-match-tls.yaml
resources:
- ../../../rendered.yaml
exceptions: []
results:
# net-mgt-001
- policy: restrict-external-ips
rule: check-ips
result: pass
# net-mgt-002
- policy: restrict-nodeport
rule: validate-nodeport
result: pass
# net-mgt-003
- policy: ingress-host-match-tls
rule: host-match-tls
result: pass

View File

@@ -0,0 +1,37 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-external-ips
labels:
opendesk.eu/security-id: net-mgt-001
annotations:
policies.kyverno.io/title: Restrict External IPs
policies.kyverno.io/category: Best Practices
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Service
policies.kyverno.io/description: >-
Service externalIPs can be used for a MITM attack (CVE-2020-8554).
Restrict externalIPs or limit to a known set of addresses.
See: https://github.com/kyverno/kyverno/issues/1367. This policy validates
that the `externalIPs` field is not set on a Service.
spec:
validationFailureAction: Audit
background: true
rules:
- name: check-ips
match:
any:
- resources:
kinds:
- Service
validate:
message: "externalIPs are not allowed."
pattern:
spec:
# restrict external IP addresses
# you can alternatively restrict to a known set of addresses using:
# =(externalIPs): ["37.10.11.53", "153.10.20.1"]
X(externalIPs): "null"

View File

@@ -0,0 +1,35 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-nodeport
labels:
opendesk.eu/security-id: net-mgt-002
annotations:
policies.kyverno.io/title: Disallow NodePort
policies.kyverno.io/category: Best Practices
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Service
policies.kyverno.io/description: >-
A Kubernetes Service of type NodePort uses a host port to receive traffic from
any source. A NetworkPolicy cannot be used to control traffic to host ports.
Although NodePort Services can be useful, their use must be limited to Services
with additional upstream security checks. This policy validates that any new Services
do not use the `NodePort` type.
spec:
validationFailureAction: Audit
background: true
rules:
- name: validate-nodeport
match:
any:
- resources:
kinds:
- Service
validate:
message: "Services of type NodePort are not allowed."
pattern:
spec:
=(type): "!NodePort"

View File

@@ -0,0 +1,40 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: ingress-host-match-tls
labels:
opendesk.eu/security-id: net-mgt-003
annotations:
policies.kyverno.io/title: Ingress Host Match TLS
policies.kyverno.io/category: Other
policies.kyverno.io/severity: medium
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/minversion: 1.6.0
kyverno.io/kubernetes-version: "1.20, 1.21"
policies.kyverno.io/subject: Ingress
policies.kyverno.io/description: >-
Ingress resources which name a host name that is not present
in the TLS section can produce ingress routing failures as a TLS
certificate may not correspond to the destination host. This policy
ensures that the host name in an Ingress rule is also found
in the list of TLS hosts.
spec:
background: false
validationFailureAction: Audit
rules:
- name: host-match-tls
match:
any:
- resources:
kinds:
- Ingress
validate:
message: "The host(s) in spec.rules[].host must match those in spec.tls[].hosts[]."
deny:
conditions:
all:
- key: "{{ (request.object.spec.rules[].host || `[]`) | sort(@) }}"
operator: AnyNotIn
value: "{{ (request.object.spec.tls[].hosts[] || `[]`) | sort(@) }}"

View File

@@ -0,0 +1,7 @@
## Network Management
...
### Status
{{ .net-mgt.status }}

View File

@@ -0,0 +1,49 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
name: rbac-mgt
policies:
- rbac-mgt-001_automount-serviceaccount.yaml
- rbac-mgt-002_binding-clusteradmin.yaml
#- rbac-mgt-003_clusterrole.yaml
- rbac-mgt-004_escalation-verbs.yaml
- rbac-mgt-005_automount-sa-setting.yaml
- rbac-mgt-006_secret-verbs.yaml
- rbac-mgt-007_wildcard-verbs.yaml
- rbac-mgt-008_wildcard-resources.yaml
resources:
- ../../../rendered.yaml
exceptions: []
results:
# rbac-mgt-001
- policy: restrict-automount-sa-token
rule: validate-automountServiceAccountToken
result: pass
# rbac-mgt-002
- policy: restrict-binding-clusteradmin
rule: clusteradmin-bindings
result: pass
# rbac-mgt-003
#- policy: restrict-binding-clusteradmin
# rule: clusteradmin-bindings
# result: pass
# rbac-mgt-004
- policy: restrict-escalation-verbs-roles
rule: escalate
result: pass
# rbac-mgt-005
- policy: restrict-sa-automount-sa-token
rule: validate-sa-automountServiceAccountToken
result: pass
# rbac-mgt-006
- policy: restrict-secret-role-verbs
rule: secret-verbs
result: pass
# rbac-mgt-007
- policy: restrict-wildcard-verbs
rule: wildcard-verbs
result: pass
# rbac-mgt-008
- policy: restrict-wildcard-resources
rule: wildcard-resources
result: pass

View File

@@ -0,0 +1,35 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-automount-sa-token
labels:
opendesk.eu/security-id: rbac-mgt-001
annotations:
policies.kyverno.io/title: Restrict Auto-Mount of Service Account Tokens
policies.kyverno.io/category: Sample, EKS Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod,ServiceAccount
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/description: >-
Kubernetes automatically mounts ServiceAccount credentials in each Pod.
The ServiceAccount may be assigned roles allowing Pods to access API resources.
Blocking this ability is an extension of the least privilege best practice and should
be followed if Pods do not need to speak to the API server to function.
This policy ensures that mounting of these ServiceAccount tokens is blocked.
spec:
validationFailureAction: Audit
background: true
rules:
- name: validate-automountServiceAccountToken
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Auto-mounting of Service Account tokens is not allowed."
pattern:
spec:
automountServiceAccountToken: "false"

View File

@@ -0,0 +1,37 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-binding-clusteradmin
labels:
opendesk.eu/security-id: rbac-mgt-002
annotations:
policies.kyverno.io/title: Restrict Binding to Cluster-Admin
policies.kyverno.io/category: Security
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: RoleBinding, ClusterRoleBinding, RBAC
kyverno.io/kyverno-version: 1.6.2
policies.kyverno.io/minversion: 1.6.0
kyverno.io/kubernetes-version: "1.23"
policies.kyverno.io/description: >-
The cluster-admin ClusterRole allows any action to be performed on any resource
in the cluster and its granting should be heavily restricted. This
policy prevents binding to the cluster-admin ClusterRole in
RoleBinding or ClusterRoleBinding resources.
spec:
validationFailureAction: Audit
background: true
rules:
- name: clusteradmin-bindings
match:
any:
- resources:
kinds:
- RoleBinding
- ClusterRoleBinding
validate:
message: "Binding to cluster-admin is not allowed."
pattern:
roleRef:
name: "!cluster-admin"

View File

@@ -0,0 +1,2 @@
# No clusterrole allowed
# TODO

View File

@@ -0,0 +1,53 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-escalation-verbs-roles
labels:
opendesk.eu/security-id: rbac-mgt-004
annotations:
policies.kyverno.io/title: Restrict Escalation Verbs in Roles
policies.kyverno.io/category: Security
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Role, ClusterRole, RBAC
kyverno.io/kyverno-version: 1.6.2
policies.kyverno.io/minversion: 1.6.0
kyverno.io/kubernetes-version: "1.23"
policies.kyverno.io/description: >-
The verbs `impersonate`, `bind`, and `escalate` may all potentially lead to
privilege escalation and should be tightly controlled. This policy prevents
use of these verbs in Role or ClusterRole resources.
spec:
validationFailureAction: Audit
background: true
rules:
- name: escalate
match:
any:
- resources:
kinds:
- Role
- ClusterRole
validate:
message: "Use of verbs `escalate`, `bind`, and `impersonate` are forbidden."
foreach:
- list: "request.object.rules[]"
deny:
conditions:
all:
- key: "{{ element.apiGroups || '' }}"
operator: AnyIn
value:
- rbac.authorization.k8s.io
- key: "{{ element.resources || '' }}"
operator: AnyIn
value:
- clusterroles
- roles
- key: "{{ element.verbs }}"
operator: AnyIn
value:
- bind
- escalate
- impersonate

View File

@@ -0,0 +1,35 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-sa-automount-sa-token
labels:
opendesk.eu/security-id: rbac-mgt-005
annotations:
policies.kyverno.io/title: Restrict Auto-Mount of Service Account Tokens in Service Account
policies.kyverno.io/category: Security
kyverno.io/kyverno-version: 1.11.1
kyverno.io/kubernetes-version: "1.27"
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Secret,ServiceAccount
policies.kyverno.io/description: >-
Kubernetes automatically mounts ServiceAccount credentials in each ServiceAccount.
The ServiceAccount may be assigned roles allowing Pods to access API resources.
Blocking this ability is an extension of the least privilege best practice and should
be followed if Pods do not need to speak to the API server to function.
This policy ensures that mounting of these ServiceAccount tokens is blocked.
spec:
validationFailureAction: Audit
background: true
rules:
- name: validate-sa-automountServiceAccountToken
match:
any:
- resources:
kinds:
- ServiceAccount
validate:
message: "ServiceAccounts must set automountServiceAccountToken to false."
pattern:
automountServiceAccountToken: false

View File

@@ -0,0 +1,42 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-secret-role-verbs
labels:
opendesk.eu/security-id: rbac-mgt-006
annotations:
policies.kyverno.io/title: Restrict Secret Verbs in Roles
policies.kyverno.io/category: Security
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Role, ClusterRole, RBAC
kyverno.io/kyverno-version: 1.6.2
policies.kyverno.io/minversion: 1.6.0
kyverno.io/kubernetes-version: "1.23"
policies.kyverno.io/description: >-
The verbs `get`, `list`, and `watch` in a Role or ClusterRole, when paired with the Secrets resource, effectively
allows Secrets to be read which may expose sensitive information. This policy prevents
a Role or ClusterRole from using these verbs in tandem with Secret resources. In order to
fully implement this control, it is recommended to pair this policy with another which
also prevents use of the wildcard ('*') in the verbs list either when explicitly naming Secrets
or when also using a wildcard in the base API group.
spec:
validationFailureAction: Audit
background: true
rules:
- name: secret-verbs
match:
any:
- resources:
kinds:
- Role
- ClusterRole
validate:
message: "Requesting verbs `get`, `list`, or `watch` on Secrets is forbidden."
deny:
conditions:
any:
- key: ["get","list","watch"]
operator: AnyIn
value: "{{ request.object.rules[?resources.contains(@,'secrets')].verbs[] }}"

View File

@@ -0,0 +1,41 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-wildcard-verbs
labels:
opendesk.eu/security-id: rbac-mgt-007
annotations:
policies.kyverno.io/title: Restrict Wildcard in Verbs
policies.kyverno.io/category: Security, EKS Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Role, ClusterRole, RBAC
kyverno.io/kyverno-version: 1.6.2
policies.kyverno.io/minversion: 1.6.0
kyverno.io/kubernetes-version: "1.23"
policies.kyverno.io/description: >-
Wildcards ('*') in verbs grants all access to the resources referenced by it and
does not follow the principal of least privilege. As much as possible,
avoid such open verbs unless scoped to perhaps a custom API group.
This policy blocks any Role or ClusterRole that contains a wildcard entry in
the verbs list found in any rule.
spec:
validationFailureAction: Audit
background: true
rules:
- name: wildcard-verbs
match:
any:
- resources:
kinds:
- Role
- ClusterRole
validate:
message: "Use of a wildcard ('*') in any verbs is forbidden."
deny:
conditions:
any:
- key: "{{ contains(to_array(request.object.rules[].verbs[]), '*') }}"
operator: Equals
value: true

View File

@@ -0,0 +1,41 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-wildcard-resources
labels:
opendesk.eu/security-id: rbac-mgt-008
annotations:
policies.kyverno.io/title: Restrict Wildcards in Resources
policies.kyverno.io/category: Security, EKS Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: ClusterRole, Role, RBAC
kyverno.io/kyverno-version: 1.7.0
policies.kyverno.io/minversion: 1.6.0
kyverno.io/kubernetes-version: "1.23"
policies.kyverno.io/description: >-
Wildcards ('*') in resources grants access to all of the resources referenced by
the given API group and does not follow the principal of least privilege. As much as possible,
avoid such open resources unless scoped to perhaps a custom API group.
This policy blocks any Role or ClusterRole that contains a wildcard entry in
the resources list found in any rule.
spec:
validationFailureAction: Audit
background: true
rules:
- name: wildcard-resources
match:
any:
- resources:
kinds:
- Role
- ClusterRole
validate:
message: "Use of a wildcard ('*') in any resources is forbidden."
deny:
conditions:
any:
- key: "{{ contains(request.object.rules[].resources[], '*') }}"
operator: Equals
value: true

View File

@@ -0,0 +1,7 @@
## Role Based Access Control (RBAC) Management
...
### Status
{{ .rbac-mgt.status }}

View File

@@ -8,6 +8,11 @@ policies:
- wld-iso-003_host-ports.yaml
- wld-iso-004_host-probes.yaml
- wld-iso-005_volume-types.yaml
- wld-iso-006_cri-socket-mount.yaml
- wld-iso-007_resource-requests-limits.yaml
- wld-iso-008_emptydir-sizelimit.yaml
- wld-iso-009_secrets-from-envs.yaml
- wld-iso-010_controlplane-scheduling.yaml
resources:
- ../../../rendered.yaml
exceptions: []
@@ -31,4 +36,42 @@ results:
# wld-iso-005
- policy: restrict-volume-types
rule: restricted-volumes
result: pass
# wld-iso-006
- policy: disallow-container-sock-mounts
rule: validate-docker-sock-mount
result: pass
- policy: disallow-container-sock-mounts
rule: validate-containerd-sock-mount
result: pass
- policy: disallow-container-sock-mounts
rule: validate-crio-sock-mount
result: pass
- policy: disallow-container-sock-mounts
rule: validate-dockerd-sock-mount
result: pass
- policy: disallow-container-sock-mounts
rule: validate-var-mount
result: pass
- policy: disallow-container-sock-mounts
rule: validate-var-run-mount
result: pass
# wld-iso-007
- policy: require-requests-limits
rule: validate-resources
result: pass
# wld-iso-008
- policy: require-emptydir-sizelimit
rule: require-emptydir-sizelimit
result: pass
# wld-iso-009
- policy: secrets-not-from-env-vars
rule: secrets-not-from-env-vars
result: pass
# wld-iso-010
- policy: restrict-controlplane-scheduling
rule: restrict-controlplane-scheduling-master
result: pass
- policy: restrict-controlplane-scheduling
rule: restrict-controlplane-scheduling-control-plane
result: pass

View File

@@ -0,0 +1,101 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-container-sock-mounts
labels:
opendesk.eu/security-id: wld-iso-006
annotations:
policies.kyverno.io/title: Disallow CRI socket mounts
policies.kyverno.io/category: Best Practices, EKS Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/description: >-
Container daemon socket bind mounts allows access to the container engine on the
node. This access can be used for privilege escalation and to manage containers
outside of Kubernetes, and hence should not be allowed. This policy validates that
the sockets used for CRI engines Docker, Containerd, and CRI-O are not used.
spec:
validationFailureAction: Audit
background: true
rules:
- name: validate-docker-sock-mount
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Use of the Docker Unix socket is not allowed."
pattern:
spec:
=(volumes):
- =(hostPath):
path: "!/var/run/docker.sock"
- name: validate-containerd-sock-mount
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Use of the Containerd Unix socket is not allowed."
pattern:
spec:
=(volumes):
- =(hostPath):
path: "!/var/run/containerd/containerd.sock"
- name: validate-crio-sock-mount
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Use of the CRI-O Unix socket is not allowed."
pattern:
spec:
=(volumes):
- =(hostPath):
path: "!/var/run/crio/crio.sock"
- name: validate-dockerd-sock-mount
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Use of the Docker CRI socket is not allowed."
pattern:
spec:
=(volumes):
- =(hostPath):
path: "!/var/run/cri-dockerd.sock"
- name: validate-var-mount
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Mounting /var is not allowed."
pattern:
spec:
=(volumes):
- =(hostPath):
path: "!/var"
- name: validate-var-run-mount
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Mounting /var/run is not allowed."
pattern:
spec:
=(volumes):
- =(hostPath):
path: "!/var/run"

View File

@@ -0,0 +1,56 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-requests-limits
labels:
opendesk.eu/security-id: wld-iso-007
annotations:
policies.kyverno.io/title: Require Limits and Requests
policies.kyverno.io/category: Best Practices, EKS Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/minversion: 1.6.0
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 resource requests and
limits per Pod, especially for memory and CPU. If a Namespace level request or limit is specified,
defaults will automatically be applied to each Pod based on the LimitRange configuration.
This policy validates that all containers have something specified for memory and CPU
requests and memory limits.
spec:
validationFailureAction: Audit
background: true
rules:
- name: validate-resources
match:
any:
- resources:
kinds:
- Pod
validate:
message: "CPU and memory resource requests and memory limits are required for containers."
pattern:
spec:
containers:
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
=(initContainers):
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
=(ephemeralContainers):
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"

View File

@@ -0,0 +1,36 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-emptydir-sizelimit
labels:
opendesk.eu/security-id: wld-iso-008
annotations:
policies.kyverno.io/title: Require emptyDir sizeLimit
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod, Volume
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/description: >-
When a Pod requests an emptyDir, by default it does not have a size limit which
may allow it to consume excess or all of the space in the medium backing the volume.
This can quickly overrun a Node and may result in a denial of service for other
workloads. This policy requires that all emptyDir volumes have a sizeLimit set.
spec:
validationFailureAction: Audit
background: true
rules:
- name: require-emptydir-sizelimit
match:
any:
- resources:
kinds:
- Pod
validate:
message: "All emptyDir volumes must have a sizeLimit set."
pattern:
spec:
=(volumes):
- =(emptyDir):
sizeLimit: "?*"

View File

@@ -0,0 +1,50 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: secrets-not-from-env-vars
labels:
opendesk.eu/security-id: wld-iso-009
annotations:
policies.kyverno.io/title: Disallow Secrets from Env Vars
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod, Secret
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/description: >-
Secrets used as environment variables containing sensitive information may, if not carefully controlled,
be printed in log output which could be visible to unauthorized people and captured in forwarding
applications. This policy disallows using Secrets as environment variables.
spec:
validationFailureAction: Audit
background: true
rules:
- name: secrets-not-from-env-vars
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Secrets must be mounted as volumes, not as environment variables."
pattern:
spec:
containers:
- name: "*"
=(env):
- =(valueFrom):
X(secretKeyRef): "null"
- name: secrets-not-from-envfrom
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Secrets must not come from envFrom statements."
pattern:
spec:
containers:
- name: "*"
=(envFrom):
- X(secretRef): "null"

View File

@@ -0,0 +1,46 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-controlplane-scheduling
labels:
opendesk.eu/security-id: wld-iso-010
annotations:
policies.kyverno.io/title: Restrict control plane scheduling
policies.kyverno.io/subject: Pod
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/description: >-
Scheduling non-system Pods to control plane nodes (which run kubelet) is often undesirable
because it takes away resources from the control plane components and can represent
a possible security threat vector. This policy prevents users from setting a toleration
in a Pod spec which allows running on control plane nodes
with the taint key `node-role.kubernetes.io/master`.
spec:
validationFailureAction: Audit
background: true
rules:
- name: restrict-controlplane-scheduling-master
match:
any:
- resources:
kinds:
- Pod
validate:
message: Pods may not use tolerations which schedule on control plane nodes.
pattern:
spec:
=(tolerations):
- key: "!node-role.kubernetes.io/master"
- name: restrict-controlplane-scheduling-control-plane
match:
any:
- resources:
kinds:
- Pod
validate:
message: Pods may not use tolerations which schedule on control plane nodes.
pattern:
spec:
=(tolerations):
- key: "!node-role.kubernetes.io/control-plane"