Understanding Kubernetes RBAC: Roles, RoleBindings, and and Client Certificates

Understanding Kubernetes RBAC: Roles, RoleBindings, and and Client Certificates

1 3 11
calendar_today agoschedule3 min read

One thing I discovered today is that before Kubernetes can decide what you're allowed to do, it first needs to know who you are.

That means there are two separate steps:

  1. Authentication – Proving your identity using a client certificate.
  2. Authorization – Deciding what you're allowed to do using RBAC.

In this lab, I created my own Kubernetes user named adeoye, authenticated the user with a certificate, and then used RBAC to control what that user could access.


Step 1 – Generate a Private Key

openssl genrsa -out adeoye.key 2048

This generates a 2048-bit RSA private key.

Think of this as your digital identity. It should never be shared.


Step 2 – Generate a Certificate Signing Request (CSR)

openssl req -new -key adeoye.key -out adeoye.csr -subj "/CN=adeoye"

A Certificate Signing Request asks Kubernetes to issue a client certificate.

The important part is:

/CN=adeoye

The Common Name (CN) becomes the Kubernetes username.


Step 3 – Base64 Encode the CSR

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

Kubernetes expects the CSR to be embedded inside a YAML manifest as Base64-encoded text. The tr -d '\n' removes line breaks so it becomes a single continuous string.


Step 4 – Submit the CSR

After inserting the encoded CSR into csr.yaml, I submitted it.

kubectl apply -f csr.yaml

Initially, the request was in the Pending state so I had to approve the request.


Step 5 – Approve the Certificate

kubectl certificate approve adeoye

Approving the request tells Kubernetes to trust the user and issue a signed client certificate.


Step 6 – Extract the Signed Certificate

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

Now I had:

  • adeoye.key
  • adeoye.crt

The key proves my identity, while the certificate proves Kubernetes trusts that identity.


Step 7 – Configure kubectl

kubectl config set-credentials adeoye \
--client-key=adeoye.key \
--client-certificate=adeoye.crt

Then I created a context.

kubectl config set-context adeoye \
--cluster=kind-cka-cluster3 \
--user=adeoye

A mistake I made: I initially typed lind-cka-cluster3 instead of kind-cka-cluster3, which caused API errors until I corrected the cluster name.

Finally, I switched to my new user.

kubectl config use-context adeoye

At this point I was authenticated, but I still didn't have permissions to perform actions.


RBAC Time!

Authentication tells Kubernetes who I am.

RBAC tells Kubernetes what I'm allowed to do.

Creating the Role

role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs:
    - get
    - watch
    - list

This Role only allows reading Pods.

Apply it:

kubectl apply -f role.yaml

Creating the RoleBinding

binding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default

subjects:
- kind: User
  name: adeoye
  apiGroup: rbac.authorization.k8s.io

roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

This binds the adeoye user to the pod-reader Role.

kubectl apply -f binding.yaml

Testing the Permissions

Verify permission:

kubectl auth can-i get pods

Output:

yes

List Pods:

kubectl get pods

Output:

No resources found in default namespace.

That means the command succeeded, but there were simply no Pods.

Next, I tried listing Deployments.

kubectl get deploy

Output:

Error from server (Forbidden): deployments.apps is forbidden

Why Could I Read Pods but Not Deployments?

The answer is in the Role.

It only grants access to:

resources:
- pods

It does not include Deployments.

Deployments belong to the apps API group, while Pods belong to the core API group.

Since my RoleBinding connects adeoye to the pod-reader Role, Kubernetes only allows the permissions defined there.

No Deployment permissions were granted, so Kubernetes correctly denied access.

This is the Principle of Least Privilege in action.


What I Learned

  • Kubernetes first authenticates users using client certificates.
  • The certificate's Common Name becomes the Kubernetes username.
  • A Role defines permissions.
  • A RoleBinding assigns those permissions to users.
  • Authentication and authorization are separate processes.
  • RBAC only grants explicitly defined permissions.
  • Pods and Deployments are different resources, so access to one doesn't imply access to the other.

Final Thoughts

Today's lab tied together authentication and authorization. Creating my own client certificate, configuring a new kubectl context, and then restricting that user with RBAC made the concepts much easier to understand.

Security in Kubernetes isn't about giving users full access,but about giving them exactly the permissions they need, nothing more.

Part 4 of 4 in My Kubernetes Journey
🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Just completed another large-scale WordPress migration — and the client left this

saqib_devmorph - Apr 7

Kubernetes Autoscaling: HPA vs VPA Explained With Hands-On Practice

AYANFE - Jul 1

Check out this article for beginners on Kubernetes

Onlyfave - Jan 17, 2025

Manage TLS Certificates In a Kubernetes Cluster

AYANFE - Jul 3

How Kubernetes Simplifies Cloud Application Deployment, Scaling, and Management

Aditya Pratap Bhuyan - Mar 13, 2025
chevron_left
265 Points15 Badges
Abuja,Nigeria.
6Posts
3Comments
5Connections
A gentleman with a rough edge.

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!