Kubernetes Authentication & Authorization

The two-gate security model of the Kubernetes API server: every request must pass authentication (who are you?) and authorization (what can you do?) before a resource is accessed. Core to the ~25% Cluster Architecture CKA domain. Source: CKA Day 22 Source: CKA Day 23 Source: CKA Day 24 Source: CKA Day 25

The Request Pipeline

When kubectl (or any client) sends a request to the API server, it flows through a strict pipeline:

Client Request → TLS Termination → Authentication → Authorization → Admission Control → Resource
  1. TLS Termination — The API server presents its server certificate. The client verifies it against the cluster CA.
  2. Authentication — The API server extracts credentials from the request (client cert, bearer token, or basic auth) and verifies identity using the configured authentication plugin.
  3. Authorization — The authenticated UserInfo (username, groups, UID) is passed to the authorization chain. The first module that returns an allow/deny decision wins.
  4. Admission Control — Optional mutating/validating webhooks that enforce policy (e.g., PodSecurity, ResourceQuota). See Kubernetes Admission Controllers for the full mechanism, and Kyverno for YAML-driven dynamic admission control. Source: Enforce Kubernetes Security with Kyverno

Authentication (AuthN)

Kubernetes does not have a built-in user database. Instead, it delegates identity verification to pluggable mechanisms configured on the API server.

Authentication Methods

MethodCKA RelevanceHow It Works
X.509 Client CertificatesHighClient presents a certificate signed by the cluster CA. API server extracts the Common Name as username and Organization as group. Used by kubeadm and most admin tools.
Bearer TokensHighStatic tokens in files, service account tokens (auto-mounted into Pods), or OIDC tokens from identity providers (e.g., Azure AD, Okta).
Webhook Token AuthenticationMediumAPI server POSTs the token to an external service for verification. Enables SSO and custom identity providers.
Basic AuthDeprecatedUsername/password in a CSV file. Disabled by default and removed in modern distributions.
Anonymous AuthLowUnauthenticated requests are mapped to system:anonymous user and system:unauthenticated group. Disabled in production.

Service Account Authentication

Every Namespace has a default ServiceAccount. When a Pod is created, Kubernetes automatically:

  1. Creates a ServiceAccount token (JWT) and stores it as a Secret
  2. Mounts that Secret as a volume at /var/run/secrets/kubernetes.io/serviceaccount
  3. Sets environment variables KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT

Inside the Pod, applications use this token to call the API server. The token is bound to the ServiceAccount’s identity and subject to its RBAC permissions. Since Kubernetes 1.24, long-lived token Secrets are no longer auto-generated; Pods instead receive short-lived projected volume tokens that the kubelet rotates automatically. Source: CKA Day 22 Source: CKA Day 25

Authorization (AuthZ)

After authentication, the request enters the authorization chain. The API server checks modules in the order specified by --authorization-mode:

--authorization-mode=Node,RBAC  # default in modern clusters

Authorization Modules

ModuleScopeCKA Relevance
NodeNode-localGrants kubelet read/write access only to resources bound to its own node. Enabled by default.
ABACCluster-wideLegacy file-based policy. Evaluates attributes of user, resource, and environment. Replaced by RBAC.
RBACNamespace + ClusterThe modern standard. Uses Kubernetes API objects (Role, ClusterRole, RoleBinding, ClusterRoleBinding).
WebhookCluster-wideDelegates to an external HTTP service (e.g., OPA, AWS IAM). Useful for multi-cluster policy.

RBAC Decision Flow

RBAC evaluates a request by asking three questions:

  1. Who? — The subject (User, Group, or ServiceAccount) referenced in the Binding
  2. Can do what? — The verb (get, list, watch, create, update, patch, delete, deletecollection) on the resource
  3. On what? — The resource name, namespace (for Roles), or cluster scope (for ClusterRoles)

If any Role or ClusterRole bound to the subject contains a matching rule, the request is allowed. There is no deny rule in RBAC — lack of permission equals denial. Source: CKA Day 22

Cluster-Scoped Authorization Patterns

For resources that exist outside any Namespace — Nodes, PersistentVolumes, Namespaces, ClusterRoles — Kubernetes requires ClusterRoles and ClusterRoleBindings:

# A user with this ClusterRoleBinding can list all Nodes
kubectl create clusterrolebinding node-reader-binding \
  --clusterrole=node-reader --user=alice

A critical exam distinction: a RoleBinding referencing a ClusterRole grants the ClusterRole’s rules, but only within the RoleBinding’s Namespace. This is the standard way to reuse the built-in admin, edit, and view ClusterRoles across many Namespaces without defining duplicate Roles. Source: CKA Day 24

Kubeconfig: The Client Credential Bundle

The kubeconfig file (~/.kube/config by default) is the client-side map that tells kubectl which cluster to talk to and how to authenticate. It decouples cluster endpoint configuration from user credentials. See the dedicated Kubernetes Kubeconfig deep-dive for full YAML anatomy and command reference. Source: CKA Day 22

Direct REST API Access

kubectl is a sophisticated REST client. The API server exposes all resources under /api/v1/ (core) and /apis/<group>/v1/ (named groups). You can call these endpoints directly with curl using a client certificate for mutual TLS:

curl https://<control-plane-ip>:6443/api/v1/namespaces/default/pods \
  --cacert /path/to/ca.crt \
  --cert /path/to/client.crt \
  --key /path/to/client.key

This returns raw JSON from the API server. The same TLS and RBAC rules apply regardless of whether the client is kubectl, curl, or a custom application. Source: CKA Day 23

CKA Exam Patterns

  • Switch Contexts: kubectl config use-context <context-name> is the first command in many exam tasks
  • Impersonate: kubectl auth can-i <verb> <resource> --as <user> tests permissions without logging in as that user. For cluster-scoped resources, omit --namespace.
  • Debug Forbidden: kubectl describe rolebinding and kubectl describe clusterrolebinding reveal which subjects have which roles
  • ServiceAccount Secrets: Since 1.24, ServiceAccount tokens are no longer auto-generated as Secrets unless explicitly requested or projected via TokenRequest API
  • Count Objects: kubectl get roles --no-headers -A | wc -l counts roles without header noise; kubectl get clusterroles --no-headers | wc -l for cluster-scoped roles
  • ClusterRoleBinding vs RoleBinding: Remember that ClusterRoleBindings apply globally, while RoleBindings (even with ClusterRoles) are namespace-scoped

Practical Practice

Exam-style hands-on tasks for this topic. Complete each task before reviewing the solution. Time yourself — CKA tasks average 5–7 minutes.

Task 1: Create and Approve a User CSR You are asked to onboard user alice by creating a CSR, approving it, and generating a kubeconfig context. Requirements: The private key alice.key already exists; generate a CSR named alice, approve it, extract the signed certificate, and add credentials + context to kubeconfig. Verification: kubectl config current-context shows alice and kubectl get nodes --as alice works. Solution:

# 1. Generate CSR from existing key
openssl req -new -key alice.key -out alice.csr -subj "/CN=alice/O=dev"
# 2. Create and submit CertificateSigningRequest object
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: alice
spec:
  request: $(cat alice.csr | base64 | tr -d '\n')
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth
EOF
# 3. Approve
kubectl certificate approve alice
# 4. Extract certificate
kubectl get csr alice -o jsonpath='{.status.certificate}' | base64 -d > alice.crt
# 5. Add to kubeconfig
kubectl config set-credentials alice --client-certificate=alice.crt --client-key=alice.key
kubectl config set-context alice --cluster=kubernetes --user=alice
kubectl config use-context alice

Task 2: Debug a 403 Forbidden Error A user reports Error from server (Forbidden) when trying to list Pods in namespace qa. Determine whether this is an authentication or authorization issue and fix it. Requirements: Do not modify the user’s certificate or kubeconfig. Verification: kubectl auth can-i list pods --as <user> --namespace qa returns yes. Solution:

# 1. If auth fails with "Unauthorized" → AuthN issue (bad cert/token)
#    If auth fails with "Forbidden" and user identity is valid → AuthZ issue
kubectl auth can-i list pods --as <user> --namespace qa
# 2. Check if a RoleBinding exists for the user in namespace qa
kubectl get rolebindings -n qa
# 3. If missing, create a RoleBinding to an appropriate Role
kubectl create rolebinding qa-pod-reader --role=pod-reader --user=<user> -n qa --dry-run=client -o yaml | kubectl apply -f -
kubectl auth can-i list pods --as <user> --namespace qa

Tags: kubernetes security authentication authorization rbac cka api-server devsecops