What Is a Kubernetes ServiceAccount and How Does It Relate to RBAC?
A ServiceAccount is an identity for processes running inside Pods. Kubernetes automatically mounts a token for the Pod's ServiceAccount, and RBAC bindings grant that ServiceAccount specific API permissions. Every namespace has a default ServiceAccount.
Detailed Answer
A ServiceAccount provides an identity for processes running in a Pod. While Users and Groups represent people or external systems, ServiceAccounts represent workloads — your applications, controllers, CI/CD agents, and operators.
How ServiceAccounts Work
When a Pod starts, Kubernetes mounts a token at /var/run/secrets/kubernetes.io/serviceaccount/token. The kubelet obtains this token from the TokenRequest API. When the Pod makes API calls, it presents this token, and the API server authenticates it as the corresponding ServiceAccount.
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-service-account
namespace: production
labels:
app: my-application
Assigning a ServiceAccount to a Pod
Specify the ServiceAccount in the Pod spec:
apiVersion: v1
kind: Pod
metadata:
name: my-app
namespace: production
spec:
serviceAccountName: app-service-account
containers:
- name: app
image: my-app:1.0
resources:
requests:
cpu: "100m"
memory: "128Mi"
If you omit serviceAccountName, the Pod uses the default ServiceAccount in its namespace.
ServiceAccount Token Evolution
Understanding the token mechanism is important for both interviews and security:
Before Kubernetes 1.24:
- A Secret was automatically created for each ServiceAccount
- The token was long-lived (never expired) and not audience-bound
- This was a security risk — leaked tokens were valid indefinitely
Kubernetes 1.24 and later:
- No auto-created Secret-based tokens
- Tokens are issued by the TokenRequest API
- Tokens are short-lived (default 1 hour), audience-bound, and automatically rotated
- Projected as a volume into the Pod by the kubelet
# The projected token volume (automatically configured)
spec:
containers:
- name: app
image: my-app:1.0
volumeMounts:
- name: kube-api-access
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
readOnly: true
volumes:
- name: kube-api-access
projected:
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
name: kube-root-ca.crt
items:
- key: ca.crt
path: ca.crt
- downwardAPI:
items:
- path: namespace
fieldRef:
fieldPath: metadata.namespace
Connecting ServiceAccounts to RBAC
A ServiceAccount by itself has no permissions. You grant permissions by creating an RBAC binding:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: configmap-reader
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: production
name: app-configmap-access
subjects:
- kind: ServiceAccount
name: app-service-account
namespace: production
roleRef:
kind: Role
name: configmap-reader
apiGroup: rbac.authorization.k8s.io
Now any Pod running as app-service-account can read ConfigMaps in the production namespace.
Disabling Token Mounting
Some Pods never need to talk to the Kubernetes API (most application Pods). You can disable the automatic token mount to reduce the attack surface:
apiVersion: v1
kind: ServiceAccount
metadata:
name: no-api-access
namespace: production
automountServiceAccountToken: false
Or at the Pod level:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
serviceAccountName: no-api-access
automountServiceAccountToken: false
containers:
- name: app
image: my-app:1.0
Creating and Managing ServiceAccounts
# Create a ServiceAccount
kubectl create serviceaccount deploy-bot -n ci-cd
# List ServiceAccounts in a namespace
kubectl get serviceaccounts -n production
# Check which ServiceAccount a Pod uses
kubectl get pod my-app -n production -o jsonpath='{.spec.serviceAccountName}'
# Verify permissions of a ServiceAccount
kubectl auth can-i list pods \
--as=system:serviceaccount:production:app-service-account \
-n production
ImagePullSecrets with ServiceAccounts
ServiceAccounts can also carry image pull credentials, so every Pod using that ServiceAccount automatically pulls from a private registry:
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-service-account
namespace: production
imagePullSecrets:
- name: registry-credentials
Best Practices
- Create dedicated ServiceAccounts for each workload instead of using
default. - Disable token mounting for Pods that do not need API access.
- Apply least-privilege RBAC — only grant the verbs and resources the workload actually needs.
- Audit ServiceAccount bindings regularly to detect privilege creep.
- Use projected tokens (default in 1.24+) and avoid manually creating long-lived Secret-based tokens.
Why Interviewers Ask This
Interviewers ask this to assess whether you understand in-cluster identity and authorization. Misconfigured ServiceAccounts are a common attack vector in Kubernetes security incidents.
Common Follow-Up Questions
Key Takeaways
- ServiceAccounts are the identity mechanism for workloads running inside the cluster.
- Every namespace gets a default ServiceAccount, which should be locked down in production.
- Modern Kubernetes uses projected, short-lived tokens instead of long-lived Secrets.
- RBAC bindings link ServiceAccounts to specific permissions.