Skip to main content

Host Process

Description

Disallows HostProcess containers for Windows pods. HostProcess containers enable privileged access on Windows nodes and must be disallowed in Baseline and Restricted policies. Corresponds to the windowsOptions.hostProcess field in a Pod's securityContext or container securityContext. For more information, see https://kubernetes.io/docs/concepts/security/pod-security-standards/

Template

apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8spsphostprocess
annotations:
metadata.gatekeeper.sh/title: "Host Process"
metadata.gatekeeper.sh/version: 1.0.0
description: >-
Disallows HostProcess containers for Windows pods.
HostProcess containers enable privileged access on Windows nodes
and must be disallowed in Baseline and Restricted policies.
Corresponds to the windowsOptions.hostProcess field in a Pod's
securityContext or container securityContext.
For more information, see
https://kubernetes.io/docs/concepts/security/pod-security-standards/
spec:
crd:
spec:
names:
kind: K8sPSPHostProcess
validation:
openAPIV3Schema:
type: object
description: >-
Disallows HostProcess containers for Windows pods.
HostProcess containers enable privileged access on Windows nodes
and must be disallowed in Baseline and Restricted policies.
Corresponds to the windowsOptions.hostProcess field in a Pod's
securityContext or container securityContext.
For more information, see
https://kubernetes.io/docs/concepts/security/pod-security-standards/
properties:
exemptImages:
description: >-
Any container that uses an image that matches an entry in this list will be excluded
from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`.

It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name)
in order to avoid unexpectedly exempting images from an untrusted repository.
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
code:
- engine: K8sNativeValidation
source:
variables:
- name: containers
expression: 'has(variables.anyObject.spec.containers) ? variables.anyObject.spec.containers : []'
- name: initContainers
expression: 'has(variables.anyObject.spec.initContainers) ? variables.anyObject.spec.initContainers : []'
- name: ephemeralContainers
expression: 'has(variables.anyObject.spec.ephemeralContainers) ? variables.anyObject.spec.ephemeralContainers : []'
- name: exemptImagePrefixes
expression: |
!has(variables.params.exemptImages) ? [] :
variables.params.exemptImages.filter(image, image.endsWith("*")).map(image, string(image).replace("*", ""))
- name: exemptImageExplicit
expression: |
!has(variables.params.exemptImages) ? [] :
variables.params.exemptImages.filter(image, !image.endsWith("*"))
- name: exemptImages
expression: |
(variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,
container.image in variables.exemptImageExplicit ||
variables.exemptImagePrefixes.exists(exemption, string(container.image).startsWith(exemption))
).map(container, container.image)
- name: podHostProcess
expression: |
has(variables.anyObject.spec.securityContext) &&
has(variables.anyObject.spec.securityContext.windowsOptions) &&
has(variables.anyObject.spec.securityContext.windowsOptions.hostProcess) &&
variables.anyObject.spec.securityContext.windowsOptions.hostProcess
- name: badContainers
expression: |
(variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,
!(container.image in variables.exemptImages) &&
has(container.securityContext) &&
has(container.securityContext.windowsOptions) &&
has(container.securityContext.windowsOptions.hostProcess) &&
container.securityContext.windowsOptions.hostProcess
).map(container, "HostProcess container is not allowed: " + container.name + ", securityContext.windowsOptions.hostProcess: true")
- name: isUpdate
expression: has(request.operation) && request.operation == "UPDATE"
validations:
- expression: 'variables.isUpdate || !variables.podHostProcess'
messageExpression: '"HostProcess is not allowed at pod level: " + variables.anyObject.metadata.name'
- expression: variables.isUpdate || size(variables.badContainers) == 0
messageExpression: 'variables.badContainers.join(", ")'
- engine: Rego
source:
rego: |
package k8spsphostprocess

import data.lib.exclude_update.is_update
import data.lib.exempt_container.is_exempt

violation[{"msg": msg, "details": {}}] {
# spec.securityContext.windowsOptions.hostProcess field is immutable.
not is_update(input.review)

# Check pod-level securityContext
input.review.object.spec.securityContext.windowsOptions.hostProcess == true
msg := sprintf("HostProcess is not allowed at pod level: %v", [input.review.object.metadata.name])
}

violation[{"msg": msg, "details": {}}] {
# spec.containers.securityContext.windowsOptions.hostProcess field is immutable.
not is_update(input.review)

c := input_containers[_]
not is_exempt(c)
c.securityContext.windowsOptions.hostProcess == true
msg := sprintf("HostProcess container is not allowed: %v, securityContext.windowsOptions.hostProcess: true", [c.name])
}

input_containers[c] {
c := input.review.object.spec.containers[_]
}

input_containers[c] {
c := input.review.object.spec.initContainers[_]
}

input_containers[c] {
c := input.review.object.spec.ephemeralContainers[_]
}
libs:
- |
package lib.exclude_update

is_update(review) {
review.operation == "UPDATE"
}
- |
package lib.exempt_container

is_exempt(container) {
exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", [])
img := container.image
exemption := exempt_images[_]
_matches_exemption(img, exemption)
}

_matches_exemption(img, exemption) {
not endswith(exemption, "*")
exemption == img
}

_matches_exemption(img, exemption) {
endswith(exemption, "*")
prefix := trim_suffix(exemption, "*")
startswith(img, prefix)
}

Usage

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-process/template.yaml

Examples

host-process-disallowed
constraint
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPHostProcess
metadata:
name: psp-host-process
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]

Usage

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-process/samples/psp-host-process/constraint.yaml
example-disallowed-pod-level
apiVersion: v1
kind: Pod
metadata:
name: nginx-host-process-disallowed
labels:
app: nginx-host-process
spec:
securityContext:
windowsOptions:
hostProcess: true
hostNetwork: true
containers:
- name: nginx
image: nginx

Usage

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-process/samples/psp-host-process/example_disallowed_pod_level.yaml
example-disallowed-container-level
apiVersion: v1
kind: Pod
metadata:
name: nginx-host-process-disallowed
labels:
app: nginx-host-process
spec:
containers:
- name: nginx
image: nginx
securityContext:
windowsOptions:
hostProcess: true

Usage

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-process/samples/psp-host-process/example_disallowed_container_level.yaml
example-allowed
apiVersion: v1
kind: Pod
metadata:
name: nginx-host-process-allowed
labels:
app: nginx-host-process
spec:
containers:
- name: nginx
image: nginx

Usage

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-process/samples/psp-host-process/example_allowed.yaml
disallowed-ephemeral
apiVersion: v1
kind: Pod
metadata:
name: nginx-host-process-disallowed
labels:
app: nginx-host-process
spec:
ephemeralContainers:
- name: nginx
image: nginx
securityContext:
windowsOptions:
hostProcess: true

Usage

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-process/samples/psp-host-process/disallowed_ephemeral.yaml
disallowed-init
apiVersion: v1
kind: Pod
metadata:
name: nginx-host-process-disallowed
labels:
app: nginx-host-process
spec:
containers:
- name: nginx
image: nginx
initContainers:
- name: nginx-init
image: nginx
securityContext:
windowsOptions:
hostProcess: true

Usage

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-process/samples/psp-host-process/disallowed_init.yaml