Files
Homelabv4/infrastructure/kyverno/policies/restrict-image-registries.yaml
T
2026-03-09 20:21:35 -05:00

108 lines
4.1 KiB
YAML

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: "*.*/*"