All Products
Search
Document Center

Container Service for Kubernetes:Use ServiceAccount token volume projection

Last Updated:Sep 11, 2024

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. 1.png

    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.

  1. Create a file named nginx.yaml with the following sample code. This configuration specifies that the pod uses a ServiceAccount with an audience of vault 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
  2. Run the following command to deploy an application running in the pod that uses volume projection:

    kubectl apply -f nginx.yaml
  3. Verify the expiration time of the token mounted in the pod.

    1. 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
    2. Download the token mounted in the container of the pod:

      kubectl exec -t nginx -- cat /var/run/secrets/tokens/vault-token > vault-token
    3. 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
Important
  • 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.