The ServiceAccount token serves as an authentication credential that enables secure communication between applications running in a pod and the Kubernetes API. To address security risks associated with the traditional method of automatically mounting ServiceAccount tokens as Secrets in pods, you can use the Service Account Token Volume Projection feature provided by Container Service for Kubernetes (ACK). This feature allows you to mount ServiceAccount tokens or related certificates into containers as volume projections, which reduces the risk of secret exposure.
Feature introduction
A service account provides an identity for communication between pods and the API server of the cluster. Use service accounts in the traditional way may face the following challenges:
The JSON Web Tokens (JWTs) in service accounts are not bound to
audience
identities. A user of a service account can masquerade as another user and launch masquerade attacks.Traditionally, each service account is stored in a Secret and delivered as a file to the corresponding application node. Service accounts used by system components may be granted unnecessary permissions. Attackers can obtain these service accounts to launch privilege escalation attacks, which results in a broad attack surface for the Kubernetes control plane.
JWTs are not time-bound. A JWT that is compromised in the aforementioned attacks stays valid for as long as the service account exists. You can mitigate the issue only by rotating the private key of the service account. However, client-go does not support automated key rotation. You must perform manual key rotation, which is complex.
A Secret must be created for each service account. This may downgrade elasticity and capacity in large-scale workload deployments.
The ServiceAccount token volume projection feature enhances the security of ServiceAccounts, providing ServiceAccount-related authentication information to pods in a more secure and flexible manner. This feature allows pods to mount ServiceAccounts into containers in the form of volume projections, avoiding the dependency on Secrets.
Prerequisites
An ACK managed cluster, ACK dedicated cluster, or ACK Serverless cluster that runs Kubernetes 1.20 or later is created. For more information, see Create an ACK managed cluster, Create an ACK dedicated cluster, and Create an ACK Serverless cluster.
The ServiceAccount token volume projection feature is enabled during the cluster creation process.
By default, the ServiceAccount token volume projection feature is enabled in clusters that run Kubernetes 1.22 or later. To upgrade the cluster, see Manually update ACK clusters.
The API server and controller-manager of system components automatically enable the feature gate for binding ServiceAccount token volume projection, and add the following configuration in the startup parameters of the API server.
Parameter
Description
Default value
Console configuration
service-account-issuer
The issuer of the ServiceAccount token, which corresponds to the
iss
field in the token payload.https://kubernetes.default.svc
Supported.
api-audiences
The identifiers of the API, used to validate the request tokens for the API server service.
https://kubernetes.default.svc
Supported. More than one
audience
can be configured, separated by commas (,
).service-account-signing-key-file
The file path of the private key that signs the token.
/etc/kubernetes/pki/sa.key
Not supported. Default value: /etc/kubernetes/pki/sa.key.
Step 1: Create a ServiceAccount object
By default, each namespace comes with a default
ServiceAccount, which you can view by running the kubectl get serviceaccounts
command. To assign additional identities to processes running in the pod, you can create a new ServiceAccount by using the following code:
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
EOF
After the ServiceAccount is created, you can view the complete information of the ServiceAccount by running the kubectl get serviceaccounts/build-robot -o yaml
command.
Step 2: Deploy a pod application that uses ServiceAccount token volume projection
You can project the ServiceAccount into a pod as a volume, allowing the container in the pod to use the token to access the API server of the cluster and authenticate with the ServiceAccount. For example, you can specify the audience
, expiration time (expirationSeconds
), and other properties of the token, and project these into an application that runs in the pod.
Create a file named nginx.yaml with the following sample code. This configuration specifies that the pod uses a ServiceAccount with an
audience
ofvault
and an expiration time of 2 hours.apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - image: nginx 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: vault
Run the following command to deploy an application running in the pod that uses volume projection:
kubectl apply -f nginx.yaml
Verify the expiration time of the token mounted in the pod.
Run the following command to confirm that the pod runs as expected:
kubectl get pod nginx
Expected output:
NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 3m15s
Download the token mounted in the container of the pod:
kubectl exec -t nginx -- cat /var/run/secrets/tokens/vault-token > vault-token
Run the following command to get the token expiration 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
Ensure that the pod can retrieve the latest rotated token in real time by periodically reloading the target token, preferably every 5 minutes. Official Kubernetes supports automatic token retrieval in client-go version 10.0.0 or later.
The file permissions for the ServiceAccount token in the container are updated from 644 to 600. When you use the bound ServiceAccount token volume projection, the file permissions are now set to 600, and to 640 if the
fsGroup
feature is enabled.