How does authentication work in the Kubernetes API server?
The Kubernetes API server supports multiple authentication methods including client certificates, bearer tokens, OIDC, and service account tokens. Requests pass through all configured authenticators until one succeeds. Once authenticated, the identity is passed to authorization (RBAC) and admission control before the request is processed.
Detailed Answer
The Kubernetes API server implements a pluggable authentication system where multiple authentication methods (called authenticators) run in parallel for each request. The first authenticator to successfully validate the request determines the caller's identity. If all authenticators fail, the request is rejected with a 401 Unauthorized response.
Authentication Methods
X.509 Client Certificates -- The most common method for cluster components and administrators. The API server is configured with a CA certificate, and any client presenting a certificate signed by that CA is authenticated. The Common Name (CN) becomes the username, and Organization (O) fields become group memberships.
# Generate a client certificate for a user
openssl genrsa -out jane.key 2048
openssl req -new -key jane.key -out jane.csr -subj "/CN=jane/O=developers"
# Sign with the cluster CA
openssl x509 -req -in jane.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial \
-out jane.crt -days 365
# Add to kubeconfig
kubectl config set-credentials jane \
--client-certificate=jane.crt \
--client-key=jane.key
kubectl config set-context jane-context \
--cluster=kubernetes \
--user=jane \
--namespace=development
# Test authentication
kubectl --context=jane-context get pods
Service Account Tokens -- Kubernetes automatically provisions service accounts for pods. Since v1.24, pods receive bound service account tokens, which are short-lived, audience-scoped JWTs projected as volumes:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
serviceAccountName: my-app-sa
containers:
- name: app
image: my-app:latest
# Token is automatically mounted at:
# /var/run/secrets/kubernetes.io/serviceaccount/token
volumeMounts:
- name: kube-api-access
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
readOnly: true
# Create a service account
kubectl create serviceaccount my-app-sa
# Create a token manually (for external use)
kubectl create token my-app-sa --duration=1h
# Inspect the token (it's a JWT)
kubectl create token my-app-sa | cut -d. -f2 | base64 -d | python3 -m json.tool
# Shows: iss, sub, aud, exp, iat, kubernetes.io claims
OpenID Connect (OIDC) -- Integrates with identity providers like Keycloak, Okta, Azure AD, or Google:
# API server flags for OIDC
spec:
containers:
- command:
- kube-apiserver
- --oidc-issuer-url=https://accounts.google.com
- --oidc-client-id=kubernetes
- --oidc-username-claim=email
- --oidc-groups-claim=groups
- --oidc-ca-file=/etc/kubernetes/pki/oidc-ca.crt
Webhook Token Authentication -- Delegates token validation to an external service:
# API server flag
--authentication-token-webhook-config-file=/etc/kubernetes/webhook-authn.yaml
# webhook-authn.yaml
apiVersion: v1
kind: Config
clusters:
- name: authn-service
cluster:
server: https://authn.example.com/authenticate
certificate-authority: /etc/kubernetes/pki/authn-ca.crt
users:
- name: api-server
user:
client-certificate: /etc/kubernetes/pki/authn-client.crt
client-key: /etc/kubernetes/pki/authn-client.key
Bootstrap Tokens -- Short-lived tokens used during cluster bootstrapping (kubeadm join):
# Create a bootstrap token
kubeadm token create --ttl 24h --print-join-command
Authentication Flow
Client Request
|
v
+----------------------------+
| API Server Auth Chain |
| 1. Client Certificate? | -> Check CN/O against CA
| 2. Bearer Token? | -> Check against token auth file, SA tokens, OIDC
| 3. Webhook? | -> Delegate to external service
| 4. Anonymous? | -> system:anonymous (if enabled)
+----------------------------+
|
v (identity established)
Authorization (RBAC)
|
v
Admission Control
Verifying Authentication
# Check who you are authenticated as
kubectl auth whoami # Kubernetes 1.27+
# Or use the legacy method
kubectl get --raw='/apis/authentication.k8s.io/v1/selfsubjectreviews' \
-o jsonpath='{.status.userInfo}'
# Test if a user can perform an action
kubectl auth can-i create deployments --as=jane --namespace=production
kubectl auth can-i '*' '*' --as=system:serviceaccount:default:my-app-sa
# View RBAC bindings for a user
kubectl get clusterrolebindings -o json | \
python3 -c "import json,sys;[print(b['metadata']['name']) for b in json.load(sys.stdin)['items'] if any(s.get('name')=='jane' for s in b.get('subjects',[]))]"
Security Best Practices
- Disable anonymous authentication in production (
--anonymous-auth=false) - Use short-lived tokens -- Prefer bound service account tokens and OIDC over static tokens
- Rotate certificates -- Use cert-manager or kubeadm certs renew to rotate before expiry
- Audit authentication -- Enable API server audit logging to track authentication events
- Use RBAC -- Always pair authentication with fine-grained RBAC policies
- Minimize service account privileges -- Avoid using the default service account; create dedicated ones with minimal permissions
Why Interviewers Ask This
Authentication is a critical security boundary. Interviewers ask this to evaluate whether a candidate understands how cluster access is secured, how service accounts work, and how to integrate external identity providers. This is essential for securing production clusters.
Common Follow-Up Questions
Key Takeaways
- Multiple authentication strategies run simultaneously; the first to succeed determines identity
- Service accounts are for pod-to-API-server communication; user accounts are for human/CI access
- Bound service account tokens (short-lived, audience-scoped JWTs) replaced static secret-based tokens