ServiceAccount tokens authenticate communication between pods and the Kubernetes API server. The traditional approach stores tokens in Secrets and mounts them as files—leaving pods exposed to impersonation attacks, privilege escalation, and stale tokens that never expire. Service Account Token Volume Projection eliminates these risks by mounting short-lived, audience-bound tokens directly as projected volumes, without relying on Secrets.
Background
Traditional ServiceAccount tokens have four structural security weaknesses:
Unbound audience: JSON Web Tokens (JWTs) carry no
audiencerestriction, so a compromised token can be replayed against any service in the cluster, enabling impersonation attacks.Overprivileged Secrets: Tokens are stored in Secrets and delivered as files to nodes. System-component tokens often carry permissions beyond what individual workloads need, expanding the attack surface.
No expiry: JWTs remain valid for the entire lifetime of the ServiceAccount. Rotating them requires manually replacing the signing key—a process client-go does not automate.
Secret sprawl: One Secret per ServiceAccount degrades cluster elasticity at scale.
ServiceAccount token volume projection addresses all four problems. Tokens are scoped to a specific audience, expire after a configurable period, and are automatically rotated by the kubelet—no Secrets required.
How it works
When a pod with a projected ServiceAccount token volume starts, the kubelet requests a short-lived, signed token from the API server and writes it to the configured mount path inside the container. The kubelet monitors the token and proactively requests a replacement before it expires. The application is responsible for reloading the token file when it rotates; polling every five minutes is sufficient for most workloads.
Prerequisites
Before you begin, ensure that you have:
An ACK managed cluster, ACK dedicated cluster, or ACK Serverless cluster running Kubernetes 1.20 or later. See Create an ACK managed cluster, Create an ACK dedicated cluster (discontinued), and Create an ACK Serverless cluster.
Service Account Token Volume Projection enabled on the cluster. The feature is on by default in clusters running Kubernetes 1.22 or later. To upgrade, see Manually upgrade ACK clusters.
When enabled, the API server and controller-manager automatically configure the following startup parameters:
Parameter Description Default value Console configurable service-account-issuerThe token issuer, mapped to the issfield in the JWT payloadhttps://kubernetes.default.svcYes api-audiencesAPI identifiers used to validate incoming tokens. Separate multiple values with commas ( ,).https://kubernetes.default.svcYes service-account-signing-key-filePath to the private key used to sign tokens /etc/kubernetes/pki/sa.keyNo (fixed at default)
Step 1: Create a ServiceAccount
Each namespace includes a default ServiceAccount. Run kubectl get serviceaccounts to list existing accounts in the current namespace.
To assign a distinct identity to a pod, create a dedicated ServiceAccount:
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
EOFVerify the ServiceAccount was created:
kubectl get serviceaccounts/build-robot -o yamlStep 2: Deploy a pod with token volume projection
The following example mounts a projected ServiceAccount token into an nginx pod. The token is scoped to the vault audience and expires after two hours (7200 seconds).
Create a file named
nginx.yaml:apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 name: nginx volumeMounts: - mountPath: /var/run/secrets/tokens name: vault-token serviceAccountName: build-robot volumes: - name: vault-token projected: sources: - serviceAccountToken: path: vault-token expirationSeconds: 7200 audience: vaultApply the manifest:
kubectl apply -f nginx.yaml
Verify token expiry
Confirm the pod is running:
kubectl get pod nginxExpected output:
NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 3m15sExtract the token from the container:
kubectl exec -t nginx -- cat /var/run/secrets/tokens/vault-token > vault-tokenDecode the token and print its expiry time:
cat vault-token | awk -F '.' '{print $2}' | base64 -d 2>/dev/null | jq '.exp' | xargs -I {} date -d @{}Sample output:
Mon Aug 26 15:45:59 CST 2024
Usage notes
Token rotation: The kubelet automatically rotates the token before it expires. Configure your application to reload the token file on a schedule—polling every five minutes is sufficient regardless of the actual TTL.
SDK compatibility: Automatic token reloading in Go requires client-go version 10.0.0 or later.
File permissions: The ServiceAccount token file permission changes from 644 to 600 when using bound token volume projection. If fsGroup is set in the pod's security context, the permission is 640.
What's next
Configure ServiceAccount RAM permissions for pod access control through RRSA: Use RAM Roles for Service Accounts (RRSA) to apply pod-level RAM permissions and restrict access to specific cloud resources.
Alibaba Cloud KMS for disk encryption: Encrypt Kubernetes secret keys in ACK Pro clusters using Key Management Service (KMS).
Configure service accounts for pods: Kubernetes upstream documentation on service account configuration.