Skip to content

Commit

Permalink
Exclude UPDATE and PATCH operations in constraints for immutable fields
Browse files Browse the repository at this point in the history
Signed-off-by: Hidehito Yabuuchi <hdht.ybuc@gmail.com>
  • Loading branch information
ordovicia committed May 23, 2023
1 parent 7db1c86 commit ff93bf1
Show file tree
Hide file tree
Showing 34 changed files with 103 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/general/automount-serviceaccount-token/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspautomountserviceaccounttokenpod
annotations:
metadata.gatekeeper.sh/title: "Automount Service Account Token for Pod"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Controls the ability of any Pod to enable automountServiceAccountToken.
spec:
Expand Down
5 changes: 5 additions & 0 deletions src/general/automount-serviceaccount-token/src.rego
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package k8sautomountserviceaccounttoken

import data.lib.exclude_update_patch.is_update_or_patch

violation[{"msg": msg}] {
# spec.automountServiceAccountToken and spec.containers.volumeMounts fields are immutable.
not is_update_or_patch(input.review)

obj := input.review.object
mountServiceAccountToken(obj.spec)
msg := sprintf("Automounting service account token is disallowed, pod: %v", [obj.metadata.name])
Expand Down
2 changes: 1 addition & 1 deletion src/general/ephemeralstoragelimit/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8scontainerephemeralstoragelimit
annotations:
metadata.gatekeeper.sh/title: "Container ephemeral storage limit"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Requires containers to have an ephemeral storage limit set and constrains
the limit to be within the specified maximum values.
Expand Down
5 changes: 5 additions & 0 deletions src/general/ephemeralstoragelimit/src.rego
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package k8scontainerephemeralstoragelimit

import data.lib.exclude_update_patch.is_update_or_patch
import data.lib.exempt_container.is_exempt

missing(obj, field) = true {
Expand Down Expand Up @@ -112,10 +113,14 @@ canonify_storage(orig) = new {
}

violation[{"msg": msg}] {
# spec.containers.resources.limits["ephemeral-storage"] field is immutable.
not is_update_or_patch(input.review)

general_violation[{"msg": msg, "field": "containers"}]
}

violation[{"msg": msg}] {
not is_update_or_patch(input.review)
general_violation[{"msg": msg, "field": "initContainers"}]
}

Expand Down
2 changes: 1 addition & 1 deletion src/general/requiredprobes/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8srequiredprobes
annotations:
metadata.gatekeeper.sh/title: "Required Probes"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: Requires Pods to have readiness and/or liveness probes.
spec:
crd:
Expand Down
5 changes: 5 additions & 0 deletions src/general/requiredprobes/src.rego
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package k8srequiredprobes

import data.lib.exclude_update_patch.is_update_or_patch

probe_type_set = probe_types {
probe_types := {type | type := input.parameters.probeTypes[_]}
}

violation[{"msg": msg}] {
# Probe fields are immutable.
not is_update_or_patch(input.review)

container := input.review.object.spec.containers[_]
probe := input.parameters.probes[_]
probe_is_missing(container, probe)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspallowprivilegeescalationcontainer
annotations:
metadata.gatekeeper.sh/title: "Allow Privilege Escalation in Container"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Controls restricting escalation to root privileges. Corresponds to the
`allowPrivilegeEscalation` field in a PodSecurityPolicy. For more
Expand Down
4 changes: 4 additions & 0 deletions src/pod-security-policy/allow-privilege-escalation/src.rego
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package k8spspallowprivilegeescalationcontainer

import data.lib.exclude_update_patch.is_update_or_patch
import data.lib.exempt_container.is_exempt

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

c := input_containers[_]
not is_exempt(c)
input_allow_privilege_escalation(c)
Expand Down
2 changes: 1 addition & 1 deletion src/pod-security-policy/capabilities/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspcapabilities
annotations:
metadata.gatekeeper.sh/title: "Capabilities"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Controls Linux capabilities on containers. Corresponds to the
`allowedCapabilities` and `requiredDropCapabilities` fields in a
Expand Down
9 changes: 9 additions & 0 deletions src/pod-security-policy/capabilities/src.rego
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package capabilities

import data.lib.exclude_update_patch.is_update_or_patch
import data.lib.exempt_container.is_exempt

violation[{"msg": msg}] {
# spec.containers.securityContext.capabilities field is immutable.
not is_update_or_patch(input.review)

container := input.review.object.spec.containers[_]
not is_exempt(container)
has_disallowed_capabilities(container)
msg := sprintf("container <%v> has a disallowed capability. Allowed capabilities are %v", [container.name, get_default(input.parameters, "allowedCapabilities", "NONE")])
}

violation[{"msg": msg}] {
not is_update_or_patch(input.review)
container := input.review.object.spec.containers[_]
not is_exempt(container)
missing_drop_capabilities(container)
Expand All @@ -19,13 +24,15 @@ violation[{"msg": msg}] {


violation[{"msg": msg}] {
not is_update_or_patch(input.review)
container := input.review.object.spec.initContainers[_]
not is_exempt(container)
has_disallowed_capabilities(container)
msg := sprintf("init container <%v> has a disallowed capability. Allowed capabilities are %v", [container.name, get_default(input.parameters, "allowedCapabilities", "NONE")])
}

violation[{"msg": msg}] {
not is_update_or_patch(input.review)
container := input.review.object.spec.initContainers[_]
not is_exempt(container)
missing_drop_capabilities(container)
Expand All @@ -35,13 +42,15 @@ violation[{"msg": msg}] {


violation[{"msg": msg}] {
not is_update_or_patch(input.review)
container := input.review.object.spec.ephemeralContainers[_]
not is_exempt(container)
has_disallowed_capabilities(container)
msg := sprintf("ephemeral container <%v> has a disallowed capability. Allowed capabilities are %v", [container.name, get_default(input.parameters, "allowedCapabilities", "NONE")])
}

violation[{"msg": msg}] {
not is_update_or_patch(input.review)
container := input.review.object.spec.ephemeralContainers[_]
not is_exempt(container)
missing_drop_capabilities(container)
Expand Down
2 changes: 1 addition & 1 deletion src/pod-security-policy/flexvolume-drivers/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspflexvolumes
annotations:
metadata.gatekeeper.sh/title: "FlexVolumes"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Controls the allowlist of FlexVolume drivers. Corresponds to the
`allowedFlexVolumes` field in PodSecurityPolicy. For more information,
Expand Down
5 changes: 5 additions & 0 deletions src/pod-security-policy/flexvolume-drivers/src.rego
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package k8spspflexvolumes

import data.lib.exclude_update_patch.is_update_or_patch

violation[{"msg": msg, "details": {}}] {
# spec.volumes field is immutable.
not is_update_or_patch(input.review)

volume := input_flexvolumes[_]
not input_flexvolumes_allowed(volume)
msg := sprintf("FlexVolume %v is not allowed, pod: %v. Allowed drivers: %v", [volume, input.review.object.metadata.name, input.parameters.allowedFlexVolumes])
Expand Down
2 changes: 1 addition & 1 deletion src/pod-security-policy/forbidden-sysctls/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspforbiddensysctls
annotations:
metadata.gatekeeper.sh/title: "Forbidden Sysctls"
metadata.gatekeeper.sh/version: 1.1.1
metadata.gatekeeper.sh/version: 1.1.2
description: >-
Controls the `sysctl` profile used by containers. Corresponds to the
`allowedUnsafeSysctls` and `forbiddenSysctls` fields in a PodSecurityPolicy.
Expand Down
6 changes: 6 additions & 0 deletions src/pod-security-policy/forbidden-sysctls/src.rego
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package k8spspforbiddensysctls

import data.lib.exclude_update_patch.is_update_or_patch

# Block if forbidden
violation[{"msg": msg, "details": {}}] {
# spec.securityContext.sysctls field is immutable.
not is_update_or_patch(input.review)

sysctl := input.review.object.spec.securityContext.sysctls[_].name
forbidden_sysctl(sysctl)
msg := sprintf("The sysctl %v is not allowed, pod: %v. Forbidden sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.forbiddenSysctls])
}

# Block if not explicitly allowed
violation[{"msg": msg, "details": {}}] {
not is_update_or_patch(input.review)
sysctl := input.review.object.spec.securityContext.sysctls[_].name
not allowed_sysctl(sysctl)
msg := sprintf("The sysctl %v is not explicitly allowed, pod: %v. Allowed sysctls: %v", [sysctl, input.review.object.metadata.name, input.parameters.allowedSysctls])
Expand Down
2 changes: 1 addition & 1 deletion src/pod-security-policy/fsgroup/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspfsgroup
annotations:
metadata.gatekeeper.sh/title: "FS Group"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Controls allocating an FSGroup that owns the Pod's volumes. Corresponds
to the `fsGroup` field in a PodSecurityPolicy. For more information, see
Expand Down
5 changes: 5 additions & 0 deletions src/pod-security-policy/fsgroup/src.rego
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package k8spspfsgroup

import data.lib.exclude_update_patch.is_update_or_patch

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

spec := input.review.object.spec
not input_fsGroup_allowed(spec)
msg := sprintf("The provided pod spec fsGroup is not allowed, pod: %v. Allowed fsGroup: %v", [input.review.object.metadata.name, input.parameters])
Expand Down
2 changes: 1 addition & 1 deletion src/pod-security-policy/host-filesystem/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spsphostfilesystem
annotations:
metadata.gatekeeper.sh/title: "Host Filesystem"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Controls usage of the host filesystem. Corresponds to the
`allowedHostPaths` field in a PodSecurityPolicy. For more information,
Expand Down
5 changes: 5 additions & 0 deletions src/pod-security-policy/host-filesystem/src.rego
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package k8spsphostfilesystem

import data.lib.exclude_update_patch.is_update_or_patch

violation[{"msg": msg, "details": {}}] {
# spec.volumes field is immutable.
not is_update_or_patch(input.review)

volume := input_hostpath_volumes[_]
allowedPaths := get_allowed_paths(input)
input_hostpath_violation(allowedPaths, volume)
Expand Down
2 changes: 1 addition & 1 deletion src/pod-security-policy/host-namespaces/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spsphostnamespace
annotations:
metadata.gatekeeper.sh/title: "Host Namespace"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Disallows sharing of host PID and IPC namespaces by pod containers.
Corresponds to the `hostPID` and `hostIPC` fields in a PodSecurityPolicy.
Expand Down
5 changes: 5 additions & 0 deletions src/pod-security-policy/host-namespaces/src.rego
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package k8spsphostnamespace

import data.lib.exclude_update_patch.is_update_or_patch

violation[{"msg": msg, "details": {}}] {
# spec.hostPID and spec.hostIPC fields are immutable.
not is_update_or_patch(input.review)

input_share_hostnamespace(input.review.object)
msg := sprintf("Sharing the host namespace is not allowed: %v", [input.review.object.metadata.name])
}
Expand Down
2 changes: 1 addition & 1 deletion src/pod-security-policy/host-network-ports/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spsphostnetworkingports
annotations:
metadata.gatekeeper.sh/title: "Host Networking Ports"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Controls usage of host network namespace by pod containers. Specific
ports must be specified. Corresponds to the `hostNetwork` and
Expand Down
4 changes: 4 additions & 0 deletions src/pod-security-policy/host-network-ports/src.rego
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package k8spsphostnetworkingports

import data.lib.exclude_update_patch.is_update_or_patch
import data.lib.exempt_container.is_exempt

violation[{"msg": msg, "details": {}}] {
# spec.hostNetwork field is immutable.
not is_update_or_patch(input.review)

input_share_hostnetwork(input.review.object)
msg := sprintf("The specified hostNetwork and hostPort are not allowed, pod: %v. Allowed values: %v", [input.review.object.metadata.name, input.parameters])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspprivilegedcontainer
annotations:
metadata.gatekeeper.sh/title: "Privileged Container"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Controls the ability of any container to enable privileged mode.
Corresponds to the `privileged` field in a PodSecurityPolicy. For more
Expand Down
4 changes: 4 additions & 0 deletions src/pod-security-policy/privileged-containers/src.rego
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package k8spspprivileged

import data.lib.exclude_update_patch.is_update_or_patch
import data.lib.exempt_container.is_exempt

violation[{"msg": msg, "details": {}}] {
# spec.containers.privileged field is immutable.
not is_update_or_patch(input.review)

c := input_containers[_]
not is_exempt(c)
c.securityContext.privileged
Expand Down
2 changes: 1 addition & 1 deletion src/pod-security-policy/proc-mount/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspprocmount
annotations:
metadata.gatekeeper.sh/title: "Proc Mount"
metadata.gatekeeper.sh/version: 1.0.1
metadata.gatekeeper.sh/version: 1.0.2
description: >-
Controls the allowed `procMount` types for the container. Corresponds to
the `allowedProcMountTypes` field in a PodSecurityPolicy. For more
Expand Down
4 changes: 4 additions & 0 deletions src/pod-security-policy/proc-mount/src.rego
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package k8spspprocmount

import data.lib.exclude_update_patch.is_update_or_patch
import data.lib.exempt_container.is_exempt

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

c := input_containers[_]
not is_exempt(c)
allowedProcMount := get_allowed_proc_mount(input)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspreadonlyrootfilesystem
annotations:
metadata.gatekeeper.sh/title: "Read Only Root Filesystem"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Requires the use of a read-only root file system by pod containers.
Corresponds to the `readOnlyRootFilesystem` field in a
Expand Down
4 changes: 4 additions & 0 deletions src/pod-security-policy/read-only-root-filesystem/src.rego
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package k8spspreadonlyrootfilesystem

import data.lib.exclude_update_patch.is_update_or_patch
import data.lib.exempt_container.is_exempt

violation[{"msg": msg, "details": {}}] {
# spec.containers.readOnlyRootFilesystem field is immutable.
not is_update_or_patch(input.review)

c := input_containers[_]
not is_exempt(c)
input_read_only_root_fs(c)
Expand Down
2 changes: 1 addition & 1 deletion src/pod-security-policy/selinux/constraint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: k8spspselinuxv2
annotations:
metadata.gatekeeper.sh/title: "SELinux V2"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/version: 1.0.1
description: >-
Defines an allow-list of seLinuxOptions configurations for pod
containers. Corresponds to a PodSecurityPolicy requiring SELinux configs.
Expand Down
7 changes: 7 additions & 0 deletions src/pod-security-policy/selinux/src.rego
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package k8spspselinux

import data.lib.exclude_update_patch.is_update_or_patch
import data.lib.exempt_container.is_exempt

# Disallow top level custom SELinux options
violation[{"msg": msg, "details": {}}] {
# spec.securityContext.seLinuxOptions field is immutable.
not is_update_or_patch(input.review)

has_field(input.review.object.spec.securityContext, "seLinuxOptions")
not input_seLinuxOptions_allowed(input.review.object.spec.securityContext.seLinuxOptions)
msg := sprintf("SELinux options is not allowed, pod: %v. Allowed options: %v", [input.review.object.metadata.name, input.parameters.allowedSELinuxOptions])
}
# Disallow container level custom SELinux options
violation[{"msg": msg, "details": {}}] {
# spec.containers.securityContext.seLinuxOptions field is immutable.
not is_update_or_patch(input.review)

c := input_security_context[_]
not is_exempt(c)
has_field(c.securityContext, "seLinuxOptions")
Expand Down
Loading

0 comments on commit ff93bf1

Please sign in to comment.