Service Accounts (SA)
[!IMPORTANT] A ServiceAccount is an identity for processes that run in a Pod. While User Accounts are for humans, ServiceAccounts are for robots (your applications).
If your application needs to talk to the Kubernetes API (e.g., a Jenkins agent creating pods, or a monitoring agent listing nodes), it needs credentials. You should never hardcode these. Instead, you assign a ServiceAccount to the Pod.
1. User vs. ServiceAccount
| Feature | User Account | ServiceAccount |
|---|---|---|
| Intended For | Humans (Alice, Bob) | Processes (Pods, Jobs) |
| Scope | Global (across all clusters) | Namespaced (specific to dev, prod) |
| Management | External (LDAP, OIDC, AWS IAM) | Kubernetes API Object |
| Credential | Access Token / Cert | Projected ServiceAccount Token (JWT) |
2. Interactive: Token Projection Flow
How does a Pod actually get its ID card? It’s “projected” into the container at runtime.
1. K8s Control Plane
2. Your Pod
Ready to start...
3. Workload Identity (The Modern Way)
In the cloud (AWS/GCP/Azure), you often need to access cloud resources like S3 buckets or BigQuery. Historically, people put AWS Keys in Kubernetes Secrets. This is bad practice.
Workload Identity (or IRSA in AWS) allows you to map a Kubernetes ServiceAccount to a Cloud IAM Role.
- Pod creates a token signed by Kubernetes.
- Pod sends this token to AWS/GCP.
- Cloud Provider validates the signature (OIDC Federation).
- Cloud Provider returns temporary cloud credentials.
[!TIP] This means zero long-lived secrets exist in your cluster. If a Pod is deleted, access is gone.
4. Implementation Details
1. Creating a ServiceAccount
It’s just a simple object.
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
namespace: default
annotations:
# Example for AWS IRSA
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/s3-reader
2. Using it in a Pod
apiVersion: v1
kind: Pod
metadata:
name: jenkins-agent
spec:
serviceAccountName: build-robot # Link to the SA
containers:
- name: agent
image: jenkins/inbound-agent
3. Disabling Auto-Mounting (Security Best Practice)
If your app does not need to talk to the K8s API (99% of web apps don’t), turn off the token mount. This reduces the attack surface if the container is compromised.
apiVersion: v1
kind: ServiceAccount
metadata:
name: web-app-sa
automountServiceAccountToken: false # Disable by default
Or on the Pod level:
spec:
automountServiceAccountToken: false