Back to Blog

Cluster Access & User Management for the CKA Exam: kubeconfig, Contexts & CertificateSigningRequests

A practitioner's guide to Kubernetes cluster access for the CKA exam — how authentication actually works, the anatomy of a kubeconfig, switching contexts and namespaces under the clock, and provisioning a brand-new kubectl user end-to-end with the CertificateSigningRequest API, with copy-paste commands and a failure-diagnosis table.

By Sailor Team , July 28, 2026

Every CKA task begins with the same instruction, printed in bold at the top of the question: “You must first set the context.” Candidates who ignore it lose points on a task they solved correctly, because they solved it on the wrong cluster. Cluster access — how you authenticate, how kubeconfig ties a user to a cluster, and how you switch between them — is the connective tissue of the entire exam, and one of its objectives asks you to go a step further and create a new user from scratch.

This objective lives in the Cluster Architecture, Installation & Configuration domain, roughly 25% of the exam. It is easy to under-prepare for because it feels like plumbing rather than a “real” Kubernetes skill. But provisioning a user with the CertificateSigningRequest API is a mechanical, high-value task that appears on the exam, and understanding kubeconfig prevents the silent context mistakes that quietly cost points on every other question. This guide covers how Kubernetes authenticates a request, the anatomy of a kubeconfig, working with contexts on exam day, and the full end-to-end workflow to onboard a new kubectl user.

If you want the full exam picture first, start with the CKA exam guide for 2026 and the CKA domains breakdown, then come back here. This guide pairs directly with the CKA RBAC hands-on guide: access answers who are you? (authentication), RBAC answers what may you do? (authorization). You need both to make a user useful.

How Kubernetes Actually Authenticates You

The single most important fact for this topic: Kubernetes has no User object. You will never run kubectl create user. There is no row in etcd that represents a human. Instead, every request to the API server carries a credential, and a chain of authenticators inspects that credential and, if valid, attaches an identity — a username and a set of groups — to the request. That identity is then handed to the authorization layer (RBAC) to decide what the request is allowed to do.

The API server supports several authentication methods, and you should be able to recognise them:

MethodCredentialWhere the identity comes from
Client certificatesX.509 cert signed by the cluster CACN field → username, O fields → groups
Bearer tokensStatic token, or OIDC tokenToken maps to a username/groups
Service account tokensJWT mounted into a podsystem:serviceaccount:<ns>:<name>
Authenticating proxy / webhookHeader or external serviceDelegated to the proxy or webhook

For the CKA, client certificates are what matter. When you authenticate with a certificate, the API server checks that the certificate was signed by the cluster’s certificate authority. If it was, it trusts the certificate’s contents: the Common Name (CN) becomes your username and each Organization (O) field becomes a group. This is why creating a user is really “getting the cluster CA to sign a certificate for a name you choose” — there is nothing else to create.

This design has a clean consequence for the exam. To onboard alice into the dev group, you don’t touch a user database. You generate a certificate whose CN=alice and O=dev, get it signed by the cluster, and hand it to her. RBAC bindings then reference alice or the dev group by name, even though neither exists as a stored object.

The Anatomy of a kubeconfig

A kubeconfig is a YAML file — by default ~/.kube/config, overridable with the KUBECONFIG environment variable — that stitches together three independent lists. Understanding these three lists is what lets you read and repair access under pressure.

apiVersion: v1
kind: Config
current-context: dev-admin        # the pointer: which context is active

clusters:                         # WHERE: the API server + its CA
- name: prod-cluster
  cluster:
    server: https://10.0.0.1:6443
    certificate-authority-data: LS0tLS1CRUdJ…   # the CA that signs/verifies

users:                            # WHO: credentials to present
- name: alice
  user:
    client-certificate-data: LS0tLS1CRUdJ…       # alice's signed cert
    client-key-data: LS0tLS1CRUdJ…               # alice's private key

contexts:                         # the JOIN: cluster + user + namespace
- name: dev-admin
  context:
    cluster: prod-cluster
    user: alice
    namespace: dev

The mental model is simple:

  • clusters answer where — the API server URL and the CA used to verify the server (and to verify certs the server issues).
  • users answer who — the credentials kubectl presents. A “user” here is just a named credential bundle; it can be a client cert, a token, or an exec plugin.
  • contexts answer which combination — a context is a named tuple of (cluster, user, namespace). current-context is a pointer to whichever one is active.

Two commands you will use constantly:

# See the whole file, resolved
kubectl config view

# See only the active context's details, with secrets redacted
kubectl config view --minify

When a task gives you a kubeconfig file to use, point kubectl at it without overwriting your default:

kubectl --kubeconfig /root/alice.kubeconfig get pods
# or, for a whole session:
export KUBECONFIG=/root/alice.kubeconfig

Working With Contexts on Exam Day

Context management is the highest-frequency, lowest-glamour skill on the CKA — and skipping it is the most common avoidable mistake, as covered in Kubernetes exam mistakes to avoid. Burn these four commands into muscle memory:

# What contexts exist? (the * marks the active one)
kubectl config get-contexts

# Which context am I on right now?
kubectl config current-context

# Switch context — DO THIS FIRST for every single question
kubectl config use-context cka-cluster

# Pin a default namespace to the current context (stop typing -n dev)
kubectl config set-context --current --namespace=dev

The last one is a genuine time-saver. On a multi-step question scoped to one namespace, setting it once means every subsequent kubectl command is already pointed at the right place — no more forgetting -n dev on the fifth command and debugging a “not found” that was never real.

A discipline that separates passing candidates from failing ones: run kubectl config use-context <ctx> as the literal first action of every question, copy-pasted straight from the task text. It costs three seconds and eliminates an entire class of “I did everything right but on the wrong cluster” failures.

Provisioning a New User With the CertificateSigningRequest API

This is the marquee task for the objective. The goal: take a person who has no access and produce a working kubeconfig that authenticates them as a named user in a named group. Kubernetes gives you a first-class way to do this without ever touching the CA’s private key on disk — the CertificateSigningRequest (CSR) API. You submit a certificate request as a Kubernetes object, an administrator (you) approves it, and the cluster’s signer returns a signed certificate.

Step 1: Generate a Private Key and a CSR

Work with openssl locally. The CN becomes the username; each O becomes a group.

# 1. Private key — this never leaves the user's hands
openssl genrsa -out alice.key 2048

# 2. A certificate signing request: CN=username, O=group
openssl req -new -key alice.key -out alice.csr \
  -subj "/CN=alice/O=dev"

You now have alice.key (the private key) and alice.csr (the request). The cluster only ever sees the request, never the private key.

Step 2: Submit the CSR as a Kubernetes Object

The CSR object wraps your base64-encoded request. Encode it as a single line first:

cat alice.csr | base64 | tr -d '\n'

Paste that value into the request field:

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: alice
spec:
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNU…   # base64 of alice.csr
  signerName: kubernetes.io/kube-apiserver-client       # signs client-auth certs
  expirationSeconds: 86400                                # 24h; optional
  usages:
  - client auth

Two fields decide whether this works:

  • signerName: kubernetes.io/kube-apiserver-client — this is the built-in signer for client-authentication certificates. Getting this wrong (for example using the kubelet-serving signer) means the resulting cert won’t authenticate you to the API server.
  • usages: ["client auth"] — the certificate is for authenticating to the API server, not for serving TLS.

Apply it, then check its state:

kubectl apply -f alice-csr.yaml
kubectl get csr
# NAME    AGE   SIGNERNAME                            REQUESTOR   CONDITION
# alice   5s    kubernetes.io/kube-apiserver-client   kubernetes-admin   Pending

Step 3: Approve and Extract the Signed Certificate

Approval is a one-liner. Until you approve, the request sits Pending and no certificate is issued.

kubectl certificate approve alice

The condition flips to Approved,Issued. Now pull the signed certificate out of the object’s status — it’s base64-encoded, so decode it:

kubectl get csr alice -o jsonpath='{.status.certificate}' | base64 -d > alice.crt

You now hold alice.crt, a certificate the cluster CA has signed, asserting CN=alice, O=dev.

Step 4: Build the kubeconfig

Assemble the three lists using kubectl config subcommands. --embed-certs=true inlines the cert and key so the file is self-contained and portable:

# WHO: register alice's credentials
kubectl config set-credentials alice \
  --client-certificate=alice.crt \
  --client-key=alice.key \
  --embed-certs=true

# the JOIN: a context tying alice to the cluster + a default namespace
kubectl config set-context alice@cka \
  --cluster=cka-cluster \
  --user=alice \
  --namespace=dev

# activate it and test
kubectl config use-context alice@cka
kubectl get pods

If the cluster entry doesn’t already exist in the kubeconfig you’re editing, add it with kubectl config set-cluster cka-cluster --server=https://<api>:6443 --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true.

At this point alice can authenticate — but she can’t do anything yet.

Authentication Is Only Half the Job: Grant Permissions

A freshly minted certificate user is authenticated and completely powerless. Every command returns Forbidden until you bind permissions to her identity. This is the hand-off to RBAC:

# A namespaced role: read pods in dev
kubectl create role pod-reader \
  --verb=get,list,watch --resource=pods -n dev

# Bind it to the USER named in the cert's CN
kubectl create rolebinding alice-pod-reader \
  --role=pod-reader --user=alice -n dev

Because the certificate also carried O=dev, you could instead bind to the group dev with --group=dev, granting the permission to every user whose certificate includes that organization — the standard pattern for onboarding a team once and issuing individual certs thereafter. The full role/binding model, including ClusterRoles and ServiceAccount subjects, is in the CKA RBAC hands-on guide.

The distinction to keep straight under exam pressure: Unauthorized is an authentication failure (who are you?), Forbidden is an authorization failure (you’re known, but not allowed). They point to completely different fixes.

ServiceAccounts: Identity for Workloads

Human users authenticate with certificates; pods authenticate with ServiceAccounts. A ServiceAccount is a real Kubernetes object, and its token is auto-mounted into pods so in-cluster workloads can call the API. You’ll occasionally build a kubeconfig backed by a ServiceAccount token rather than a client cert:

kubectl create serviceaccount deployer -n dev
# Request a short-lived token (v1.24+ no longer auto-creates secret tokens)
TOKEN=$(kubectl create token deployer -n dev)

kubectl config set-credentials deployer --token="$TOKEN"
kubectl config set-context deployer@cka --cluster=cka-cluster --user=deployer --namespace=dev

RBAC then binds to the subject system:serviceaccount:dev:deployer. Use ServiceAccounts for automation and CI, client certificates for humans.

Common Cluster-Access Failures and How to Read Them

Access problems produce a small, recognisable set of errors. Diagnosing them quickly is a Troubleshooting-domain skill too — see the CKA troubleshooting guide for the wider method.

SymptomMost likely causeFix
error: You must be logged in to the server (Unauthorized)Cert expired, not signed by cluster CA, or wrong signer usedRe-issue the CSR with kubernetes.io/kube-apiserver-client; check cert validity
Error from server (Forbidden): ... cannot list resource "pods"Authenticated but no RBAC bindingCreate a Role/RoleBinding for the user or group
x509: certificate signed by unknown authorityWrong certificate-authority-data for the clusterPoint the cluster entry at the correct CA
Commands hit the wrong namespace / return emptyContext’s namespace not setkubectl config set-context --current --namespace=<ns>
CSR stuck PendingNot approved yetkubectl certificate approve <name>
The connection to the server ... was refusedWrong server: URL or API server downVerify the endpoint; check control-plane health

A fast triage tool is kubectl auth can-i. It answers authorization questions without trial and error, and --as lets you impersonate the user you just created:

kubectl auth can-i list pods -n dev --as alice
# yes / no — confirms the binding worked before you hand over the kubeconfig

Exam-Day Speed Tips

  • Set the context first, every question. Copy the kubectl config use-context line from the task text before doing anything else.
  • Pin the namespace with set-context --current --namespace=<ns> on any question scoped to one namespace.
  • Know the CSR field values coldsignerName: kubernetes.io/kube-apiserver-client and usages: ["client auth"]. These are the two fields candidates get wrong.
  • CN is the user, O is the group. Bind RBAC to whichever the task names.
  • Use --embed-certs=true so the kubeconfig you produce is self-contained and survives being copied elsewhere.
  • Verify before moving on with kubectl auth can-i ... --as <user> rather than assuming the binding took. The CKA kubectl cheat sheet collects these commands for last-minute review.

Practice on a Real Cluster

Reading the CSR workflow is not the same as executing it in under five minutes with a timer running. The muscle memory — generate the key, encode the request, apply, approve, extract, assemble the kubeconfig, bind RBAC, verify — only forms through repetition on a live cluster. Sailor.sh’s Certified Kubernetes Administrator (CKA) Mock Exam Bundle runs exam-style performance tasks on a real, browser-based cluster that mirror the format and difficulty of the actual exam, including cluster-access and user-provisioning scenarios like the one above. Pair the hands-on practice with the 30-day CKA study plan, shore up the adjacent authorization domain with the CKA RBAC hands-on guide, and if you’re building a home lab to rehearse for free, the Kubernetes lab setup for CKA and how to practice CKA for free walk you through it.

Frequently Asked Questions

Is there really no User object in Kubernetes?

Correct. Users are not stored anywhere in the cluster. A “user” exists only as a name (CN) inside a certificate the cluster CA has signed, or as a subject a token maps to. RBAC bindings reference that name as a string. This is why you provision a user by issuing a certificate, not by creating an object.

What’s the difference between signerName: kubernetes.io/kube-apiserver-client and the other signers?

kube-apiserver-client issues certificates for authenticating to the API server as a client — exactly what a human user needs. Other built-in signers (kubelet-serving, kube-apiserver-client-kubelet, legacy-unknown) serve different purposes. Using the wrong signer produces a certificate that either won’t be trusted or won’t authenticate you as a client, so this field is a common source of failed CSR tasks.

Why does my new user get “Forbidden” even though the certificate works?

Because authentication and authorization are separate. The certificate proves who you are; RBAC decides what you may do. A brand-new user has zero permissions until you create a Role (or ClusterRole) and bind it to the user or their group. Forbidden means auth succeeded and authorization failed — create the binding.

Can I bind RBAC to a group instead of individual users?

Yes, and it’s the scalable pattern. If every developer’s certificate includes O=dev, a single RoleBinding to --group=dev grants the permission to all of them. You then only issue per-person certificates; you don’t touch RBAC again when a new teammate joins.

How do I switch namespaces without editing the kubeconfig file by hand?

kubectl config set-context --current --namespace=<ns> updates the active context in place. On the exam this saves you from appending -n <ns> to every command in a multi-step task and from the “not found” errors that come from forgetting it.

What credential do pods use instead of a kubeconfig?

Pods use a ServiceAccount, whose token is automatically projected into the container. In-cluster clients read it from the mounted path and authenticate as system:serviceaccount:<namespace>:<name>. Use ServiceAccounts for workloads and automation; use client certificates for humans.

Conclusion

Cluster access is the CKA skill you exercise on every question and get graded on directly through the user-provisioning objective. Internalise three things: Kubernetes authenticates identities but never stores users; a kubeconfig is just three lists — clusters, users, contexts — joined by current-context; and creating a user is the CSR loop of generate → submit → approve → extract → assemble → bind. Set your context first, keep authentication and authorization straight in your head, verify with kubectl auth can-i --as, and this becomes one of the most reliable point-earners on the exam. From here, go deep on what a user is allowed to do in the CKA RBAC hands-on guide, and map the rest of the blueprint with the CKA exam guide for 2026.

Limited Time Offer: Get 80% off all Mock Exam Bundles | Sale ends in 7 days. Start learning today.

Claim Now