101 lines
3.5 KiB
YAML
101 lines
3.5 KiB
YAML
# Dev admission policy: allow local registry images
|
|
# In dev, we also allow images from localhost/minikube registry
|
|
---
|
|
apiVersion: admissionregistration.k8s.io/v1
|
|
kind: ValidatingAdmissionPolicy
|
|
metadata:
|
|
name: dexorder-agent-image-policy
|
|
spec:
|
|
failurePolicy: Fail
|
|
matchConstraints:
|
|
namespaceSelector:
|
|
matchLabels:
|
|
dexorder.io/type: agents
|
|
resourceRules:
|
|
- apiGroups: ["apps"]
|
|
apiVersions: ["v1"]
|
|
resources: ["deployments"]
|
|
operations: ["CREATE", "UPDATE"]
|
|
validations:
|
|
# Allow local dev images in addition to production registry
|
|
- expression: |
|
|
object.spec.template.spec.containers.all(c,
|
|
c.image.startsWith('ghcr.io/dexorder/agent:') ||
|
|
c.image.startsWith('ghcr.io/dexorder/agent-') ||
|
|
c.image.startsWith('localhost:5000/dexorder/agent') ||
|
|
c.image.startsWith('dexorder/agent') ||
|
|
c.image.startsWith('dexorder/ai-client-py') ||
|
|
c.image.startsWith('ai-client-py') ||
|
|
c.image.startsWith('lifecycle-sidecar'))
|
|
message: "Only approved dexorder agent images are allowed"
|
|
reason: Forbidden
|
|
|
|
# No privileged containers
|
|
- expression: |
|
|
object.spec.template.spec.containers.all(c,
|
|
!has(c.securityContext) ||
|
|
!has(c.securityContext.privileged) ||
|
|
c.securityContext.privileged == false)
|
|
message: "Privileged containers are not allowed"
|
|
reason: Forbidden
|
|
|
|
# No hostPath volumes
|
|
- expression: |
|
|
!has(object.spec.template.spec.volumes) ||
|
|
object.spec.template.spec.volumes.all(v,
|
|
!has(v.hostPath))
|
|
message: "hostPath volumes are not allowed"
|
|
reason: Forbidden
|
|
|
|
# No hostNetwork
|
|
- expression: |
|
|
!has(object.spec.template.spec.hostNetwork) ||
|
|
object.spec.template.spec.hostNetwork == false
|
|
message: "hostNetwork is not allowed"
|
|
reason: Forbidden
|
|
|
|
# No hostPID
|
|
- expression: |
|
|
!has(object.spec.template.spec.hostPID) ||
|
|
object.spec.template.spec.hostPID == false
|
|
message: "hostPID is not allowed"
|
|
reason: Forbidden
|
|
|
|
# Containers must run as non-root
|
|
- expression: |
|
|
object.spec.template.spec.containers.all(c,
|
|
has(c.securityContext) &&
|
|
has(c.securityContext.runAsNonRoot) &&
|
|
c.securityContext.runAsNonRoot == true)
|
|
message: "Containers must run as non-root"
|
|
reason: Forbidden
|
|
|
|
# Must drop all capabilities
|
|
- expression: |
|
|
object.spec.template.spec.containers.all(c,
|
|
has(c.securityContext) &&
|
|
has(c.securityContext.capabilities) &&
|
|
has(c.securityContext.capabilities.drop) &&
|
|
c.securityContext.capabilities.drop.exists(cap, cap == 'ALL'))
|
|
message: "Containers must drop all capabilities"
|
|
reason: Forbidden
|
|
|
|
# Read-only root filesystem
|
|
- expression: |
|
|
object.spec.template.spec.containers.all(c,
|
|
has(c.securityContext) &&
|
|
has(c.securityContext.readOnlyRootFilesystem) &&
|
|
c.securityContext.readOnlyRootFilesystem == true)
|
|
message: "Containers must have read-only root filesystem"
|
|
reason: Forbidden
|
|
|
|
# Resource limits must be set
|
|
- expression: |
|
|
object.spec.template.spec.containers.all(c,
|
|
has(c.resources) &&
|
|
has(c.resources.limits) &&
|
|
has(c.resources.limits.memory) &&
|
|
has(c.resources.limits.cpu))
|
|
message: "Containers must have resource limits set"
|
|
reason: Forbidden
|