Service Accounts: Managing Pod Identity in Kubernetes
Learn how to use a Kubernetes ServiceAccount to provide your applications with a secure, unique identity and control their access to cluster resources.

Previously in this course, we explored Security Contexts to restrict what a container can do at the OS level. While that secures the container's interaction with the host, it doesn't solve the problem of how a Pod identifies itself to the cluster itself.
In the world of microservices, your code often needs to talk to the Kubernetes API—perhaps to list other Pods, check the status of a deployment, or watch for configuration changes. You shouldn't use your personal admin credentials for this. Instead, we use a ServiceAccount.
What is a ServiceAccount?
A ServiceAccount is an object within Kubernetes that provides an identity for processes running in a Pod. Think of it as a "service user" for your application. When a Pod is created, it is automatically assigned the default ServiceAccount if you don't specify one.
By default, this default ServiceAccount has minimal permissions. However, as your applications grow, you’ll likely need to implement Authentication and Authorization patterns to ensure your apps can perform specific tasks within the cluster without being over-privileged.
The Anatomy of Pod Identity
Every ServiceAccount creates a token that is automatically mounted into the Pod's filesystem. This token allows the application to authenticate against the API server.
When you want to give a Pod special permissions, you don't assign them to the Pod directly; you assign them to the ServiceAccount. This is a core tenet of RBAC (Role-Based Access Control). By decoupling the identity (the ServiceAccount) from the workload (the Pod), you can easily rotate credentials or update permissions without rebuilding your container images.
Worked Example: Creating and Attaching a ServiceAccount
Let’s create a custom ServiceAccount for our web application and attach it to a Pod.
1. Create the ServiceAccount YAML (app-sa.yaml):
YAMLapiVersion: v1 kind: ServiceAccount metadata: name: web-app-sa
Apply it with kubectl apply -f app-sa.yaml.
2. Attach it to your Pod:
In your Pod manifest, you add the serviceAccountName field under the spec section. This tells Kubernetes to mount the identity of web-app-sa into this specific Pod.
YAMLapiVersion: v1 kind: Pod metadata: name: my-web-app spec: serviceAccountName: web-app-sa containers: - name: nginx image: nginx:latest
When this Pod starts, it will use the web-app-sa identity rather than the default one.
Hands-on Exercise
- Create a new ServiceAccount named
data-reader. - Update your existing Nginx Pod manifest from previous lessons to use the
data-readerServiceAccount. - Apply the changes and verify the attachment by running:
kubectl get pod my-web-app -o yaml | grep serviceAccountName
Common Pitfalls
- Over-permissioning: It is tempting to use the
cluster-adminrole for your ServiceAccount to "just make it work." Avoid this. Always follow the principle of least privilege. - Assuming the default: Never rely on the
defaultServiceAccount for production applications. If you need to interact with the API, create a dedicated one so you can audit and restrict its specific access. - Token Expiration: In modern Kubernetes versions, tokens are projected and automatically rotated. If you are writing custom code to call the API, ensure you are reading the token from the standard location (
/var/run/secrets/kubernetes.io/serviceaccount/token) rather than hardcoding it.
FAQ
Why can't I just use environment variables for credentials? Environment variables are often exposed in logs or UI dashboards. Using a ServiceAccount leverages the built-in Kubernetes token rotation and security mechanisms, which is significantly more secure.
Does a ServiceAccount work across Namespaces?
No. A ServiceAccount is namespaced. A Pod in namespace-a cannot use a ServiceAccount defined in namespace-b.
How does this relate to external cloud roles? In managed environments (like EKS or GKE), you can map a Kubernetes ServiceAccount to an IAM role (e.g., AWS IRSA). This allows your Pod to access external cloud services like S3 or RDS without needing long-lived access keys.
Recap
We’ve moved from securing the container process to defining the application's identity. By creating a ServiceAccount and attaching it to your Pod, you've established a formal identity that can be granted specific RBAC permissions. This is the foundation for secure, production-grade cluster communication.
Up next: We will look at how to run one-off tasks in your cluster using Jobs.
Work with me

VPS Server Setup, Deployment & Hardening
Get your app live on a fast, secure server — properly configured, hardened, and deployment-ready. No more wrestling with the command line.

CI/CD Pipeline & Docker Containerization
Ship with confidence: automated CI/CD pipelines and Docker setups so every push is tested and deployed — no more manual, error-prone releases.


