Ensure Use Service Account Credentials Argument Is Enabled
More Info:
Use individual service account credentials for each controller
Risk Level
High
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
- On every control plane node, back up the current manifest:
sudo cp -a /etc/kubernetes/manifests/kube-controller-manager.yaml /etc/kubernetes/manifests/kube-controller-manager.yaml.bak
- Edit the controller manager manifest on that control plane node:
sudo vi /etc/kubernetes/manifests/kube-controller-manager.yaml
- In the
spec.containers[0].command(orargs) list, add or update the flag so it appears exactly as:
- --use-service-account-credentials=true
If a line with --use-service-account-credentials= already exists, change its value to true instead of adding a duplicate.
-
Save the file and exit the editor. The kubelet on that control plane node will automatically detect the manifest change and restart the
kube-controller-managerstatic pod; expect a brief controller-manager restart. -
After 30–60 seconds, verify the new flag is in effect on that control plane node:
/bin/ps -ef | grep kube-controller-manager | grep -v grep
Confirm the kube-controller-manager process command line includes:
--use-service-account-credentials=true
Using kubectl
kubectl cannot modify the kube-controller-manager static pod manifest or its process flags. This finding must be remediated by editing /etc/kubernetes/manifests/kube-controller-manager.yaml directly on every control plane node; see the Manual Steps section for exact instructions.
Automation
#!/usr/bin/env bash
#
# Remediation: Ensure --use-service-account-credentials=true for kube-controller-manager
# Scope: Run on every control plane node
# Effect: Editing /etc/kubernetes/manifests/kube-controller-manager.yaml will
# trigger an automatic restart of the kube-controller-manager static pod.
#
set -euo pipefail
MANIFEST="/etc/kubernetes/manifests/kube-controller-manager.yaml"
REQUIRED_ARG="--use-service-account-credentials=true"
echo "[INFO] Starting remediation for kube-controller-manager on host: $(hostname)"
if [[ ! -f "${MANIFEST}" ]]; then
echo "[ERROR] Manifest not found: ${MANIFEST}"
exit 1
fi
# Backup manifest once per run (idempotent-safe because we timestamp)
BACKUP="${MANIFEST}.$(date +%Y%m%d%H%M%S).bak"
cp "${MANIFEST}" "${BACKUP}"
echo "[INFO] Backup created at ${BACKUP}"
# Check if argument already present with correct value
if grep -qE '[[:space:]]-'"${REQUIRED_ARG}" "${MANIFEST}"; then
echo "[INFO] Required argument already present: ${REQUIRED_ARG}"
else
echo "[INFO] Updating ${MANIFEST} to ensure ${REQUIRED_ARG} is set"
# If any existing --use-service-account-credentials argument exists, remove it
# to avoid duplicates and ensure the value is true.
if grep -q -- "--use-service-account-credentials=" "${MANIFEST}"; then
# Remove any line containing the flag; safe as long as used only once in args list
tmpfile="$(mktemp)"
sed '/--use-service-account-credentials=/d' "${MANIFEST}" > "${tmpfile}"
mv "${tmpfile}" "${MANIFEST}"
echo "[INFO] Removed existing --use-service-account-credentials lines"
fi
# Insert the required arg in the args list under kube-controller-manager container.
# This assumes a standard kubeadm-style static pod manifest with 'containers:' and 'name: kube-controller-manager'.
tmpfile="$(mktemp)"
awk -v arg="${REQUIRED_ARG}" '
$0 ~ /name:[[:space:]]*kube-controller-manager/ { in_kcm=1 }
in_kcm && $0 ~ /^[[:space:]]*args:[[:space:]]*$/ { in_args=1 }
in_kcm && in_args && $0 !~ /^[[:space:]]*-[[:space:]]/ && $0 !~ /^[[:space:]]*#/ && $0 !~ /^[[:space:]]*$/ { in_args=0 }
{
print $0
if (in_kcm && in_args && $0 ~ /^[[:space:]]*args:[[:space:]]*$/) {
print " - " arg
}
}
' "${MANIFEST}" > "${tmpfile}"
# If awk failed to add the argument (e.g. non-standard manifest), fall back to simple append
if ! grep -qE '[[:space:]]-'"${REQUIRED_ARG}" "${tmpfile}"; then
echo "[WARN] Could not locate standard args section; appending argument under containers section"
awk -v arg="${REQUIRED_ARG}" '
$0 ~ /name:[[:space:]]*kube-controller-manager/ { in_kcm=1 }
in_kcm && $0 ~ /^[[:space:]]*image:[[:space:]]*/ && !printed {
print $0
print " args:"
print " - " arg
printed=1
next
}
{ print $0 }
' "${MANIFEST}" > "${tmpfile}"
fi
mv "${tmpfile}" "${MANIFEST}"
echo "[INFO] Manifest updated. kube-controller-manager static pod will restart automatically."
fi
# Verification: wait for kube-controller-manager process to expose the flag
echo "[INFO] Verifying kube-controller-manager process has ${REQUIRED_ARG} enabled"
# Give kubelet some time to restart the static pod if it changed
sleep 10
if /bin/ps -ef | grep kube-controller-manager | grep -v grep | grep -q -- "${REQUIRED_ARG}"; then
echo "[SUCCESS] kube-controller-manager is running with ${REQUIRED_ARG}"
exit 0
else
echo "[ERROR] kube-controller-manager process is not running with ${REQUIRED_ARG}"
echo "[INFO] Current kube-controller-manager processes:"
/bin/ps -ef | grep kube-controller-manager | grep -v grep || true
exit 2
fi
Usage (run on every control plane node):
chmod +x ./fix-use-service-account-credentials.sh
sudo ./fix-use-service-account-credentials.sh