> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API Server Should Disable Service Account Extend Token Expiration

### More Info:

Verifies that --service-account-extend-token-expiration is set to false so bound service account tokens are not automatically extended to long lifetimes, reducing token exposure.

### Risk Level

High

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every control plane node, back up the existing manifest before editing:
           ```bash theme={null}
           sudo cp -a /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak
           ```

        2. On every control plane node, open the kube-apiserver static pod manifest for editing:
           ```bash theme={null}
           sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
           ```

        3. In the container `command:` section, either add or modify the flag so it is present exactly as:
           ```yaml theme={null}
           - --service-account-extend-token-expiration=false
           ```
           Ensure there is no other `--service-account-extend-token-expiration` flag with a different value in the file, then save and exit.\
           Note: editing this file will cause the kube-apiserver static pod to be restarted automatically by the kubelet.

        4. Wait 30–60 seconds for the kube-apiserver pod to restart, then confirm the apiserver container is running (on any control plane node):
           ```bash theme={null}
           sudo crictl ps | grep kube-apiserver
           ```
           (If `crictl` is not available, use `sudo docker ps | grep kube-apiserver` on nodes using Docker.)

        5. On every control plane node, verify the running process includes the correct flag value:
           ```bash theme={null}
           /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -- '--service-account-extend-token-expiration=false'
           ```
           Ensure this command returns at least one line and that there is no line showing `--service-account-extend-token-expiration=true`.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify the kube-apiserver static pod manifest or its process flags, so this setting cannot be fixed via the Kubernetes API. To remediate, you must edit `/etc/kubernetes/manifests/kube-apiserver.yaml` directly on every control plane node; follow the Manual Steps section for the exact host-level changes.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Remediate CIS Kubernetes 1.2.30:
        # Ensure --service-account-extend-token-expiration is set to false
        # Target: every control plane node
        #
        # Usage: run as root on each control plane node.
        #   sudo bash ./fix-service-account-extend-token-expiration.sh

        set -euo pipefail

        APISERVER_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
        BACKUP_DIR="/etc/kubernetes/manifests/backup-cis-1.2.30"
        PARAM_NAME="service-account-extend-token-expiration"
        DESIRED_VALUE="false"

        echo "[INFO] Starting remediation for CIS 1.2.30 on this control plane node"

        if [[ $EUID -ne 0 ]]; then
          echo "[ERROR] This script must be run as root." >&2
          exit 1
        fi

        if [[ ! -f "${APISERVER_MANIFEST}" ]]; then
          echo "[ERROR] kube-apiserver manifest not found at ${APISERVER_MANIFEST}" >&2
          exit 1
        fi

        mkdir -p "${BACKUP_DIR}"

        TS="$(date +%Y%m%d-%H%M%S)"
        BACKUP_FILE="${BACKUP_DIR}/kube-apiserver.yaml.${TS}"
        cp "${APISERVER_MANIFEST}" "${BACKUP_FILE}"
        echo "[INFO] Backed up ${APISERVER_MANIFEST} to ${BACKUP_FILE}"

        # Function to ensure the desired flag is present and set to false
        ensure_flag() {
          local file="$1"
          local param="$2"
          local value="$3"

          # If line with parameter exists, replace it to ensure correct value
          if grep -q -- "--${param}=" "${file}"; then
            # If already correctly set, do nothing
            if grep -q -- "--${param}=${value}" "${file}"; then
              echo "[INFO] --${param} already set to ${value}; no change needed"
              return 0
            fi
            echo "[INFO] Updating existing --${param} flag to ${value}"
            # Replace the value while preserving YAML formatting
            # This substitution changes only the flag value, not indentation or other content
            sed -i "s#--${param}=[^\"']*#--${param}=${value}#g" "${file}"
          else
            echo "[INFO] Adding --${param}=${value} flag under kube-apiserver command section"
            # Insert the flag after the kube-apiserver command line in the manifest.
            # We look for the line containing 'kube-apiserver' in the container command list.
            # This is a heuristic but is safe and idempotent: we only add if missing.
            awk -v p="--${param}=${value}" '
              # Once we see kube-apiserver line inside the command list, we remember and
              # insert the flag on the following line (with same indentation plus two spaces).
              /kube-apiserver/ && in_cmd == 0 {
                print $0
                # capture indentation of this line
                indent = match($0, /[^ ]/)-1
                pad = sprintf("%*s", indent+2, "")
                print pad "- " p
                in_cmd = 1
                next
              }
              { print $0 }
            ' "${file}" > "${file}.tmp"

            mv "${file}.tmp" "${file"
            }
        }

        ensure_flag "${APISERVER_MANIFEST}" "${PARAM_NAME}" "${DESIRED_VALUE}"

        echo "[INFO] Changes applied to ${APISERVER_MANIFEST}."
        echo "[INFO] Because this is a static pod manifest, the kube-apiserver pod will be restarted automatically by the kubelet."

        # Wait for kube-apiserver process to reflect updated flag
        echo "[INFO] Waiting for kube-apiserver to restart with new flags..."
        SLEEP_SECS=5
        MAX_WAIT_SECS=180
        elapsed=0

        while true; do
          if /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q -- "--${PARAM_NAME}=${DESIRED_VALUE}"; then
            echo "[INFO] Verification successful: kube-apiserver is running with --${PARAM_NAME}=${DESIRED_VALUE}"
            break
          fi
          if (( elapsed >= MAX_WAIT_SECS )); then
            echo "[ERROR] Timed out waiting for kube-apiserver to start with --${PARAM_NAME}=${DESIRED_VALUE}" >&2
            echo "[INFO] Current kube-apiserver process flags:" >&2
            /bin/ps -ef | grep kube-apiserver | grep -v grep || true
            exit 1
          fi
          sleep "${SLEEP_SECS}"
          elapsed=$((elapsed + SLEEP_SECS))
        done

        echo "[INFO] CIS 1.2.30 remediation completed on this control plane node."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
