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

Token Controller Signs JWTs
JWT

2. Your Pod

/var/run/secrets/...

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.

  1. Pod creates a token signed by Kubernetes.
  2. Pod sends this token to AWS/GCP.
  3. Cloud Provider validates the signature (OIDC Federation).
  4. 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