Users authenticate with certificates and tokens from outside. Pods need an identity from inside the cluster. That identity is a ServiceAccount.
Every Pod has one
kubectl get serviceaccounts -n citadel
kubectl get pod market-web-7d9c4c5b7f-k2m4x -o jsonpath='{.spec.serviceAccountName}'NAME SECRETS AGE
default 0 3m
defaultEach namespace gets a default ServiceAccount when it is created, and a Pod that names none runs as it. kubectl create serviceaccount ci makes another; spec.serviceAccountName: ci makes a Pod use it. Naming one that does not exist is an error at creation time.
The mounted token
Inside the container, the credential is a file:
kubectl exec market-web-7d9c4c5b7f-k2m4x -- ls /var/run/secrets/kubernetes.io/serviceaccountca.crt
namespace
tokenThat is the kube-api-access-… volume every Pod gets in describe. The Kubernetes client libraries read it automatically, so a program in the Pod that calls the API does so as the ServiceAccount, and the API server authorises it like any other subject.
The username is system:serviceaccount:<namespace>:<name>, and the groups include system:serviceaccounts. That is the string you put after --as to test what a Pod may do.
Turning it off
Most workloads never call the API. A token they do not need is a token an attacker in the container could use:
spec:
serviceAccountName: web
automountServiceAccountToken: falseThe flag works on the Pod or on the ServiceAccount itself. With it set, the directory is simply not there.