Skip to main content

More Info:

Pods that do not need to access the Kubernetes API should not mount service account tokens. Disabling token automounting reduces the blast radius of a compromised pod.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS AKS

Triage and Remediation

Remediation

Manual Steps

  1. List service accounts with default token behavior
    • Run on: any machine with kubectl access
    • This shows service accounts that are not explicitly set to automountServiceAccountToken: false (including those inheriting the cluster default).
  2. Identify workloads that will mount tokens via their service accounts
    • Run on: any machine with kubectl access
    • Note: If .spec.automountServiceAccountToken is empty, the pod uses the behavior of its referenced service account (or namespace/cluster default).
  3. Review which pods actually need API access
    • For a sample of pods from step 2 (start with those in non-system namespaces), inspect their full spec and containers to determine if they interact with the Kubernetes API (client libraries, kubeconfig usage, KUBERNETES_SERVICE_HOST/KUBERNETES_PORT env usage, etc.):
    • Decide per workload: “Requires Kubernetes API access” vs “Does NOT require Kubernetes API access.”
  4. Update workload templates to disable token automount where not needed
    • For each deployment/statefulset/daemonset/job whose pods do NOT need API access, edit its manifest (or use kubectl edit) to add automountServiceAccountToken: false to the pod template:
    • Run on: any machine with kubectl access
    • In the opened YAML, under spec.template.spec, ensure:
    • Save and exit; the controller will recreate pods with tokens disabled.
  5. Optionally harden service accounts for non-API workloads
    • For service accounts used only by non-API workloads, set automountServiceAccountToken: false on the service account itself (so future pods using it do not mount tokens by default):
  6. Verify that service account tokens are not mounted where unnecessary
    • Re-run the pod inspection to confirm automountServiceAccountToken: false is set on pod specs that should not have tokens:
    • For a spot check, confirm the token volume is absent inside a pod that should not have a token:
    • No files found there (or the directory missing) indicates the token is not mounted.
Review guidance:
  • If a ServiceAccount has automountServiceAccountToken: false, pods using it will not auto-mount tokens unless overridden at pod level.
  • If the field is missing or true, pods using that ServiceAccount will auto-mount tokens unless the pod spec disables it.

Review guidance:
  • The 4th column is the pod-level setting:
    • false → token will not be mounted for that pod (good for workloads that do not need API access).
    • true → token will be mounted (needs review: does this pod really need API access?).
    • <no value> (blank) → pod inherits behavior from its ServiceAccount; see step 1.
Focus review on:
  • Pods whose function clearly does not need Kubernetes API access but show true or blank with a true/unset ServiceAccount.
  • High-privilege or internet-facing workloads where reducing token exposure is especially important.

Review guidance:
  • In .spec.template.spec of the workload:
    • automountServiceAccountToken: false → template is configured to avoid mounting tokens.
    • Missing or true → template will mount tokens (or inherit from ServiceAccount), and should be reviewed for necessity.
Use this pattern for other controllers (StatefulSet, DaemonSet, CronJob, Job) by swapping the resource kind in the command.
How to interpret the output:
  • Section 1: SA_AUTOMOUNT of true or default(true) means pods using that ServiceAccount will mount tokens unless they override spec.automountServiceAccountToken: false. Review these ServiceAccounts; for workloads that do not need API access, consider setting automountServiceAccountToken: false on the ServiceAccount and/or in the pod template.
  • Section 2: Lists all pods, showing:
    • POD_AUTOMOUNT: true or inherit-from-SA/namespace-default means the pod is mounting or likely mounting the token.
    • SA_AUTOMOUNT: true or default(true) means the ServiceAccount is also allowing mounts. Focus review on pods where:
    • POD_AUTOMOUNT is true or inherit-from-SA/namespace-default, and
    • You know the workload does not need to talk to the Kubernetes API.
  • Section 3: Heuristic list of pods that likely do NOT need API access but are auto-mounting tokens (based on simple text matches in command/args). This is only a starting point for human review; it can miss or misclassify workloads. For each candidate, inspect its deployment/statefulset/cronjob and decide whether to set:
    • spec.automountServiceAccountToken: false in the pod template, and/or
    • automountServiceAccountToken: false on the ServiceAccount.
This script does not attempt to change any resources; all remediation decisions and edits must be made manually in the workload manifests.