All Policies

Ensure Read Only hostPath in CEL expressions

Pods which are allowed to mount hostPath volumes in read/write mode pose a security risk even if confined to a "safe" file system on the host and may escape those confines (see https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts). The only true way to ensure safety is to enforce that all Pods mounting hostPath volumes do so in read only mode. This policy checks all containers for any hostPath volumes and ensures they are explicitly mounted in readOnly mode.

Policy Definition

/other-cel/ensure-readonly-hostpath/ensure-readonly-hostpath.yaml

 1apiVersion: kyverno.io/v1
 2kind: ClusterPolicy
 3metadata:
 4  name: ensure-readonly-hostpath
 5  annotations:
 6    policies.kyverno.io/title: Ensure Read Only hostPath in CEL expressions
 7    policies.kyverno.io/category: Other in CEL 
 8    policies.kyverno.io/severity: medium
 9    policies.kyverno.io/minversion: 1.11.0
10    kyverno.io/kyverno-version: 1.11.0
11    kyverno.io/kubernetes-version: "1.26-1.27"
12    policies.kyverno.io/subject: Pod
13    policies.kyverno.io/description: >-
14      Pods which are allowed to mount hostPath volumes in read/write mode pose a security risk
15      even if confined to a "safe" file system on the host and may escape those confines (see
16      https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts). The only true way
17      to ensure safety is to enforce that all Pods mounting hostPath volumes do so in read only
18      mode. This policy checks all containers for any hostPath volumes and ensures they are
19      explicitly mounted in readOnly mode.      
20spec:
21  background: false
22  validationFailureAction: Audit
23  rules:
24  - name: ensure-hostpaths-readonly
25    match:
26      any:
27      - resources:
28          kinds:
29            - Pod
30    validate:
31      cel:
32        variables:
33          - name: allContainers
34            expression: "(object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []))"
35          - name: hostPathVolumes
36            expression: "has(object.spec.volumes) ? object.spec.volumes.filter(volume, has(volume.hostPath)) : []"
37        expressions:
38          - expression: >-
39              variables.hostPathVolumes.all(hostPath, variables.allContainers.all(container, 
40              !has(container.volumeMounts) || 
41              container.volumeMounts.all(volume, (hostPath.name != volume.name) || has(volume.readOnly) && volume.readOnly == true)))              
42            message: All hostPath volumes must be mounted as readOnly.
43