Compare commits

...

2 Commits

Author SHA1 Message Date
Sebastian Kawelke
ac712f4063 Adds further kyverno policies
Signed-off-by: Sebastian Kawelke <sebastian.kawelke@l3montree.com>
2025-12-03 11:48:43 +01:00
Sebastian Kawelke
56ddb422ca Adds sec context and workload isolation kyverno checks
Signed-off-by: Sebastian Kawelke <sebastian.kawelke@l3montree.com>
2025-12-01 13:33:13 +01:00
55 changed files with 2231 additions and 0 deletions

5
.gitignore vendored
View File

@@ -28,3 +28,8 @@ logs
# Ignore backup files, e.g. created by the script that eases the local chart development # Ignore backup files, e.g. created by the script that eases the local chart development
*.bak *.bak
rendered.yaml
pol.yaml
.DS_Store

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

@@ -0,0 +1,20 @@
apiVersion: kyverno.io/v2
kind: PolicyException
metadata:
name: postfix-exception
namespace: opendesk
spec:
exceptions:
- policyName: require-run-as-non-root-user
ruleNames:
- run-as-non-root-user
- autogen-run-as-non-root-user
match:
any:
- resources:
kinds:
- Deployment
namespaces:
- opendesk
names:
- postfix

View File

@@ -0,0 +1,66 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
name: sec-ctx
policies:
- sec-ctx-001_disallow-privileged-containers.yaml
- sec-ctx-002_require-as-non-root.yaml
- sec-ctx-003_run-as-user.yaml
- sec-ctx-004_capabilities.yaml
- sec-ctx-005_seccomp.yaml
- sec-ctx-006_sysctl.yaml
- sec-ctx-007_apparmor.yaml
- sec-ctx-008_selinux.yaml
- sec-ctx-009_proc-mount.yaml
- sec-ctx-010_privilege-escalation.yaml
resources:
- ../../../rendered.yaml
exceptions:
- exceptions/postfix-exception.yaml
results:
# sec-ctx-001
- policy: disallow-privileged-containers
rule: privileged-containers
result: pass
# sec-ctx-002
- policy: require-run-as-nonroot
rule: run-as-non-root
result: pass
# sec-ctx-003
- policy: require-run-as-non-root-user
rule: run-as-non-root-user
result: pass
# sec-ctx-004
- policy: disallow-capabilities-strict
rule: require-drop-all
result: pass
- policy: disallow-capabilities-strict
rule: adding-capabilities-strict
result: pass
# sec-ctx-005
- policy: restrict-seccomp-strict
rule: check-seccomp-strict
result: pass
# sec-ctx-006
- policy: restrict-sysctls
rule: check-sysctls
result: pass
# sec-ctx-007
- policy: restrict-apparmor-profiles
rule: app-armor
result: pass
# sec-ctx-008
- policy: disallow-selinux
rule: selinux-type
result: pass
- policy: disallow-selinux
rule: selinux-user-role
result: pass
# sec-ctx-009
- policy: disallow-proc-mount
rule: check-proc-mount
result: pass
# sec-ctx-010
- policy: disallow-privilege-escalation
rule: privilege-escalation
result: pass

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:
labels:
opendesk.eu/security-id: sec-ctx-001
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/description: Privileged mode disables most security mechanisms
and must not be allowed. This policy ensures Pods do not call for privileged
mode.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Disallow Privileged Containers
name: disallow-privileged-containers
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: privileged-containers
validate:
message: Privileged mode is disallowed. The fields spec.containers[*].securityContext.privileged,
spec.initContainers[*].securityContext.privileged, and spec.ephemeralContainers[*].securityContext.privileged
must be unset or set to `false`.
pattern:
spec:
=(ephemeralContainers):
- =(securityContext):
=(privileged): "false"
=(initContainers):
- =(securityContext):
=(privileged): "false"
containers:
- =(securityContext):
=(privileged): "false"
validationFailureAction: Audit

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:
labels:
opendesk.eu/security-id: sec-ctx-002
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/description: Containers must be required to run as non-root
users. This policy ensures `runAsNonRoot` is set to `true`. A known issue prevents
a policy such as this using `anyPattern` from being persisted properly in Kubernetes
1.23.0-1.23.2.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Require runAsNonRoot
name: require-run-as-nonroot
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: run-as-non-root
validate:
anyPattern:
- spec:
=(ephemeralContainers):
- =(securityContext):
=(runAsNonRoot): "true"
=(initContainers):
- =(securityContext):
=(runAsNonRoot): "true"
containers:
- =(securityContext):
=(runAsNonRoot): "true"
securityContext:
runAsNonRoot: "true"
- spec:
=(ephemeralContainers):
- securityContext:
runAsNonRoot: "true"
=(initContainers):
- securityContext:
runAsNonRoot: "true"
containers:
- securityContext:
runAsNonRoot: "true"
message: Running as root is not allowed. Either the field spec.securityContext.runAsNonRoot
must be set to `true`, or the fields spec.containers[*].securityContext.runAsNonRoot,
spec.initContainers[*].securityContext.runAsNonRoot, and spec.ephemeralContainers[*].securityContext.runAsNonRoot
must be set to `true`.
validationFailureAction: Audit

View File

@@ -0,0 +1,45 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
labels:
opendesk.eu/security-id: sec-ctx-003
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/description: Containers must be required to run as non-root
users. This policy ensures `runAsUser` is either unset or set to a number greater
than zero.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Require Run As Non-Root User
name: require-run-as-non-root-user
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: run-as-non-root-user
validate:
message: Running as root is not allowed. The fields spec.securityContext.runAsUser,
spec.containers[*].securityContext.runAsUser, spec.initContainers[*].securityContext.runAsUser,
and spec.ephemeralContainers[*].securityContext.runAsUser must be unset or
set to a number greater than zero.
pattern:
spec:
=(ephemeralContainers):
- =(securityContext):
=(runAsUser): '>0'
=(initContainers):
- =(securityContext):
=(runAsUser): '>0'
=(securityContext):
=(runAsUser): '>0'
containers:
- =(securityContext):
=(runAsUser): '>0'
validationFailureAction: Audit

View File

@@ -0,0 +1,120 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
labels:
opendesk.eu/security-id: sec-ctx-004
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/description: Adding capabilities beyond those listed in the
policy must be disallowed.
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Disallow Capabilities
name: disallow-capabilities
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: adding-capabilities
preconditions:
all:
- key: '{{ request.operation || ''BACKGROUND'' }}'
operator: NotEquals
value: DELETE
validate:
deny:
conditions:
all:
- key: '{{ request.object.spec.[ephemeralContainers, initContainers, containers][].securityContext.capabilities.add[]
}}'
operator: AnyNotIn
value:
- AUDIT_WRITE
- CHOWN
- DAC_OVERRIDE
- FOWNER
- FSETID
- KILL
- MKNOD
- NET_BIND_SERVICE
- SETFCAP
- SETGID
- SETPCAP
- SETUID
- SYS_CHROOT
message: Any capabilities added beyond the allowed list (AUDIT_WRITE, CHOWN,
DAC_OVERRIDE, FOWNER, FSETID, KILL, MKNOD, NET_BIND_SERVICE, SETFCAP, SETGID,
SETPCAP, SETUID, SYS_CHROOT) are disallowed.
validationFailureAction: Audit
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
labels:
opendesk.eu/security-id: sec-ctx-001
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/description: Adding capabilities other than `NET_BIND_SERVICE`
is disallowed. In addition, all containers must explicitly drop `ALL` capabilities.
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Disallow Capabilities (Strict)
name: disallow-capabilities-strict
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: require-drop-all
preconditions:
all:
- key: '{{ request.operation || ''BACKGROUND'' }}'
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.
- match:
any:
- resources:
kinds:
- Pod
name: adding-capabilities-strict
preconditions:
all:
- key: '{{ request.operation || ''BACKGROUND'' }}'
operator: NotEquals
value: DELETE
validate:
foreach:
- deny:
conditions:
all:
- key: '{{ element.securityContext.capabilities.add[] || `[]` }}'
operator: AnyNotIn
value:
- NET_BIND_SERVICE
- ""
list: request.object.spec.[ephemeralContainers, initContainers, containers][]
message: Any capabilities added other than NET_BIND_SERVICE are disallowed.
validationFailureAction: Audit

View File

@@ -0,0 +1,113 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
labels:
opendesk.eu/security-id: sec-ctx-005
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/description: The seccomp profile must not be explicitly set
to Unconfined. This policy, requiring Kubernetes v1.19 or later, ensures that
seccomp is unset or set to `RuntimeDefault` or `Localhost`.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Restrict Seccomp
name: restrict-seccomp
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: check-seccomp
validate:
message: Use of custom Seccomp profiles is disallowed. The fields spec.securityContext.seccompProfile.type,
spec.containers[*].securityContext.seccompProfile.type, spec.initContainers[*].securityContext.seccompProfile.type,
and spec.ephemeralContainers[*].securityContext.seccompProfile.type must be
unset or set to `RuntimeDefault` or `Localhost`.
pattern:
spec:
=(ephemeralContainers):
- =(securityContext):
=(seccompProfile):
=(type): RuntimeDefault | Localhost
=(initContainers):
- =(securityContext):
=(seccompProfile):
=(type): RuntimeDefault | Localhost
=(securityContext):
=(seccompProfile):
=(type): RuntimeDefault | Localhost
containers:
- =(securityContext):
=(seccompProfile):
=(type): RuntimeDefault | Localhost
validationFailureAction: Audit
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
labels:
opendesk.eu/security-id: sec-ctx-005
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/description: The seccomp profile in the Restricted group must
not be explicitly set to Unconfined but additionally must also not allow an
unset value. This policy, requiring Kubernetes v1.19 or later, ensures that
seccomp is set to `RuntimeDefault` or `Localhost`. A known issue prevents a
policy such as this using `anyPattern` from being persisted properly in Kubernetes
1.23.0-1.23.2.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Restrict Seccomp (Strict)
name: restrict-seccomp-strict
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: check-seccomp-strict
validate:
anyPattern:
- spec:
=(ephemeralContainers):
- =(securityContext):
=(seccompProfile):
=(type): RuntimeDefault | Localhost
=(initContainers):
- =(securityContext):
=(seccompProfile):
=(type): RuntimeDefault | Localhost
containers:
- =(securityContext):
=(seccompProfile):
=(type): RuntimeDefault | Localhost
securityContext:
seccompProfile:
type: RuntimeDefault | Localhost
- spec:
=(ephemeralContainers):
- securityContext:
seccompProfile:
type: RuntimeDefault | Localhost
=(initContainers):
- securityContext:
seccompProfile:
type: RuntimeDefault | Localhost
containers:
- securityContext:
seccompProfile:
type: RuntimeDefault | Localhost
message: Use of custom Seccomp profiles is disallowed. The fields spec.securityContext.seccompProfile.type,
spec.containers[*].securityContext.seccompProfile.type, spec.initContainers[*].securityContext.seccompProfile.type,
and spec.ephemeralContainers[*].securityContext.seccompProfile.type must be
set to `RuntimeDefault` or `Localhost`.
validationFailureAction: Audit

View File

@@ -0,0 +1,39 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
labels:
opendesk.eu/security-id: sec-ctx-006
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/description: Sysctls can disable security mechanisms or affect
all containers on a host, and should be disallowed except for an allowed "safe"
subset. A sysctl is considered safe if it is namespaced in the container or
the Pod, and it is isolated from other Pods or processes on the same Node. This
policy ensures that only those "safe" subsets can be specified in a Pod.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Restrict sysctls
name: restrict-sysctls
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: check-sysctls
validate:
message: Setting additional sysctls above the allowed type is disallowed. The
field spec.securityContext.sysctls must be unset or not use any other names
than kernel.shm_rmid_forced, net.ipv4.ip_local_port_range, net.ipv4.ip_unprivileged_port_start,
net.ipv4.tcp_syncookies and net.ipv4.ping_group_range.
pattern:
spec:
=(securityContext):
=(sysctls):
- =(name): kernel.shm_rmid_forced | net.ipv4.ip_local_port_range | net.ipv4.ip_unprivileged_port_start | net.ipv4.tcp_syncookies | net.ipv4.ping_group_range
validationFailureAction: Audit

View File

@@ -0,0 +1,38 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
labels:
opendesk.eu/security-id: sec-ctx-007
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/description: On supported hosts, the 'runtime/default' AppArmor
profile is applied by default. The default policy should prevent overriding
or disabling the policy, or restrict overrides to an allowed set of profiles.
This policy ensures Pods do not specify any other AppArmor profiles than `runtime/default`
or `localhost/*`.
policies.kyverno.io/minversion: 1.3.0
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod, Annotation
policies.kyverno.io/title: Restrict AppArmor
name: restrict-apparmor-profiles
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: app-armor
validate:
message: Specifying other AppArmor profiles is disallowed. The annotation `container.apparmor.security.beta.kubernetes.io`
if defined must not be set to anything other than `runtime/default` or `localhost/*`.
pattern:
=(metadata):
=(annotations):
=(container.apparmor.security.beta.kubernetes.io/*): runtime/default |
localhost/*
validationFailureAction: Audit

View File

@@ -0,0 +1,84 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
labels:
opendesk.eu/security-id: sec-ctx-008
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/description: SELinux options can be used to escalate privileges
and should not be allowed. This policy ensures that the `seLinuxOptions` field
is undefined.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Disallow SELinux
name: disallow-selinux
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: selinux-type
validate:
message: Setting the SELinux type is restricted. The fields spec.securityContext.seLinuxOptions.type,
spec.containers[*].securityContext.seLinuxOptions.type, , spec.initContainers[*].securityContext.seLinuxOptions,
and spec.ephemeralContainers[*].securityContext.seLinuxOptions.type must either
be unset or set to one of the allowed values (container_t, container_init_t,
or container_kvm_t).
pattern:
spec:
=(ephemeralContainers):
- =(securityContext):
=(seLinuxOptions):
=(type): container_t | container_init_t | container_kvm_t
=(initContainers):
- =(securityContext):
=(seLinuxOptions):
=(type): container_t | container_init_t | container_kvm_t
=(securityContext):
=(seLinuxOptions):
=(type): container_t | container_init_t | container_kvm_t
containers:
- =(securityContext):
=(seLinuxOptions):
=(type): container_t | container_init_t | container_kvm_t
- match:
any:
- resources:
kinds:
- Pod
name: selinux-user-role
validate:
message: Setting the SELinux user or role is forbidden. The fields spec.securityContext.seLinuxOptions.user,
spec.securityContext.seLinuxOptions.role, spec.containers[*].securityContext.seLinuxOptions.user,
spec.containers[*].securityContext.seLinuxOptions.role, spec.initContainers[*].securityContext.seLinuxOptions.user,
spec.initContainers[*].securityContext.seLinuxOptions.role, spec.ephemeralContainers[*].securityContext.seLinuxOptions.user,
and spec.ephemeralContainers[*].securityContext.seLinuxOptions.role must be
unset.
pattern:
spec:
=(ephemeralContainers):
- =(securityContext):
=(seLinuxOptions):
X(role): "null"
X(user): "null"
=(initContainers):
- =(securityContext):
=(seLinuxOptions):
X(role): "null"
X(user): "null"
=(securityContext):
=(seLinuxOptions):
X(role): "null"
X(user): "null"
containers:
- =(securityContext):
=(seLinuxOptions):
X(role): "null"
X(user): "null"
validationFailureAction: Audit

View File

@@ -0,0 +1,44 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
labels:
opendesk.eu/security-id: sec-ctx-009
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/description: The default /proc masks are set up to reduce
attack surface and should be required. This policy ensures nothing but the default
procMount can be specified. Note that in order for users to deviate from the
`Default` procMount requires setting a feature gate at the API server.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Disallow procMount
name: disallow-proc-mount
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: check-proc-mount
validate:
message: Changing the proc mount from the default is not allowed. The fields
spec.containers[*].securityContext.procMount, spec.initContainers[*].securityContext.procMount,
and spec.ephemeralContainers[*].securityContext.procMount must be unset or
set to `Default`.
pattern:
spec:
=(ephemeralContainers):
- =(securityContext):
=(procMount): Default
=(initContainers):
- =(securityContext):
=(procMount): Default
containers:
- =(securityContext):
=(procMount): Default
validationFailureAction: Audit

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:
labels:
opendesk.eu/security-id: sec-ctx-010
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/description: Privilege escalation, such as via set-user-ID
or set-group-ID file mode, should not be allowed. This policy ensures the `allowPrivilegeEscalation`
field is set to `false`.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Disallow Privilege Escalation
name: disallow-privilege-escalation
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: privilege-escalation
validate:
message: Privilege escalation is disallowed. The fields spec.containers[*].securityContext.allowPrivilegeEscalation,
spec.initContainers[*].securityContext.allowPrivilegeEscalation, and spec.ephemeralContainers[*].securityContext.allowPrivilegeEscalation
must be set to `false`.
pattern:
spec:
=(ephemeralContainers):
- securityContext:
allowPrivilegeEscalation: "false"
=(initContainers):
- securityContext:
allowPrivilegeEscalation: "false"
containers:
- securityContext:
allowPrivilegeEscalation: "false"
validationFailureAction: Audit

View File

@@ -0,0 +1,18 @@
## Pod & Container Security Context
| ID | Description | References |
|---|---|---|
| SEC-CTX-001 | Pods must run non **privileged** only to prevent excessive rights and to make persistence and further escalation more difficult. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| SEC-CTX-002 | All Containers of a pod (containers, Init-Containers and Epehmeral-Containers) must run as non-root user (**runAsNonRoot**) to make persistence and further escalation more difficult. Given a justification and only if the necessary containers of the pod set this setting to false, while all other containers keep this setting set to true, this requirement may be violated. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| SEC-CTX-003 | All containers of a pod (containers, init-containers and ephemeral-containers) must not explicitly set runAsUser to 0 (root). The **runAsUser** field must either be undefined/null or set to a non-zero UID to ensure containers run with non-root privileges and reduce the risk of privilege escalation attacks. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| SEC-CTX-004 | All containers of a pod (containers, init-containers and ephemeral-containers) must drop `ALL` **capabilities** and may only add back the `NET_BIND_SERVICE` capability to follow the principle of least privilege and minimize the attack surface. This supports preventing containers from performing privileged system operations that could lead to container escape or host compromise. Given a justification, it is tolerated to add back the followingcapabilities: `AUDIT_WRITE`, `CHOWN`, `DAC_OVERRIDE`, `FOWNER`, `FSETID`, `KILL`, `MKNOD`, `SETFCAP`, `SETGID`, `SETPCAP`, `SETUID`, `SYS_CHROOT` | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| SEC-CTX-005 | All containers of a pod (containers, init-containers and ephemeral-containers) must have a **Seccomp** profile explicitly set to either `RuntimeDefault` or `Localhost` to restrict system calls and reduce the kernel attack surface. The Unconfined profile and absence of a profile are prohibited. Container-level `seccompProfile.type` fields may be undefined only if the pod-level `seccompProfile.type` is set appropriately, and conversely, the pod-level field may be undefined only if all container-level fields are set. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| SEC-CTX-006 | Pods must only use sysctls from an allowed safe list that are namespaced and isolated from other pods and processes on the same node. Only the following **sysctls** are permitted: `kernel.shm_rmid_forced`, `net.ipv4.ip_local_port_range`, `net.ipv4.ip_unprivileged_port_start`, `net.ipv4.tcp_syncookies`, `net.ipv4.ping_group_range`, `net.ipv4.ip_local_reserved_ports`, `net.ipv4.tcp_keepalive_time`, `net.ipv4.tcp_fin_timeout`, `net.ipv4.tcp_keepalive_intvl`, and `net.ipv4.tcp_keepalive_probes`. All other sysctls are prohibited as they can disable security mechanisms or affect all containers on the host. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| SEC-CTX-007 | On **AppArmor**-supported hosts, all containers of a pod (containers, init-containers and ephemeral-containers) must use the `RuntimeDefault` AppArmor profile or a locally defined profile (`Localhost`). The Unconfined profile is prohibited. Containers may only override the default AppArmor profile with `RuntimeDefault` or `Localhost` profiles. Undefined/nil values are permitted to inherit the runtimes default behavior. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| SEC-CTX-008 | On **SELinux**-enabled hosts, all containers of a pod (containers, init-containers and ephemeral-containers) must only use approved SELinux types (`container_t`, `container_init_t`, `container_kvm_t`, or `container_engine_t`) and are prohibited from setting custom SELinux users or roles. The `seLinux-Options.user` and `seLinuxOptions.role` fields must remain undefined or empty to prevent privilege escalation through SELinux context manipulation. This ensures containers operate within predefined SELinux security boundaries. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| SEC-CTX-009 | All containers of a pod (containers, init-containers and ephemeral-containers) must use the default **`/proc`** mount type with standard masking to reduce the kernel attack surface. The `procMount` field must be either undefined/nil or explicitly set to `Default`. The Unmasked option is prohibited to prevent containers from accessing sensitive kernel information through `/proc` that could be used for container escape or information disclosure attacks. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| SEC-CTX-010 | All containers of a pod (containers, init-containers and ephemeral-containers) must set **`allowPrivilegeEscalation`** to false to prevent privilege escalation through setuid or setgid binaries. This blocks containers from gaining more privileges than their parent process and prevents exploitation of setuid/setgid executables that could lead to container escape or unauthorized privilege elevation. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
### Status
{{ .sec-ctx.status }}

View File

@@ -0,0 +1,77 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
name: wld-iso
policies:
- wld-iso-001_host-namespaces.yaml
- wld-iso-002_hostpath-volumes.yaml
- 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: []
results:
# wld-iso-001
- policy: disallow-host-namespaces
rule: host-namespaces
result: pass
# wld-iso-002
- policy: disallow-host-path
rule: host-path
result: pass
# wld-iso-003
- policy: disallow-host-ports
rule: host-ports-none
result: pass
# wld-iso-004
- policy: disallow-host-probes-lifecycle
rule: host-probes-lifecycle
result: pass
# 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,37 @@
# Source: https://github.com/kyverno/policies/tree/main/pod-security
# License: Apache-2.0
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
labels:
opendesk.eu/security-id: wld-iso-001
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/description: Host namespaces (Process ID namespace, Inter-Process
Communication namespace, and network namespace) allow access to shared information
and can be used to elevate privileges. Pods should not be allowed access to
host namespaces. This policy ensures fields which make use of these host namespaces
are unset or set to `false`.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Disallow Host Namespaces
name: disallow-host-namespaces
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: host-namespaces
validate:
message: Sharing the host namespaces is disallowed. The fields spec.hostNetwork,
spec.hostIPC, and spec.hostPID must be unset or set to `false`.
pattern:
spec:
=(hostIPC): "false"
=(hostNetwork): "false"
=(hostPID): "false"
validationFailureAction: Audit

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:
labels:
opendesk.eu/security-id: wld-iso-002
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/description: HostPath volumes let Pods use host directories
and volumes in containers. Using host resources can be used to access shared
data or escalate privileges and should not be allowed. This policy ensures no
hostPath volumes are in use.
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod,Volume
policies.kyverno.io/title: Disallow hostPath
name: disallow-host-path
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: host-path
validate:
message: HostPath volumes are forbidden. The field spec.volumes[*].hostPath
must be unset.
pattern:
spec:
=(volumes):
- X(hostPath): "null"
validationFailureAction: Audit

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:
labels:
opendesk.eu/security-id: wld-iso-003
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/description: 'Access to host ports allows potential snooping
of network traffic and should not be allowed, or at minimum restricted to a
known list. This policy ensures the `hostPort` field is unset or set to `0`. '
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/title: Disallow hostPorts
name: disallow-host-ports
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: host-ports-none
validate:
message: Use of host ports is disallowed. The fields spec.containers[*].ports[*].hostPort
, spec.initContainers[*].ports[*].hostPort, and spec.ephemeralContainers[*].ports[*].hostPort
must either be unset or set to `0`.
pattern:
spec:
=(ephemeralContainers):
- =(ports):
- =(hostPort): 0
=(initContainers):
- =(ports):
- =(hostPort): 0
containers:
- =(ports):
- =(hostPort): 0
validationFailureAction: Audit

View File

@@ -0,0 +1,115 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-host-probes-lifecycle
labels:
opendesk.eu/security-id: wld-iso-004
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/title: Disallow Host in Probes and Lifecycle Hooks
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/description: >-
The host field in probes and lifecycle hooks allows bypassing network
policies by directing traffic to arbitrary hosts. This policy ensures
that the host field in livenessProbe, readinessProbe, startupProbe,
and lifecycle hooks (postStart/preStop) is either undefined or empty
for both containers and initContainers.
spec:
validationFailureAction: Audit
background: true
rules:
- name: host-probes-lifecycle
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
The host field in probes and lifecycle hooks must be undefined or empty.
pattern:
spec:
=(initContainers):
- =(livenessProbe):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(readinessProbe):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(startupProbe):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(lifecycle):
=(postStart):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(preStop):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(ephemeralContainers):
- =(livenessProbe):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(readinessProbe):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(startupProbe):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(lifecycle):
=(postStart):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(preStop):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(containers):
- =(livenessProbe):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(readinessProbe):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(startupProbe):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(lifecycle):
=(postStart):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""
=(preStop):
=(httpGet):
=(host): ""
=(tcpSocket):
=(host): ""

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:
labels:
opendesk.eu/security-id: wld-iso-005
annotations:
kyverno.io/kyverno-version: 1.6.0
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/description: In addition to restricting HostPath volumes,
the restricted pod security profile limits usage of non-core volume types to
those defined through PersistentVolumes. This policy blocks any other type of
volume other than those in the allow list.
policies.kyverno.io/minversion: 1.6.0
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod,Volume
policies.kyverno.io/title: Restrict Volume Types
name: restrict-volume-types
spec:
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
name: restricted-volumes
preconditions:
all:
- key: '{{ request.operation || ''BACKGROUND'' }}'
operator: NotEquals
value: DELETE
validate:
deny:
conditions:
all:
- key: '{{ request.object.spec.volumes[].keys(@)[] || '''' }}'
operator: AnyNotIn
value:
- name
- configMap
- csi
- downwardAPI
- emptyDir
- ephemeral
- persistentVolumeClaim
- projected
- secret
- ""
message: 'Only the following types of volumes may be used: configMap, csi, downwardAPI,
emptyDir, ephemeral, persistentVolumeClaim, projected, and secret.'
validationFailureAction: Audit

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"

View File

@@ -0,0 +1,14 @@
## Workload Isolation and Configuration
| ID | Description | References |
|---|---|---|
| WLD-ISO-001 | Pods must not share **host namespaces** (`hostNetwork`, `hostPID`, `hostIPC`). These fields must be undefined/nil or explicitly set to false to prevent containers from accessing host network interfaces, process trees, or inter-process communication mechanisms, which could lead to container escape or unauthorized access to host resources. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| WLD-ISO-002 | **HostPath volumes** must be forbidden (`spec.volumes[*].hostPath` must be undefined/nil) to prevent containers from mounting directories from the host filesystem, which could enable unauthorized access to sensitive host files, container escape, or persistence mechanisms on the node. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| WLD-ISO-003 | **Host ports** must be disallowed. The `hostPort` field in all containers (containers, init-containers, and ephemeral-containers) must be undefined/nil or set to 0 to prevent bypassing network policies and exposing services directly on the host network interface, which could lead to unauthorized access or port conflicts. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| WLD-ISO-004 | The **host field in probes and lifecycle hooks** must be undefined/nil or empty string for all containers (containers and init-containers). This prevents probes and hooks from targeting the host network directly, maintaining proper network isolation between containers and the host system. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
| WLD-VOL-001 | Pods must only use **approved volume types** that maintain security boundaries. Permitted volume types are: `configMap`, `csi`, `downwardAPI`, `emptyDir`, `ephemeral`, `persistentVolumeClaim`, `projected`, and `secret`. All other volume types, particularly those that break isolation boundaries (`hostPath`, etc.), are prohibited to prevent unauthorized access to host resources or external systems. | K8s-PSS, BSI-SYS-1-6, OWASP-K8s, NIST-SP, NSA-Hardening |
### Status
{{ .wld-iso.status }}