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: falseYou 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:
- Time-limited: Tokens expire (default 1 hour, configurable up to 48 hours)
- Audience-bound: Tokens are scoped to a specific audience (the API server by default)
- 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:
- Create a dedicated service account for each deployment
- Grant only the RBAC permissions that specific workload needs
- Disable auto-mounting on the
defaultservice account - 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.
- ✓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
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?