Skip to content
Snippets Groups Projects

[PLATFORM-2185] Configure Image Provenance admission control with Gatekeeper

Merged [PLATFORM-2185] Configure Image Provenance admission control with Gatekeeper
Merged Alain Atemnkeng requested to merge PLATFORM-2207-aatemnke2 into master
Files
4
+ 64
0
package k8simageprovenance
# List of exactly allowed repositories
allowed_repos := {
"docker.io",
"quay.io",
"public.ecr.aws",
"gcr.io",
"ghcr.io",
"harbor.io",
"harbor.it.vt.edu",
"gitlab.com",
"code.vt.edu",
"registry-1.docker.io",
"602401143452.dkr.ecr.us-east-1.amazonaws.com",
"code.vt.edu:5005",
"docker.elastic.co",
"harbor.platform.it.vt.edu",
"registry.gitlab.com",
"registry.k8s.io"
}
# Function to extract hostname from image (GPT4.0 assisted)
get_hostname(image) = hostname {
trace(sprintf("Checking hostname for image: %v", [image]))
contains(image, "/")
parts := split(image, "/")
# If the first part contains a '.', assume it's a hostname
contains(parts[0], ".")
hostname := parts[0]
trace(sprintf("Extracted hostname: %v", [hostname]))
} else = "docker.io" { # Default to Docker Hub if no hostname is identifiable
not contains(image, "/")
trace("Defaulting to docker.io (no hostname found)")
} else = "docker.io" { # Default if no '.' in the first part of the name
contains(image, "/")
parts := split(image, "/")
not contains(parts[0], ".")
trace("Defaulting to docker.io (no '.' in first part of hostname)")
}
# Check if image is from an allowed repository
is_from_allowed_repo(image) {
trace(sprintf("Checking if image %v is from an allowed repo", [image]))
hostname := get_hostname(image)
allowed := [repo | repo := allowed_repos[_]; hostname == repo]
result := count(allowed) > 0
trace(sprintf("Image %v allowed: %v", [image, result]))
result
}
# Main violation logic for all container types
violation[{"msg": msg}] {
trace("Evaluating violation")
input.review.object.kind == "Pod"
# Check initContainers and ephemeralContainers alongside containers
container_types := ["containers", "initContainers", "ephemeralContainers"]
container_type := container_types[_]
container := input.review.object.spec[container_type][_]
trace(sprintf("Checking %v image: %v", [container_type, container.image]))
not is_from_allowed_repo(container.image)
msg := sprintf("Image %v in %v is not from an allowed repository. Please contact the platform team", [container.image, container_type])
trace(sprintf("Violation found: %v", [msg]))
}