Cyber Intelligence
Authentication, Authorization and RBAC · Access control

L6. Service Account Hardening and Token Projection

Video generating

Check back soon for the video lesson on Service Account Hardening and Token Projection

Every pod runs under a service account. Learn how to harden service accounts by disabling auto-mounting, using projected tokens, and binding permissions to specific workloads.

The Default Service Account Problem

Every namespace in Kubernetes has a default service account. If you create a pod without specifying a service account, it uses default. By default, a token for this service account is mounted into the pod at /var/run/secrets/kubernetes.io/serviceaccount/token.

The problem: if any RBAC permissions are bound to the default service account (which happens more often than you might expect), every pod in that namespace inherits those permissions.

Disable Auto-Mounting

For pods that do not need to call the Kubernetes API, disable token mounting:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: default
  namespace: production
automountServiceAccountToken: false

You can also disable it at the pod level:

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  automountServiceAccountToken: false
  containers:
<ul class="list-disc pl-6 mb-4 space-y-2">
<li class="text-slate-300">name: app</li>
</ul>
      image: my-app:latest
Best practice: Set automountServiceAccountToken: false on the default service account in every namespace. Create dedicated service accounts for workloads that actually need API access.

Projected Service Account Tokens

Kubernetes v1.24+ uses projected volumes for service account tokens instead of long-lived secrets. Projected tokens have three advantages:

  1. Time-limited: Tokens expire (default 1 hour, configurable up to 48 hours)
  2. Audience-bound: Tokens are scoped to a specific audience (the API server by default)
  3. Pod-bound: Tokens are invalidated when the pod is deleted

Configure a custom projected token with specific audience and expiration:

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  serviceAccountName: my-app-sa
  containers:
<ul class="list-disc pl-6 mb-4 space-y-2">
<li class="text-slate-300">name: app</li>
</ul>
      image: my-app:latest
      volumeMounts:
<ul class="list-disc pl-6 mb-4 space-y-2">
<li class="text-slate-300">name: token</li>
</ul>
          mountPath: /var/run/secrets/tokens
  volumes:
<ul class="list-disc pl-6 mb-4 space-y-2">
<li class="text-slate-300">name: token</li>
</ul>
      projected:
        sources:
<ul class="list-disc pl-6 mb-4 space-y-2">
<li class="text-slate-300">serviceAccountToken:</li>
</ul>
              path: api-token
              expirationSeconds: 3600
              audience: https://my-api.example.com

One Service Account per Workload

Follow the principle of one service account per application:

  1. Create a dedicated service account for each deployment
  2. Grant only the RBAC permissions that specific workload needs
  3. Disable auto-mounting on the default service account
  4. Use projected tokens with minimal expiration

This isolation ensures that compromising one pod does not give access to another workload's permissions.

Detecting Overprivileged Service Accounts

Audit your cluster for service accounts with excessive permissions:

# List all ClusterRoleBindings referencing service accounts
kubectl get clusterrolebindings -o json | \
  jq '.items[] | select(.subjects[]?.kind=="ServiceAccount") |
  {name: .metadata.name, role: .roleRef.name,
   subjects: [.subjects[] | select(.kind=="ServiceAccount")]}'

Look for service accounts bound to cluster-admin, admin, or custom roles with wildcard permissions.

Exam Focus Points
  • The default service account in every namespace auto-mounts a token into all pods that do not specify a service account
  • Set automountServiceAccountToken: false on the default service account in every namespace
  • Projected tokens (v1.24+) are time-limited, audience-bound, and invalidated when the pod is deleted
  • Follow the pattern of one dedicated service account per workload with minimal RBAC permissions
  • Audit ClusterRoleBindings for service accounts bound to cluster-admin or roles with wildcard permissions
Knowledge Check

1. What happens if you create a pod without specifying a service account?

2. What are the three advantages of projected service account tokens over legacy secret-based tokens?

3. Where should you disable automountServiceAccountToken to protect an entire namespace?