Add Kyverno admission policies and CIS mappings
Kube-bench CIS scan / Scan ephemeral K3s cluster (push) Failing after 3m11s
Kube-bench CIS scan / Scan ephemeral K3s cluster (push) Failing after 3m11s
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
# Kyverno policy baseline
|
||||
|
||||
These policies are `ClusterPolicy` resources, but they intentionally select
|
||||
only namespaces labeled `security-baseline/open: "true"`. That keeps the
|
||||
portfolio demo enforceable without blocking Kyverno, Falco, ArgoCD, or other
|
||||
platform components. Expand the label scope deliberately for a real cluster.
|
||||
|
||||
All five policies use `validationFailureAction: Enforce`, so a matching Pod is
|
||||
rejected at admission time. The policies use `background: false` because the
|
||||
goal is to demonstrate admission enforcement, not retroactively evaluate
|
||||
existing objects.
|
||||
|
||||
| Policy | CIS alignment | Enforcement |
|
||||
| --- | --- | --- |
|
||||
| `disallow-privileged` | 5.2.2 | Rejects privileged containers and init containers. |
|
||||
| `require-non-root` | 5.2.7 | Requires `runAsNonRoot: true` on containers and init containers. |
|
||||
| `require-resource-limits` | 5.7.3 supplemental | Requires CPU and memory limits. This is a supplemental control, not a one-to-one CIS test. |
|
||||
| `restrict-image-registries` | 5.5.1 supplemental | Allows only approved registries. Full image provenance requires signing and verification as well. |
|
||||
| `disallow-host-network` | 5.2.3 and 5.2.5 | Rejects host PID, host network, and host IPC access. |
|
||||
|
||||
The CIS benchmark includes manual checks and platform-specific exceptions.
|
||||
The mapping above describes the control objective each policy supports, not a
|
||||
claim that one Kyverno rule implements the entire benchmark control.
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: disallow-host-network
|
||||
annotations:
|
||||
policies.kyverno.io/title: Disallow host network and host PID
|
||||
policies.kyverno.io/category: Pod Security Standards
|
||||
policies.kyverno.io/severity: high
|
||||
# CIS 5.2.3: minimize hostPID; CIS 5.2.5: minimize hostNetwork.
|
||||
policies.kyverno.io/cis-control: "5.2.3, 5.2.5"
|
||||
spec:
|
||||
validationFailureAction: Enforce
|
||||
background: false
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: no-host-network-or-pid
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
namespaceSelector:
|
||||
matchLabels:
|
||||
security-baseline/open: "true"
|
||||
validate:
|
||||
message: hostNetwork, hostPID, and hostIPC must be false or omitted.
|
||||
pattern:
|
||||
spec:
|
||||
=(hostNetwork): false
|
||||
=(hostPID): false
|
||||
=(hostIPC): false
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: disallow-privileged
|
||||
annotations:
|
||||
policies.kyverno.io/title: Disallow privileged containers
|
||||
policies.kyverno.io/category: Pod Security Standards
|
||||
policies.kyverno.io/severity: high
|
||||
# CIS 5.2.2: minimize admission of privileged containers.
|
||||
policies.kyverno.io/cis-control: "5.2.2"
|
||||
spec:
|
||||
validationFailureAction: Enforce
|
||||
background: false
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: privileged-containers
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
namespaceSelector:
|
||||
matchLabels:
|
||||
security-baseline/open: "true"
|
||||
validate:
|
||||
message: Privileged containers are not allowed in security-baseline namespaces.
|
||||
foreach:
|
||||
- list: request.object.spec.containers[]
|
||||
deny:
|
||||
conditions:
|
||||
any:
|
||||
- key: "{{ element.securityContext.privileged || false }}"
|
||||
operator: Equals
|
||||
value: true
|
||||
- list: request.object.spec.initContainers[]
|
||||
deny:
|
||||
conditions:
|
||||
any:
|
||||
- key: "{{ element.securityContext.privileged || false }}"
|
||||
operator: Equals
|
||||
value: true
|
||||
|
||||
@@ -2,5 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- phase-2-placeholder.yaml
|
||||
|
||||
- disallow-privileged.yaml
|
||||
- require-non-root.yaml
|
||||
- require-resource-limits.yaml
|
||||
- restrict-image-registries.yaml
|
||||
- disallow-host-network.yaml
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: policy-baseline-status
|
||||
namespace: security-baseline
|
||||
data:
|
||||
phase: "2"
|
||||
status: "GitOps target established; Kyverno policies arrive in phase 4"
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: require-non-root
|
||||
annotations:
|
||||
policies.kyverno.io/title: Require non-root containers
|
||||
policies.kyverno.io/category: Pod Security Standards
|
||||
policies.kyverno.io/severity: high
|
||||
# CIS 5.2.7: minimize admission of root containers.
|
||||
policies.kyverno.io/cis-control: "5.2.7"
|
||||
spec:
|
||||
validationFailureAction: Enforce
|
||||
background: false
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: containers-run-as-non-root
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
namespaceSelector:
|
||||
matchLabels:
|
||||
security-baseline/open: "true"
|
||||
validate:
|
||||
message: Containers must explicitly set runAsNonRoot=true.
|
||||
foreach:
|
||||
- list: request.object.spec.containers[]
|
||||
deny:
|
||||
conditions:
|
||||
any:
|
||||
- key: "{{ element.securityContext.runAsNonRoot || false }}"
|
||||
operator: Equals
|
||||
value: false
|
||||
- list: request.object.spec.initContainers[]
|
||||
deny:
|
||||
conditions:
|
||||
any:
|
||||
- key: "{{ element.securityContext.runAsNonRoot || false }}"
|
||||
operator: Equals
|
||||
value: false
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: require-resource-limits
|
||||
annotations:
|
||||
policies.kyverno.io/title: Require CPU and memory limits
|
||||
policies.kyverno.io/category: Resource governance
|
||||
policies.kyverno.io/severity: medium
|
||||
# Supplemental hardening aligned with CIS 5.7.3 workload controls. The
|
||||
# CIS benchmark does not define a one-to-one resource-limit test.
|
||||
policies.kyverno.io/cis-control: "5.7.3 supplemental"
|
||||
spec:
|
||||
validationFailureAction: Enforce
|
||||
background: false
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: containers-have-resource-limits
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
namespaceSelector:
|
||||
matchLabels:
|
||||
security-baseline/open: "true"
|
||||
validate:
|
||||
message: Every container must define CPU and memory limits.
|
||||
foreach:
|
||||
- list: request.object.spec.containers[]
|
||||
deny:
|
||||
conditions:
|
||||
any:
|
||||
- key: "{{ element.resources.limits.cpu || '' }}"
|
||||
operator: Equals
|
||||
value: ""
|
||||
- key: "{{ element.resources.limits.memory || '' }}"
|
||||
operator: Equals
|
||||
value: ""
|
||||
- list: request.object.spec.initContainers[]
|
||||
deny:
|
||||
conditions:
|
||||
any:
|
||||
- key: "{{ element.resources.limits.cpu || '' }}"
|
||||
operator: Equals
|
||||
value: ""
|
||||
- key: "{{ element.resources.limits.memory || '' }}"
|
||||
operator: Equals
|
||||
value: ""
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: restrict-image-registries
|
||||
annotations:
|
||||
policies.kyverno.io/title: Restrict image registries
|
||||
policies.kyverno.io/category: Supply chain
|
||||
policies.kyverno.io/severity: high
|
||||
# CIS 5.5.1: image provenance. This is a concrete admission control that
|
||||
# supports the broader provenance objective but is not the full CIS test.
|
||||
policies.kyverno.io/cis-control: "5.5.1 supplemental"
|
||||
spec:
|
||||
validationFailureAction: Enforce
|
||||
background: false
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: images-from-approved-registries
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
namespaceSelector:
|
||||
matchLabels:
|
||||
security-baseline/open: "true"
|
||||
validate:
|
||||
message: Images must come from ghcr.io, quay.io, or docker.io/library.
|
||||
foreach:
|
||||
- list: request.object.spec.containers[]
|
||||
anyPattern:
|
||||
- image: ghcr.io/*
|
||||
- image: quay.io/*
|
||||
- image: docker.io/library/*
|
||||
- list: request.object.spec.initContainers[]
|
||||
anyPattern:
|
||||
- image: ghcr.io/*
|
||||
- image: quay.io/*
|
||||
- image: docker.io/library/*
|
||||
|
||||
Reference in New Issue
Block a user