Initial commit

This commit is contained in:
Scooby Husky
2026-03-09 20:21:35 -05:00
commit aacb8eebbe
314 changed files with 21766 additions and 0 deletions
@@ -0,0 +1,24 @@
apiVersion: kyverno.io/v2
kind: PolicyException
metadata:
name: authentik-exemption
namespace: kyverno
spec:
exceptions:
- policyName: disallow-automount-sa-token
ruleNames:
- validate-automount
- autogen-validate-automount
match:
any:
- resources:
kinds:
- Deployment
- ReplicaSet
- Pod
namespaces:
- authentik
names:
- authentik-server*
- authentik-worker*
- pg-authentik*
@@ -0,0 +1,68 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-automount-sa-token
annotations:
policies.kyverno.io/title: Disallow Automount Service Account Token
policies.kyverno.io/category: DoD STIG
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
STIG V-242382: Pods that do not need to communicate with the
Kubernetes API server should have automountServiceAccountToken
set to false to prevent credential exposure.
pod-policies.kyverno.io/autogen-controllers: none
spec:
validationFailureAction: Audit
background: true
rules:
- name: validate-automount
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- kyverno
- istio-system
- cert-manager
- cnpg-system
- external-secrets
- vault
- rook-ceph
- prometheus
- argocd
- envoy-gateway-system
- kiali-operator
- mariadb-system
- redis-operator
- reloader
- scylla-operator
- crowdsec
- external-dns
- frigate
- gitlab
- grafana
- guacamole
- home-assistant
- mqtt
- netbird
- nextcloud
- teslamate
- unpoller
- authentik
- checkov
- n8n
- nessus
validate:
message: >-
Pods should set automountServiceAccountToken to false unless API
access is required (STIG V-242382).
pattern:
spec:
automountServiceAccountToken: false
@@ -0,0 +1,33 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-default-namespace
annotations:
policies.kyverno.io/title: Disallow Default Namespace
policies.kyverno.io/category: DoD STIG
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
STIG V-242383: Workloads must not run in the default namespace.
The default namespace lacks proper RBAC and network policy boundaries.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: validate-namespace
match:
any:
- resources:
kinds:
- Pod
- Deployment
- StatefulSet
- DaemonSet
- Job
- CronJob
namespaces:
- default
validate:
message: >-
Workloads must not run in the default namespace (STIG V-242383).
Create a dedicated namespace for your application.
deny: {}
@@ -0,0 +1,40 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-host-namespaces
annotations:
policies.kyverno.io/title: Disallow Host Namespaces
policies.kyverno.io/category: DoD STIG
policies.kyverno.io/severity: high
policies.kyverno.io/description: >-
STIG V-242386: Containers must not share the host process ID, IPC,
or network namespace. Sharing host namespaces allows containers to
access host-level resources and break isolation boundaries.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: host-namespaces
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- rook-ceph
- istio-system
- prometheus
- kyverno
- crowdsec
validate:
message: >-
Sharing host PID, IPC, or network namespaces is not allowed (STIG V-242386).
pattern:
spec:
=(hostPID): false
=(hostIPC): false
=(hostNetwork): false
@@ -0,0 +1,34 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
annotations:
policies.kyverno.io/title: Disallow Latest Image Tag
policies.kyverno.io/category: Zero Trust
policies.kyverno.io/severity: medium
spec:
validationFailureAction: Enforce
background: true
rules:
- name: disallow-latest
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- crowdsec
- home-assistant
validate:
message: "Using ':latest' image tag is not allowed. Specify an explicit tag."
pattern:
spec:
containers:
- image: "!*:latest"
=(initContainers):
- image: "!*:latest"
@@ -0,0 +1,29 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-nodeport-services
annotations:
policies.kyverno.io/title: Disallow NodePort Services
policies.kyverno.io/category: Zero Trust
policies.kyverno.io/severity: medium
spec:
validationFailureAction: Enforce
background: true
rules:
- name: disallow-nodeport
match:
any:
- resources:
kinds:
- Service
exclude:
any:
- resources:
namespaces:
- kube-system
- istio-system
validate:
message: "NodePort services are not allowed. Use ClusterIP or LoadBalancer."
pattern:
spec:
type: "!NodePort"
@@ -0,0 +1,43 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged-containers
annotations:
policies.kyverno.io/title: Disallow Privileged Containers
policies.kyverno.io/category: Zero Trust
policies.kyverno.io/severity: high
spec:
validationFailureAction: Enforce
background: true
rules:
- name: disallow-privileged
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- rook-ceph
- istio-system
- kube-node-lease
- prometheus
- kyverno
- tetragon
- crowdsec
validate:
message: "Privileged containers are not allowed."
pattern:
spec:
containers:
- =(securityContext):
=(privileged): false
=(initContainers):
- =(securityContext):
=(privileged): false
=(ephemeralContainers):
- =(securityContext):
=(privileged): false
@@ -0,0 +1,47 @@
apiVersion: kyverno.io/v2
kind: PolicyException
metadata:
name: istio-waypoint-exemption
namespace: kyverno
spec:
exceptions:
- policyName: require-app-label
ruleNames:
- require-app-label
- policyName: require-probes
ruleNames:
- require-probes
- policyName: disallow-automount-sa-token
ruleNames:
- validate-automount
- autogen-validate-automount
- policyName: require-drop-all-capabilities
ruleNames:
- require-drop-all
- autogen-require-drop-all
- policyName: require-resource-limits
ruleNames:
- require-limits
- autogen-require-limits
- policyName: require-non-root
ruleNames:
- require-run-as-non-root
- autogen-require-run-as-non-root
- policyName: require-readonly-rootfs
ruleNames:
- require-ro-rootfs
- autogen-require-ro-rootfs
- policyName: disallow-latest-tag
ruleNames:
- disallow-latest
- autogen-disallow-latest
match:
any:
- resources:
kinds:
- Deployment
- ReplicaSet
- Pod
selector:
matchLabels:
gateway.networking.k8s.io/gateway-name: waypoint
@@ -0,0 +1,70 @@
apiVersion: kyverno.io/v2
kind: PolicyException
metadata:
name: rancher-exemption
namespace: kyverno
spec:
exceptions:
- policyName: restrict-image-registries
ruleNames:
- validate-container-registries
- autogen-validate-container-registries
- autogen-cronjob-validate-container-registries
- policyName: require-drop-all-capabilities
ruleNames:
- require-drop-all
- autogen-require-drop-all
- autogen-cronjob-require-drop-all
- policyName: require-resource-limits
ruleNames:
- require-limits
- autogen-require-limits
- autogen-cronjob-require-limits
- policyName: disallow-automount-sa-token
ruleNames:
- validate-automount
- autogen-validate-automount
- autogen-cronjob-validate-automount
- policyName: require-app-label
ruleNames:
- require-app-label
- policyName: require-probes
ruleNames:
- require-probes
- policyName: disallow-latest-tag
ruleNames:
- disallow-latest
- autogen-disallow-latest
- autogen-cronjob-disallow-latest
- policyName: require-non-root
ruleNames:
- require-run-as-non-root
- autogen-require-run-as-non-root
- autogen-cronjob-require-run-as-non-root
- policyName: require-readonly-rootfs
ruleNames:
- require-ro-rootfs
- autogen-require-ro-rootfs
- autogen-cronjob-require-ro-rootfs
- policyName: disallow-default-namespace
ruleNames:
- validate-namespace
- autogen-validate-namespace
- autogen-cronjob-validate-namespace
match:
any:
- resources:
namespaces:
- cattle-system
- cattle-fleet-system
- cattle-fleet-local-system
- cattle-capi-system
- cattle-turtles-system
- cattle-ui-plugin-system
- cattle-impersonation-system
- cattle-global-data
- cattle-local-user-passwords
- cattle-fleet-clusters-system
- fleet-default
- fleet-local
- cluster-fleet-*
@@ -0,0 +1,72 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-drop-all-capabilities
annotations:
policies.kyverno.io/title: Require Drop All Capabilities
policies.kyverno.io/category: DoD STIG
policies.kyverno.io/severity: high
policies.kyverno.io/description: >-
STIG V-242398: Containers must drop all Linux capabilities and only
add back specific capabilities that are required. This follows the
principle of least privilege for container security contexts.
spec:
validationFailureAction: Audit
background: true
rules:
- name: require-drop-all
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- rook-ceph
- istio-system
- prometheus
- kyverno
- argocd
- cert-manager
- cnpg-system
- envoy-gateway-system
- kiali-operator
- mariadb-system
- redis-operator
- reloader
- scylla-operator
- vault
- mqtt
- gitlab
- netbird
- grafana
- crowdsec
- external-dns
- nextcloud
- home-assistant
- guacamole
- teslamate
- unpoller
- frigate
- authentik
- checkov
- external-secrets
validate:
message: >-
Containers must drop ALL capabilities (STIG V-242398).
Add securityContext.capabilities.drop: ["ALL"] to each container.
pattern:
spec:
containers:
- securityContext:
capabilities:
drop:
- ALL
=(initContainers):
- securityContext:
capabilities:
drop:
- ALL
@@ -0,0 +1,81 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-istio-ambient-mesh
annotations:
policies.kyverno.io/title: Require Istio Ambient Mesh Enrollment
policies.kyverno.io/category: Zero Trust
policies.kyverno.io/severity: high
policies.kyverno.io/description: >-
Application namespaces must be enrolled in Istio ambient mesh via the
istio.io/dataplane-mode=ambient label for zero-trust mTLS enforcement.
spec:
validationFailureAction: Audit
background: true
rules:
- name: check-namespace-ambient-label
match:
any:
- resources:
kinds:
- Namespace
exclude:
any:
- resources:
names:
# Core Kubernetes
- kube-system
- kube-public
- kube-node-lease
- kyverno
- default
# Infrastructure
- istio-system
- cert-manager
- cnpg-system
- rook-ceph
- vault
- external-secrets
- redis-operator
- mariadb-system
- scylla-operator
- scylla-manager
- reloader
- checkov
- kiali-operator
- envoy-gateway-system
- tetragon
- prometheus
- crowdsec
- cilium-secrets
- gateway
- argocd
- netbird-operator
# Rancher (exact names)
- cattle-system
- cattle-fleet-system
- cattle-fleet-local-system
- cattle-capi-system
- cattle-turtles-system
- cattle-ui-plugin-system
- cattle-impersonation-system
- cattle-global-data
- cattle-local-user-passwords
- cattle-fleet-clusters-system
- fleet-default
- fleet-local
- local
# Rancher dynamic namespaces (wildcard)
- cattle-*
- fleet-*
- c-*
- p-*
- u-*
- user-*
- cluster-fleet-*
validate:
message: "Application namespaces must have istio.io/dataplane-mode=ambient for zero-trust mTLS."
pattern:
metadata:
labels:
istio.io/dataplane-mode: ambient
@@ -0,0 +1,43 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-app-label
annotations:
policies.kyverno.io/title: Require App Label
policies.kyverno.io/category: Zero Trust
policies.kyverno.io/severity: low
spec:
validationFailureAction: Audit
background: true
rules:
- name: require-app-label
match:
any:
- resources:
kinds:
- Deployment
- StatefulSet
- DaemonSet
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-node-lease
- kyverno
- rook-ceph
- default
- crowdsec
- gitlab
- scylla-manager
- scylla-operator
- cert-manager
validate:
message: "The label 'app' or 'app.kubernetes.io/name' is required."
anyPattern:
- metadata:
labels:
app: "?*"
- metadata:
labels:
app.kubernetes.io/name: "?*"
@@ -0,0 +1,37 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-non-root
annotations:
policies.kyverno.io/title: Require Non-Root User
policies.kyverno.io/category: Zero Trust
policies.kyverno.io/severity: medium
spec:
validationFailureAction: Audit
background: true
rules:
- name: require-run-as-non-root
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- rook-ceph
- istio-system
- prometheus
- kyverno
- tetragon
validate:
message: "Containers must run as non-root. Set runAsNonRoot to true."
pattern:
spec:
=(securityContext):
=(runAsNonRoot): true
containers:
- =(securityContext):
=(runAsNonRoot): true
@@ -0,0 +1,56 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-probes
annotations:
policies.kyverno.io/title: Require Liveness and Readiness Probes
policies.kyverno.io/category: Zero Trust
policies.kyverno.io/severity: low
spec:
validationFailureAction: Audit
background: true
rules:
- name: require-probes
match:
any:
- resources:
kinds:
- Deployment
- StatefulSet
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- tetragon
- rook-ceph
- argocd
- cert-manager
- cnpg-system
- envoy-gateway-system
- external-secrets
- istio-system
- kiali-operator
- mariadb-system
- prometheus
- redis-operator
- reloader
- scylla-operator
- vault
- gitlab
- grafana
- guacamole
- nextcloud
- scylla-manager
validate:
message: "Liveness and readiness probes are required for all containers."
pattern:
spec:
template:
spec:
containers:
- livenessProbe:
periodSeconds: ">0"
readinessProbe:
periodSeconds: ">0"
@@ -0,0 +1,63 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-resource-limits
annotations:
policies.kyverno.io/title: Require Resource Limits
policies.kyverno.io/category: Zero Trust
policies.kyverno.io/severity: medium
spec:
validationFailureAction: Audit
background: true
rules:
- name: require-limits
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-node-lease
- kyverno
- argocd
- authentik
- cert-manager
- cnpg-system
- envoy-gateway-system
- external-secrets
- istio-system
- kiali-operator
- mariadb-system
- prometheus
- redis-operator
- reloader
- rook-ceph
- scylla-operator
- vault
- gitlab
- netbird
- grafana
- crowdsec
- external-dns
- nextcloud
- mqtt
- home-assistant
- guacamole
- teslamate
- unpoller
- frigate
- checkov
- scylla-manager
validate:
message: "All containers must have CPU and memory limits defined."
pattern:
spec:
containers:
- resources:
limits:
cpu: "?*"
memory: "?*"
@@ -0,0 +1,39 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-readonly-rootfs
annotations:
policies.kyverno.io/title: Require Read-Only Root Filesystem
policies.kyverno.io/category: Zero Trust
policies.kyverno.io/severity: low
spec:
validationFailureAction: Audit
background: true
rules:
- name: require-ro-rootfs
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- rook-ceph
- istio-system
- kyverno
- tetragon
- prometheus
- authentik
- gitlab
- nextcloud
- home-assistant
validate:
message: "Containers should use a read-only root filesystem."
pattern:
spec:
containers:
- =(securityContext):
=(readOnlyRootFilesystem): true
@@ -0,0 +1,107 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-image-registries
annotations:
policies.kyverno.io/title: Restrict Image Registries
policies.kyverno.io/category: Zero Trust
policies.kyverno.io/severity: high
policies.kyverno.io/description: >-
Validates that all container images come from allowed registries.
Images must either use an explicit allowed registry prefix (docker.io/,
ghcr.io/, quay.io/, etc.) or be short-name Docker Hub references
(no dots before the first slash, e.g. grafana/grafana or busybox).
spec:
validationFailureAction: Enforce
background: true
rules:
- name: validate-container-registries
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-node-lease
- kyverno
validate:
message: >-
Images must come from allowed registries: docker.io, ghcr.io, quay.io,
registry.k8s.io, gcr.io, lscr.io, registry.gitlab.com, cr.fluentbit.io,
public.ecr.aws, ecr-public.aws.com, oci.external-secrets.io,
docker-registry3.mariadb.com. Docker Hub short names (org/image or
library images) are also allowed.
foreach:
- list: "request.object.spec.containers"
deny:
conditions:
all:
# Image does NOT start with any allowed registry prefix
- key: "{{element.image}}"
operator: AnyNotIn
value:
- "docker.io/*"
- "ghcr.io/*"
- "quay.io/*"
- "registry.k8s.io/*"
- "gcr.io/*"
- "lscr.io/*"
- "registry.gitlab.com/*"
- "cr.fluentbit.io/*"
- "public.ecr.aws/*"
- "ecr-public.aws.com/*"
- "oci.external-secrets.io/*"
- "docker-registry3.mariadb.com/*"
# AND image looks like a registry hostname (has a dot before the first slash)
# This allows Docker Hub short names like grafana/grafana or busybox
- key: "{{element.image}}"
operator: Equals
value: "*.*/*"
- list: "request.object.spec.initContainers || []"
deny:
conditions:
all:
- key: "{{element.image}}"
operator: AnyNotIn
value:
- "docker.io/*"
- "ghcr.io/*"
- "quay.io/*"
- "registry.k8s.io/*"
- "gcr.io/*"
- "lscr.io/*"
- "registry.gitlab.com/*"
- "cr.fluentbit.io/*"
- "public.ecr.aws/*"
- "ecr-public.aws.com/*"
- "oci.external-secrets.io/*"
- "docker-registry3.mariadb.com/*"
- key: "{{element.image}}"
operator: Equals
value: "*.*/*"
- list: "request.object.spec.ephemeralContainers || []"
deny:
conditions:
all:
- key: "{{element.image}}"
operator: AnyNotIn
value:
- "docker.io/*"
- "ghcr.io/*"
- "quay.io/*"
- "registry.k8s.io/*"
- "gcr.io/*"
- "lscr.io/*"
- "registry.gitlab.com/*"
- "cr.fluentbit.io/*"
- "public.ecr.aws/*"
- "ecr-public.aws.com/*"
- "oci.external-secrets.io/*"
- "docker-registry3.mariadb.com/*"
- key: "{{element.image}}"
operator: Equals
value: "*.*/*"