diff --git a/pod-security/baseline/disallow-capabilities/deployment.yaml b/pod-security/baseline/disallow-capabilities/deployment.yaml new file mode 100644 index 00000000..c563cb38 --- /dev/null +++ b/pod-security/baseline/disallow-capabilities/deployment.yaml @@ -0,0 +1,25 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox + command: + - "sleep" + - "3600" + securityContext: + capabilities: + add: + - SYS_ADMIN + - NET_RAW diff --git a/pod-security/baseline/disallow-capabilities/disallow-capabilities.yaml b/pod-security/baseline/disallow-capabilities/disallow-capabilities.yaml index 7141d276..8a1c2c6f 100644 --- a/pod-security/baseline/disallow-capabilities/disallow-capabilities.yaml +++ b/pod-security/baseline/disallow-capabilities/disallow-capabilities.yaml @@ -10,6 +10,7 @@ metadata: kyverno.io/kubernetes-version: "1.22-1.23" policies.kyverno.io/subject: Pod policies.nirmata.io/remediation-docs: "https://docs.nirmata.io/policysets/podsecurity/baseline/disallow-capabilities/" + policies.nirmata.io/remediation: "https://github.com/nirmata/kyverno-policies/tree/main/pod-security/baseline/disallow-capabilities/remediate-disallow-capabilities.yaml" policies.kyverno.io/description: >- Any additional capabilities not mentioned in the allowed list, which includes AUDIT_WRITE, CHOWN, DAC_OVERRIDE, FOWNER, FSETID, KILL, MKNOD, NET_BIND_SERVICE, SETFCAP, SETGID, SETPCAP, SETUID, SYS_CHROOT, are prohibited and not permitted. spec: diff --git a/pod-security/baseline/disallow-capabilities/e2e/chainsaw-test.yaml b/pod-security/baseline/disallow-capabilities/e2e/chainsaw-test.yaml index 1d083cf6..94be206f 100644 --- a/pod-security/baseline/disallow-capabilities/e2e/chainsaw-test.yaml +++ b/pod-security/baseline/disallow-capabilities/e2e/chainsaw-test.yaml @@ -10,6 +10,26 @@ spec: file: ../disallow-capabilities.yaml - assert: file: policy-assert.yaml + - apply: + file: ../remediate-disallow-capabilities.yaml + - assert: + file: remediation-policy-assert.yaml + - apply: + file: ../deployment.yaml + - sleep: + duration: 20s + - assert: + resource: + apiVersion: wgpolicyk8s.io/v1alpha2 + kind: PolicyReport + summary: + error: 0 + fail: 0 + - delete: + ref: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: remediate-disallow-capabilities - script: content: | sed 's/validationFailureAction: Audit/validationFailureAction: Enforce/' ../disallow-capabilities.yaml | kubectl apply -f - diff --git a/pod-security/baseline/disallow-capabilities/e2e/remediation-policy-assert.yaml b/pod-security/baseline/disallow-capabilities/e2e/remediation-policy-assert.yaml new file mode 100644 index 00000000..5129fb16 --- /dev/null +++ b/pod-security/baseline/disallow-capabilities/e2e/remediation-policy-assert.yaml @@ -0,0 +1,11 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: remediate-disallow-capabilities +spec: + validationFailureAction: Audit +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/pod-security/baseline/disallow-capabilities/remediate-disallow-capabilities.yaml b/pod-security/baseline/disallow-capabilities/remediate-disallow-capabilities.yaml new file mode 100644 index 00000000..efecfc45 --- /dev/null +++ b/pod-security/baseline/disallow-capabilities/remediate-disallow-capabilities.yaml @@ -0,0 +1,139 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: remediate-disallow-capabilities + annotations: + policies.kyverno.io/title: Remediate Capabilities Baseline + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/description: >- + This policy remediates the disallow-capabilities baseline policy by automatically removing any unpermitted capabilities. +spec: + background: false + rules: + - name: remove-unpermitted-capabilities + match: + resources: + kinds: + - Deployment + - StatefulSet + - Job + - DaemonSet + mutate: + foreach: + - list: request.object.spec.template.spec.containers[] + order: Descending + preconditions: + all: + - key: "{{ element.securityContext.capabilities.add[].to_upper(@) || `[]` }}" + operator: AnyNotIn + value: + - AUDIT_WRITE + - CHOWN + - DAC_OVERRIDE + - FOWNER + - FSETID + - KILL + - MKNOD + - NET_BIND_SERVICE + - SETFCAP + - SETGID + - SETPCAP + - SETUID + - SYS_CHROOT + patchesJson6902: |- + - op: remove + path: /spec/template/spec/containers/{{elementIndex}}/securityContext/capabilities/add + - op: add + path: /spec/template/spec/containers/{{elementIndex}}/securityContext/capabilities/add + value: + - AUDIT_WRITE + - CHOWN + - DAC_OVERRIDE + - FOWNER + - FSETID + - KILL + - MKNOD + - NET_BIND_SERVICE + - SETFCAP + - SETGID + - SETPCAP + - SETUID + - SYS_CHROOT + - list: request.object.spec.template.spec.initContainers[] + order: Descending + preconditions: + all: + - key: "{{ element.securityContext.capabilities.add[].to_upper(@) || `[]` }}" + operator: AnyNotIn + value: + - AUDIT_WRITE + - CHOWN + - DAC_OVERRIDE + - FOWNER + - FSETID + - KILL + - MKNOD + - NET_BIND_SERVICE + - SETFCAP + - SETGID + - SETPCAP + - SETUID + - SYS_CHROOT + patchesJson6902: |- + - op: remove + path: /spec/template/spec/initContainers/{{elementIndex}}/securityContext/capabilities/add + - op: add + path: /spec/template/spec/initContainers/{{elementIndex}}/securityContext/capabilities/add + value: + - AUDIT_WRITE + - CHOWN + - DAC_OVERRIDE + - FOWNER + - FSETID + - KILL + - MKNOD + - NET_BIND_SERVICE + - SETFCAP + - SETGID + - SETPCAP + - SETUID + - SYS_CHROOT + - list: request.object.spec.template.spec.ephemeralContainers[] + order: Descending + preconditions: + all: + - key: "{{ element.securityContext.capabilities.add[].to_upper(@) || `[]` }}" + operator: AnyNotIn + value: + - AUDIT_WRITE + - CHOWN + - DAC_OVERRIDE + - FOWNER + - FSETID + - KILL + - MKNOD + - NET_BIND_SERVICE + - SETFCAP + - SETGID + - SETPCAP + - SETUID + - SYS_CHROOT + patchesJson6902: |- + - op: remove + path: /spec/template/spec/ephemeralContainers/{{elementIndex}}/securityContext/capabilities/add + - op: add + path: /spec/template/spec/ephemeralContainers/{{elementIndex}}/securityContext/capabilities/add + value: + - AUDIT_WRITE + - CHOWN + - DAC_OVERRIDE + - FOWNER + - FSETID + - KILL + - MKNOD + - NET_BIND_SERVICE + - SETFCAP + - SETGID + - SETPCAP + - SETUID + - SYS_CHROOT diff --git a/pod-security/restricted/require-run-as-non-root-user/deployment.yaml b/pod-security/restricted/require-run-as-non-root-user/deployment.yaml new file mode 100644 index 00000000..cfe466f8 --- /dev/null +++ b/pod-security/restricted/require-run-as-non-root-user/deployment.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment02 +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + securityContext: + runAsUser: 0 + containers: + - name: container01 + image: busybox + command: + - "sleep" + - "3600" + securityContext: + runAsUser: 0 diff --git a/pod-security/restricted/require-run-as-non-root-user/e2e/chainsaw-test.yaml b/pod-security/restricted/require-run-as-non-root-user/e2e/chainsaw-test.yaml index 51669bd7..f7967c56 100644 --- a/pod-security/restricted/require-run-as-non-root-user/e2e/chainsaw-test.yaml +++ b/pod-security/restricted/require-run-as-non-root-user/e2e/chainsaw-test.yaml @@ -10,6 +10,26 @@ spec: file: ../require-run-as-non-root-user.yaml - assert: file: policy-assert.yaml + - apply: + file: ../remediate-require-run-as-non-root-user.yaml + - assert: + file: remediation-policy-assert.yaml + - apply: + file: ../deployment.yaml + - sleep: + duration: 20s + - assert: + resource: + apiVersion: wgpolicyk8s.io/v1alpha2 + kind: PolicyReport + summary: + error: 0 + fail: 0 + - delete: + ref: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: remediate-require-run-as-non-root-user - script: content: | sed 's/validationFailureAction: Audit/validationFailureAction: Enforce/' ../require-run-as-non-root-user.yaml | kubectl apply -f - diff --git a/pod-security/restricted/require-run-as-non-root-user/e2e/remediation-policy-assert.yaml b/pod-security/restricted/require-run-as-non-root-user/e2e/remediation-policy-assert.yaml new file mode 100644 index 00000000..6e2a7fb4 --- /dev/null +++ b/pod-security/restricted/require-run-as-non-root-user/e2e/remediation-policy-assert.yaml @@ -0,0 +1,11 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: remediate-require-run-as-non-root-user +spec: + validationFailureAction: Audit +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/pod-security/restricted/require-run-as-non-root-user/remediate-require-run-as-non-root-user.yaml b/pod-security/restricted/require-run-as-non-root-user/remediate-require-run-as-non-root-user.yaml new file mode 100644 index 00000000..5c0b2082 --- /dev/null +++ b/pod-security/restricted/require-run-as-non-root-user/remediate-require-run-as-non-root-user.yaml @@ -0,0 +1,53 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: remediate-require-run-as-non-root-user + annotations: + policies.kyverno.io/title: Require Run As Non-Root User + policies.kyverno.io/category: Pod Security Standards (Restricted) + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + kyverno.io/kyverno-version: 1.6.0 + kyverno.io/kubernetes-version: "1.22-1.23" + policies.kyverno.io/description: >- + Containers must be required to run as non-root users. This policy mutates the field + spec.securityContext.runAsUser to a value greater than zero, + and the fields spec.containers[*].securityContext.runAsUser, + spec.initContainers[*].securityContext.runAsUser, and spec.ephemeralContainers[*].securityContext.runAsUser + if exists, is set to a non-zero value. +spec: + background: false + rules: + - name: add-run-as-non-root-user + match: + any: + - resources: + kinds: + - Deployment + - StatefulSet + - Job + - DaemonSet + mutate: + foreach: + - list: "request.object.spec.template.spec.[containers, initContainers, ephemeralContainers][]" + patchStrategicMerge: + spec: + template: + spec: + securityContext: + runAsUser: 1000 + containers: + - (name): "{{ element.name }}" + securityContext: + (runAsUser): 0 + runAsUser: 1000 + initContainers: + - (name): "{{ element.name }}" + securityContext: + (runAsUser): 0 + runAsUser: 1000 + ephemeralContainers: + - (name): "{{ element.name }}" + securityContext: + (runAsUser): 0 + runAsUser: 1000 diff --git a/pod-security/restricted/require-run-as-non-root-user/require-run-as-non-root-user.yaml b/pod-security/restricted/require-run-as-non-root-user/require-run-as-non-root-user.yaml index b522f336..6f69c992 100644 --- a/pod-security/restricted/require-run-as-non-root-user/require-run-as-non-root-user.yaml +++ b/pod-security/restricted/require-run-as-non-root-user/require-run-as-non-root-user.yaml @@ -9,6 +9,7 @@ metadata: policies.kyverno.io/subject: Pod kyverno.io/kubernetes-version: "1.22-1.23" policies.nirmata.io/remediation-docs: "https://docs.nirmata.io/policysets/podsecurity/restricted/require-run-as-non-root-user/" + policies.nirmata.io/remediation: "https://github.com/nirmata/kyverno-policies/tree/main/pod-security/restricted/require-run-as-non-root-user/remediate-require-run-as-non-root-user.yaml" policies.kyverno.io/description: >- Containers must be required to run as non-root users. This policy ensures that the fields spec.securityContext.runAsUser, diff --git a/pod-security/restricted/restrict-seccomp-strict/deployment.yaml b/pod-security/restricted/restrict-seccomp-strict/deployment.yaml new file mode 100644 index 00000000..848df85a --- /dev/null +++ b/pod-security/restricted/restrict-seccomp-strict/deployment.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: baddeployment +spec: + replicas: 1 + selector: + matchLabels: + app: app + template: + metadata: + labels: + app: app + spec: + containers: + - name: container01 + image: busybox + command: + - "sleep" + - "3600" + securityContext: + seccompProfile: + type: Unconfined diff --git a/pod-security/restricted/restrict-seccomp-strict/e2e/chainsaw-test.yaml b/pod-security/restricted/restrict-seccomp-strict/e2e/chainsaw-test.yaml index d785a9a4..c80602f7 100644 --- a/pod-security/restricted/restrict-seccomp-strict/e2e/chainsaw-test.yaml +++ b/pod-security/restricted/restrict-seccomp-strict/e2e/chainsaw-test.yaml @@ -10,6 +10,26 @@ spec: file: ../restrict-seccomp-strict.yaml - assert: file: policy-assert.yaml + - apply: + file: ../remediate-restrict-seccomp-strict.yaml + - assert: + file: remediation-policy-assert.yaml + - apply: + file: ../deployment.yaml + - sleep: + duration: 20s + - assert: + resource: + apiVersion: wgpolicyk8s.io/v1alpha2 + kind: PolicyReport + summary: + error: 0 + fail: 0 + - delete: + ref: + apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: remediate-restrict-seccomp-strict - script: content: | sed 's/validationFailureAction: Audit/validationFailureAction: Enforce/' ../restrict-seccomp-strict.yaml | kubectl apply -f - diff --git a/pod-security/restricted/restrict-seccomp-strict/e2e/remediation-policy-assert.yaml b/pod-security/restricted/restrict-seccomp-strict/e2e/remediation-policy-assert.yaml new file mode 100644 index 00000000..23e67725 --- /dev/null +++ b/pod-security/restricted/restrict-seccomp-strict/e2e/remediation-policy-assert.yaml @@ -0,0 +1,11 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: remediate-restrict-seccomp-strict +spec: + validationFailureAction: Audit +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/pod-security/restricted/restrict-seccomp-strict/remediate-restrict-seccomp-strict.yaml b/pod-security/restricted/restrict-seccomp-strict/remediate-restrict-seccomp-strict.yaml new file mode 100644 index 00000000..70298c53 --- /dev/null +++ b/pod-security/restricted/restrict-seccomp-strict/remediate-restrict-seccomp-strict.yaml @@ -0,0 +1,88 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: remediate-restrict-seccomp-strict + annotations: + annotations: + policies.kyverno.io/title: Restrict Seccomp (Strict) + policies.kyverno.io/category: Pod Security Standards (Restricted) + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + kyverno.io/kubernetes-version: "1.22-1.23" + policies.nirmata.io/remediation-docs: "https://docs.nirmata.io/policysets/podsecurity/restricted/restrict-seccomp-strict/" + 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 the fields + spec.securityContext.seccompProfile.type, + spec.containers[*].securityContext.seccompProfile.type, + spec.initContainers[*].securityContext.seccompProfile.type, and + spec.ephemeralContainers[*].securityContext.seccompProfile.type + 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. +spec: + background: false + rules: + - name: add-seccomp-runtimedefault-containers + match: + any: + - resources: + kinds: + - Deployment + - StatefulSet + - Job + - DaemonSet + mutate: + foreach: + - list: "request.object.spec.template.spec.[containers, initContainers, ephemeralContainers][]" + order: Descending + preconditions: + all: + - key: "{{ element.securityContext.seccompProfile.type || '' }}" + operator: AnyIn + value: "Unconfined" + patchStrategicMerge: + spec: + template: + spec: + containers: + - (name): "{{ element.name }}" + securityContext: + seccompProfile: + (type): "Unconfined" + type: "RuntimeDefault" + initContainers: + - (name): "{{ element.name }}" + securityContext: + seccompProfile: + (type): "Unconfined" + type: "RuntimeDefault" + ephemeralContainers: + - (name): "{{ element.name }}" + securityContext: + seccompProfile: + (type): "Unconfined" + type: "RuntimeDefault" + - name: add-seccomp-runtimedefault-pod + match: + any: + - resources: + kinds: + - Deployment + - StatefulSet + - Job + - DaemonSet + preconditions: + all: + - key: "{{ request.object.spec.template.spec.securityContext.seccompProfile.type || '' }}" + operator: Equals + value: Unconfined + mutate: + patchStrategicMerge: + spec: + template: + spec: + securityContext: + seccompProfile: + (type): "Unconfined" + type: "RuntimeDefault" diff --git a/pod-security/restricted/restrict-seccomp-strict/restrict-seccomp-strict.yaml b/pod-security/restricted/restrict-seccomp-strict/restrict-seccomp-strict.yaml index 15481329..95f9f6fd 100644 --- a/pod-security/restricted/restrict-seccomp-strict/restrict-seccomp-strict.yaml +++ b/pod-security/restricted/restrict-seccomp-strict/restrict-seccomp-strict.yaml @@ -9,6 +9,7 @@ metadata: policies.kyverno.io/subject: Pod kyverno.io/kubernetes-version: "1.22-1.23" policies.nirmata.io/remediation-docs: "https://docs.nirmata.io/policysets/podsecurity/restricted/restrict-seccomp-strict/" + policies.nirmata.io/remediation: "https://github.com/nirmata/kyverno-policies/tree/main/pod-security/restricted/restrict-seccomp-strict/remediate-restrict-seccomp-strict.yaml" 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,