π€ Generated by the Agentic Engineer
Evidence
CKV_K8S_38 ("service account tokens are only mounted where necessary") is the second-largest
group in #2787's checkov backlog β 8 of the 42 Kubernetes-framework findings measured on main
2026-07-28:
| workload |
file |
Deployment.kube-system.coredns |
k8s/providers/docker/infrastructure/controllers/coredns/deployment.yaml |
CronJob.longhorn-system.longhorn-stale-node-cleanup |
k8s/providers/hetzner/infrastructure/controllers/longhorn/cron-job-stale-node-cleanup.yaml |
Job.openbao.vault-snapshot-init |
k8s/bases/infrastructure/vault-backup/job.yaml |
CronJob.openbao.vault-snapshot |
k8s/bases/infrastructure/vault-backup/cron-job.yaml |
Job.openbao.vault-config |
k8s/bases/infrastructure/vault-config/job.yaml |
Deployment.opencost.opencost-usage-scraper |
k8s/bases/infrastructure/opencost/components/usage-scraper/deployment.yaml |
Deployment.cdi.cdi-operator |
k8s/bases/infrastructure/controllers/cdi/cdi-operator.yaml |
Deployment.kubevirt.virt-operator |
k8s/bases/infrastructure/controllers/kubevirt/kubevirt-operator.yaml |
Why it matters
A mounted service-account token is a credential sitting in the container filesystem. Where the
workload never calls the API server it buys nothing and is simply reachable by anything that gets
code execution in that pod β which is the whole reason the check exists. Kubescape does not cover
this: its own exception CRs disable the pod-security controls cluster-wide, and the Kyverno
pod-security policies match kinds: [Pod] while k8s/ contains no Pod objects.
Why this is NOT a blanket sweep
At least three of the eight legitimately need their token β the KubeVirt and CDI operators are
controllers, and the Longhorn cleanup CronJob acts on nodes through the API. Setting
automountServiceAccountToken: false across all eight would break them. Each workload needs an
individual verdict, and the ones that keep the token need that recorded so the next pass does not
re-litigate it.
What
Per workload, either set automountServiceAccountToken: false on the pod spec, or record in the
manifest why the token is required. Prefer the pod-spec field over the ServiceAccount-level one so
the decision is visible where the workload is defined.
Acceptance criteria
Size: M β eight small diffs plus a per-workload judgement, and the verification is the
expensive half.
Part of #2787. Depends on the measurement child for its before/after count.
Evidence
CKV_K8S_38("service account tokens are only mounted where necessary") is the second-largestgroup in #2787's checkov backlog β 8 of the 42 Kubernetes-framework findings measured on
main2026-07-28:
Deployment.kube-system.corednsk8s/providers/docker/infrastructure/controllers/coredns/deployment.yamlCronJob.longhorn-system.longhorn-stale-node-cleanupk8s/providers/hetzner/infrastructure/controllers/longhorn/cron-job-stale-node-cleanup.yamlJob.openbao.vault-snapshot-initk8s/bases/infrastructure/vault-backup/job.yamlCronJob.openbao.vault-snapshotk8s/bases/infrastructure/vault-backup/cron-job.yamlJob.openbao.vault-configk8s/bases/infrastructure/vault-config/job.yamlDeployment.opencost.opencost-usage-scraperk8s/bases/infrastructure/opencost/components/usage-scraper/deployment.yamlDeployment.cdi.cdi-operatork8s/bases/infrastructure/controllers/cdi/cdi-operator.yamlDeployment.kubevirt.virt-operatork8s/bases/infrastructure/controllers/kubevirt/kubevirt-operator.yamlWhy it matters
A mounted service-account token is a credential sitting in the container filesystem. Where the
workload never calls the API server it buys nothing and is simply reachable by anything that gets
code execution in that pod β which is the whole reason the check exists. Kubescape does not cover
this: its own exception CRs disable the pod-security controls cluster-wide, and the Kyverno
pod-security policies match
kinds: [Pod]whilek8s/contains no Pod objects.Why this is NOT a blanket sweep
At least three of the eight legitimately need their token β the KubeVirt and CDI operators are
controllers, and the Longhorn cleanup CronJob acts on nodes through the API. Setting
automountServiceAccountToken: falseacross all eight would break them. Each workload needs anindividual verdict, and the ones that keep the token need that recorded so the next pass does not
re-litigate it.
What
Per workload, either set
automountServiceAccountToken: falseon the pod spec, or record in themanifest why the token is required. Prefer the pod-spec field over the ServiceAccount-level one so
the decision is visible where the workload is defined.
Acceptance criteria
false, ora comment naming the API access that requires it.
CKV_K8S_38reports zero remaining findings it can act on, measured with the reproduciblecommand from the measurement child.
controller that silently loses API access fails quietly.
ClusterSecurityExceptionor linter suppression is added; this is fixed at the manifest.Size: M β eight small diffs plus a per-workload judgement, and the verification is the
expensive half.
Part of #2787. Depends on the measurement child for its before/after count.