Build a kubeconfig from a Developer's Client Certificate
Developer `jane` joins the team that owns namespace `team-a`. The platform team issued her a client certificate signed by the cluster CA: `/root/jane/jane.crt` with key `/root/jane/jane.key`. The cluster CA certificate is `/root/jane/ca.crt`. Your own kubeconfig must keep working as it is.
Live lab access
This task description is public. Live practice requires full access unless this is the selected free weekly task. AI Lab Coach is available in single-task labs, including the free weekly task. See this week's free task.
Create an account to continue →
On a phone? Read the task and create your account here, then sign in on a desktop or laptop for the terminal lab. Nothing starts until you choose Start.
The task
Developer jane joins the team that owns namespace team-a. The platform team issued her a client certificate signed by the cluster CA: /root/jane/jane.crt with key /root/jane/jane.key. The cluster CA certificate is /root/jane/ca.crt. Your own kubeconfig must keep working as it is.
Requirements
1. Create a kubeconfig file /root/jane.kubeconfig for Jane with a cluster entry for this cluster (same API server as your kubeconfig, CA from /root/jane/ca.crt), a user entry using her certificate and key, and a context jane@team-a that uses namespace team-a. Make it the current context of that file.
2. Create RoleBinding jane-edit in team-a that grants the built-in ClusterRole edit to user jane.
3. Using Jane's kubeconfig, create Deployment hello with image nginx:1.27.5 in team-a and ensure it is available.
Do not change /root/.kube/config. Jane must not receive permissions outside team-a.
Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster. The example assumes you already hold a client certificate and key signed by the cluster CA, for instance one issued through a CertificateSigningRequest.
Build a kubeconfig from parts and prove which identity it uses
A kubeconfig file is three named lists plus a pointer. clusters say where the API server is and which CA to trust, users hold credentials, and contexts pair one cluster with one user and an optional default namespace. current-context picks the pair kubectl uses when you do not pass --context. Knowing this shape lets you build or repair a file with kubectl config instead of hand-editing base64.
apiVersion: v1
kind: Config
clusters:
- name: practice # server URL + CA
users:
- name: rio # client certificate + key
contexts:
- name: rio-practice # cluster: practice, user: rio, namespace: prepium-tutorial
current-context: rio-practice
1. Write to a separate file, never your own
Every kubectl config set-* command edits the file kubectl loaded. Passing --kubeconfig on each command keeps your working ~/.kube/config untouched. Read the server URL from your current context first:
SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
K=rio.kubeconfig
kubectl config --kubeconfig=$K set-cluster practice --server="$SERVER" \
--certificate-authority=creds/ca.crt --embed-certs=true
kubectl config --kubeconfig=$K set-credentials rio \
--client-certificate=creds/rio.crt --client-key=creds/rio.key --embed-certs=true
kubectl config --kubeconfig=$K set-context rio-practice \
--cluster=practice --user=rio --namespace=prepium-tutorial
kubectl config --kubeconfig=$K use-context rio-practice
--minify trims the output to what the current context uses, so clusters[0] is the right server. --embed-certs copies the files into certificate-authority-data, client-certificate-data and client-key-data, which makes the file portable. Without it the file stores paths, and relative paths are resolved from the kubeconfig's own location, so moving the file can silently break it.
2. Prove who you are, then what you may do
kubectl --kubeconfig=rio.kubeconfig auth whoami
kubectl --kubeconfig=rio.kubeconfig get pods
auth whoami asks the API server how it identified you. For certificate users the username is the certificate's common name and the groups come from its organization fields, plus system:authenticated. The second command may well fail with Forbidden: that is good news. A 403 means authentication succeeded and only authorization is missing, which you solve with RBAC, not with the kubeconfig. A 401 Unauthorized points back at the credentials or CA.
3. Inspect without leaking secrets
kubectl config view --kubeconfig=rio.kubeconfig
kubectl config get-contexts --kubeconfig=rio.kubeconfig
config view hides embedded certificate data unless you add --raw, so it is safe to paste into a ticket. Check that the context names the expected cluster, user and namespace, and that kubectl config current-context --kubeconfig=rio.kubeconfig returns it.
4. Understand merging with KUBECONFIG
export KUBECONFIG="$HOME/.kube/config:$PWD/rio.kubeconfig"
kubectl config get-contexts
kubectl --context=rio-practice auth whoami
unset KUBECONFIG
When KUBECONFIG lists several files, kubectl merges them, and the first file to set a value wins. Your own file comes first here, so its current-context stays active and you switch per command with --context. If two files define a user with the same name, only the first file's entry is used. The --kubeconfig flag disables merging completely and reads only that one file.
Common mistakes
- Forgetting
--kubeconfigon oneset-*command and writing a stray entry into your own config. - Skipping
use-context. The file has entries but no current context, so kubectl has no server to talk to unless you pass--context. - Pointing
--certificate-authorityat the client certificate. TLS verification of the API server then fails before any identity is checked. - Reading a
Forbiddenerror as a broken kubeconfig and rebuilding it, when the missing piece is a RoleBinding.
| Example check | Evidence |
|---|---|
| Correct identity | auth whoami shows the certificate's common name |
| Self-contained file | *-data keys present in config view --raw |
| Context wiring | get-contexts lists the right cluster, user and namespace; current-context returns it |
| Own config untouched | kubectl config current-context without flags returns your original context |
Cleanup: rm rio.kubeconfig and kubectl delete namespace prepium-tutorial if you created it. References: Organizing Cluster Access Using kubeconfig Files, Configure Access to Multiple Clusters, Authenticating. Next, try RBAC for developers or ServiceAccount troubleshooting.
Practice scope
This additional curriculum lab is available in single-task practice with the existing 12-minute limit. The three CKAD mocks keep their original 17-task sets. Hints, an explained solution and requirement-by-requirement feedback are available in the lab.
Browse CKAD practice tasks →