⌂ Home

Kubernetes User Certificate to RBAC Test Flow

This page visualizes the RBAC client-certificate flow as a lab runbook: create the namespace, generate user certificates, bind the Role, wire the certificate into kubeconfig, switch context, confirm the namespace, and test both allowed and forbidden operations. See RBAC Concepts for the full reference.

What this shows

  • How `user3.key`, `user3.csr`, and `user3.crt` are created and signed with the cluster CA.
  • How `kubectl config set-credentials` stores the client certificate for `user3`.
  • How `kubectl config set-context` points `user3` at namespace `role`.
  • How testing proves both the allow path and the RBAC deny path.

Core idea

  • Authentication comes from the client certificate common name: `user3`.
  • Authorization comes from `Role` plus `RoleBinding` in namespace `role`.
  • The kubeconfig context glues together cluster, user, and namespace.
  • Success means the user is authenticated but only partially authorized.
Namespace
role
All checks in this lab are scoped to one namespace.
User Identity
user3
The certificate common name becomes the Kubernetes username.
Trust Root
Cluster CA
The CSR is signed with the Kubernetes CA keypair.
Proof
Allow + Deny
The test ends with a successful action and a forbidden ConfigMap request.

Step-by-Step Flow

Use the stage chips to focus on one phase, or show the whole end-to-end path.

Step 1
Prepare

Create the namespace and working folder

The lab starts by isolating the RBAC exercise inside namespace `role` and creating a folder to hold certificate artifacts.

Admin shell
>
kubectl create namespace role
>
mkdir role && cd role
kubectl create namespace role
mkdir role
cd role
Namespace scope matters because a `Role` never grants permissions outside the namespace where it exists.
Step 2
Certificate

Generate the private key and CSR

The private key stays with the user, and the CSR carries the identity request. The most important field is the common name set to `user3`.

user3.key
>
user3.csr
>
CN=user3
sudo openssl genrsa -out user3.key 2048
sudo openssl req -new -key user3.key -out user3.csr

Common Name (e.g., your name or your server's hostname) []: user3
In this lab the certificate identity is user-based, not service-account based.
Step 3
Certificate

Sign the CSR with the Kubernetes CA

Once the cluster CA signs the CSR, the resulting `user3.crt` becomes a client certificate the API server can trust.

user3.csr
>
CA signs request
>
user3.crt
sudo openssl x509 -req \
  -in user3.csr \
  -CA /etc/kubernetes/pki/ca.crt \
  -CAkey /etc/kubernetes/pki/ca.key \
  -CAcreateserial \
  -out user3.crt \
  -days 500
Authentication succeeds only because the API server already trusts the cluster CA that signed the certificate.
Step 4
RBAC Bindings

Create the Role and RoleBinding

The `Role` contains verbs and resources, while the `RoleBinding` connects those rules to subject `user3` inside namespace `role`.

Role
+
RoleBinding
>
user3 in namespace role
kubectl create -f role.yaml
kubectl get roles -n role

kubectl create -f rolebinding.yaml
kubectl get rolebinding -n role
Without the binding, the certificate authenticates the user but still provides zero permissions.
Step 5
Kubeconfig

Exchange the certificate with kubectl using set-credentials

This is the handoff point where local certificate files are attached to the logical kubeconfig user named `user3`.

user3.crt + user3.key
>
kubectl config set-credentials
>
authinfo=user3
kubectl config set-credentials user3 \
  --client-certificate=/home/labsuser/role/user3.crt \
  --client-key=/home/labsuser/role/user3.key
`set-credentials` does not change authorization. It only tells kubectl which credentials to present.
Step 6
Kubeconfig

Create and inspect the user context

The new context combines the target cluster, authenticated user, and default namespace.

cluster=kubernetes
+
user=user3
+
namespace=role
>
user3-context
kubectl config set-context user3-context \
  --cluster=kubernetes \
  --namespace=role \
  --user=user3

kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin
          user3-context                 kubernetes   user3              role
`kubectl config get-contexts` is the checkpoint that proves the new namespace and identity are wired correctly.
Step 7
Testing

Switch to the user context and run positive tests

After `kubectl config use-context user3-context`, every request is sent as `user3` to namespace `role` unless you override it.

kubectl
>
client cert: user3
>
API server authn
>
RoleBinding authz
kubectl config use-context user3-context
sudo chmod 666 user3.key user3.crt

kubectl get pods
kubectl create deployment test --image=docker.io/httpd -n role
kubectl get deployment
If the Role allows these verbs and resources, the API server returns success.
Step 8
Testing

Run the negative test to prove RBAC denial

The same authenticated user is accepted by the API server, but RBAC blocks `configmaps` because the Role does not grant that permission.

user3 authenticated
>
requests ConfigMap create
>
RBAC check fails
>
Forbidden
kubectl create configmap my-config \
  --from-literal=key1=config1 \
  --kubeconfig=config

error: failed to create configmap: configmaps is forbidden:
User "user3" cannot create resource "configmaps"
in API group "" in the namespace "role"
Authentication answers “who are you?” Authorization answers “what may you do?” This failure is an authorization failure, not an authentication failure.
Step 9
Optional

Distribute the certificate to another node

The markdown also includes optional file movement steps when you want to run `kubectl` as this user from another machine or worker node.

scp user3.crt worker-node-1:/role/
scp user3.key worker-node-1:/role/

mkdir -p /role
cd /role
vi user3.crt
vi user3.key
The trust relationship stays the same. You are only moving the user's credential files to a different client location.

Artifacts and Outcomes

Each artifact has a specific job in the overall flow.

File

`user3.key`

User private key. It proves the client owns the certificate and must be protected.

File

`user3.csr`

Unsigned identity request sent to the cluster CA. It contains the subject details including common name.

FileIdentity

`user3.crt`

Signed client certificate trusted by the API server, representing user `user3`.

Kubeconfig

`user3-context`

The context entry that switches the namespace to `role` and the auth identity to `user3`.

Command Checkpoints

These are the most useful command checkpoints to demo live during training.

Check the context list

Confirms the new user and namespace entry exists.

kubectl config get-contexts

Switch to the user

Moves the active client identity from admin to `user3`.

kubectl config use-context user3-context

Positive authorization test

Shows a request that should succeed if the Role is correct.

kubectl get pods
kubectl create deployment test --image=docker.io/httpd -n role

Negative authorization test

Shows RBAC rejecting a disallowed resource type.

kubectl create configmap my-config --from-literal=key1=config1

Expected End State

The lab is successful when these outcomes are true at the same time.

Allowed

Authentication succeeds

The API server trusts the certificate signed by the cluster CA and recognizes the client as `user3`.

Allowed

Role-scoped actions work

The user can run the verbs and resources granted by the Role in namespace `role`.

Denied

Unlisted resources fail

The user is blocked from `configmaps` because no matching RBAC rule was granted.

Context

Namespace stays pinned

The active context defaults the user into namespace `role` until another context is selected.

Teaching note

This walkthrough demonstrates classic X.509 client-certificate authentication. In many enterprises, human users are integrated through OIDC or a webhook-backed identity layer, while certificates remain common for admin access, cluster bootstrap, or automation.