Scheduler Pod Specification File Permissions Are Restrictive
More Info:
Ensure that the scheduler pod specification file has permissions of 644 or more restrictive.
Risk Level
High
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every control plane node, check the current permissions of the scheduler pod specification file:
stat -c permissions=%a /etc/kubernetes/manifests/kube-scheduler.yaml -
If the reported permissions are more permissive than 644 (for example, 664, 666, 600 is fine, 640 is fine), set them to 644:
chmod 644 /etc/kubernetes/manifests/kube-scheduler.yaml -
(Optional but recommended) Confirm the file is owned by root (no change required by this control, just verify):
stat -c 'owner=%U group=%G' /etc/kubernetes/manifests/kube-scheduler.yaml -
Be aware: because this file is under
/etc/kubernetes/manifests, the kube-scheduler static pod may be briefly restarted by the kubelet when it detects the file change. Plan to make this change during a maintenance window if scheduler restarts are sensitive in your environment. -
Verify that the permissions are now 644 or more restrictive (e.g., 640, 600) on every control plane node:
/bin/sh -c 'if test -e /etc/kubernetes/manifests/kube-scheduler.yaml; then stat -c permissions=%a /etc/kubernetes/manifests/kube-scheduler.yaml; fi'
Using kubectl
kubectl cannot modify file permissions on control plane nodes, including /etc/kubernetes/manifests/kube-scheduler.yaml. This fix must be applied directly on each control plane node’s filesystem; see the Manual Steps section for the exact commands to run over SSH.
Automation
#!/usr/bin/env bash
#
# Fix CISKubernetes 1.1.5:
# Ensure scheduler pod specification file permissions are 644 or more restrictive.
#
# Run on: every control plane node (with root privileges)
# Safe to re-run (idempotent).
set -euo pipefail
SCHEDULER_MANIFEST="/etc/kubernetes/manifests/kube-scheduler.yaml"
TARGET_MODE="644"
CHANGED=0
echo "==> Checking kube-scheduler manifest at ${SCHEDULER_MANIFEST}"
if [ ! -e "${SCHEDULER_MANIFEST}" ]; then
echo "File not found: ${SCHEDULER_MANIFEST}"
echo "Nothing to change on this node."
exit 0
fi
# Get current mode as a 3-digit permission string (e.g. 644, 640, 600)
CURRENT_MODE="$(stat -c '%a' "${SCHEDULER_MANIFEST}")"
echo "Current permissions: ${CURRENT_MODE}"
echo "Target permissions : ${TARGET_MODE}"
# Normalize to 3 digits for comparison
pad3() {
local v="$1"
printf "%03d" "${v}"
}
CMODE="$(pad3 "${CURRENT_MODE}")"
TMODE="$(pad3 "${TARGET_MODE}")"
# Helper: check if mode is "more restrictive or equal" than 644.
# Logic:
# - owner perms: any value 0–7 are acceptable (CIS only constrains group/other)
# - group perms must be <= 4 (no write/execute)
# - other perms must be <= 4 (no write/execute)
is_restrictive_enough() {
local mode="$1"
local o="${mode:0:1}"
local g="${mode:1:1}"
local t="${mode:2:1}"
# group and other must not exceed 4
if [ "${g}" -le 4 ] && [ "${t}" -le 4 ]; then
return 0
fi
return 1
}
if is_restrictive_enough "${CMODE}"; then
echo "Permissions are already ${CURRENT_MODE}, which is 644 or more restrictive. No change needed."
else
echo "Permissions ${CURRENT_MODE} are too permissive. Setting to ${TARGET_MODE}..."
chmod "${TARGET_MODE}" "${SCHEDULER_MANIFEST}"
CHANGED=1
fi
echo "==> Verifying final permissions..."
FINAL_MODE="$(stat -c '%a' "${SCHEDULER_MANIFEST}")"
echo "Final permissions: ${FINAL_MODE}"
if ! is_restrictive_enough "$(pad3 "${FINAL_MODE}")"; then
echo "ERROR: Permissions still too permissive after chmod. Investigation required."
exit 1
fi
if [ "${CHANGED}" -eq 1 ]; then
echo "Permissions successfully updated to ${FINAL_MODE}."
else
echo "No changes were necessary; permissions remain compliant."
fi
# Re-run of the benchmark audit command for proof:
echo "==> Benchmark-style audit output:"
/bin/sh -c 'if test -e /etc/kubernetes/manifests/kube-scheduler.yaml; then stat -c permissions=%a /etc/kubernetes/manifests/kube-scheduler.yaml; fi'