Skip to main content

Command Palette

Search for a command to run...

Kubernetes User Authentication & Authorization

Certificate-Based User Creation with RBAC (End-to-End)

Updated
โ€ข5 min read
Kubernetes User Authentication & Authorization
D

I'm a DevOps enthusiast and software engineer with 3+ years of hands-on experience building scalable CI/CD pipelines, automating infrastructure, and streamlining deployment workflows. I specialize in tools like Jenkins, Maven, Docker, and Tomcat, and I love turning complex systems into elegant, maintainable solutions. On Hashnode, I share insights, tutorials, and real-world lessons from the trenchesโ€”whether it's debugging flaky builds, optimizing deployment strategies, or exploring the latest in cloud-native tech. My goal is to help developers and ops teams collaborate better, ship faster, and learn continuously.4

In the previous article, we learned how RBAC works and how Kubernetes decides who can do what using Roles, RoleBindings, and ServiceAccounts.

However, RBAC answers only one part of the security story.

Before Kubernetes can authorize a request, it must first answer:

Who is the user making this request?

This article completes that missing piece by demonstrating certificate-based user authentication, followed by RBAC authorization.

By the end of this guide, you will understand:

  • How Kubernetes authenticates users

  • How certificates map to users and groups

  • How RBAC permissions are applied after authentication


๐Ÿ”น Authentication vs Authorization (Quick Context)

Kubernetes security works in two phases:

  1. Authentication โ€“ Who are you?

  2. Authorization (RBAC) โ€“ Are you allowed to do this?

This article focuses on authentication first, then connects it back to RBAC authorization.


๐Ÿ”น Prerequisites

Before starting, ensure you have:

  • Cluster admin access

  • A running Kubernetes cluster (Minikube or otherwise)

  • User machine with:

    • openssl

    • kubectl

    • base64


๐Ÿ”น Stage 1 โ€” User Side: Generate Certificate Signing Request (CSR)

In Kubernetes, users are external identities.
They are authenticated using certificates, not Kubernetes resources.


Step 1: Create Working Directory

mkdir -p ~/.certs && cd ~/.certs

Step 2: Generate Private Key and CSR

# Create 2048-bit RSA private key
openssl genrsa -out divakar.key 2048

# Create CSR with CN=username and O=group
openssl req -new -key divakar.key -out divakar.csr -subj "/CN=divakarchakali/O=group"
  • CN (Common Name) โ†’ Kubernetes username

  • O (Organization) โ†’ Kubernetes group

These values must match RBAC subjects exactly.


Step 3: Encode CSR for Cluster Admin

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

Copy the output and share it securely with the cluster administrator.


๐Ÿ”น Stage 2 โ€” Admin Side: Process CSR & Issue Certificate

The cluster admin is responsible for validating and approving the CSR.


Step 1: Create CSR Manifest

Manifest: csr-requests.yaml

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: csr-request
spec:
  groups:
  - system:authenticated
  request: <PASTE_BASE64_ENCODED_CSR_HERE>
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - digital signature
  - key encipherment
  - client auth

Step 2: Apply & Verify CSR

kubectl apply -f csr-requests.yaml

Verify the request:

kubectl get csr csr-request -o jsonpath='{.spec.username}'
kubectl describe csr csr-request | grep -A5 "Subject:"

Ensure the subject shows:

CN=divakarchakali

Step 3: Approve CSR

kubectl certificate approve csr-request

Step 4: Extract Signed Certificate

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

Step 5: Share Certificate with User

Send the following to the user securely:

  1. divakar.crt (signed client certificate)

  2. ca.crt (cluster CA certificate)

    • Cluster CA certificate through JSONPath

        kubectl config view -o jsonpath='{range .clusters[*]}{.name}{"\t"}{.cluster.certificate-authority-data}{"\n"}{end}'
      
    • Cluster CA with --raw

        kubectl config view --raw
      
  3. Cluster details:

    • API server URL

    • Cluster name

Example cluster reference:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: /path/to/ca.crt  # Encoded CA
    server: https://api-kops-k8s-local-airxxx-e46xxx0x0xxxxeb8.elb.us-east-2.amazonaws.com
    tls-server-name: api.internal.kops.k8s.local
  name: kops.k8s.local  
users: []
contexts: []
current-context: ""

๐Ÿ”น Stage 3 โ€” User Side: Configure kubeconfig

Now the user configures local access using the issued certificate.


Step 1: Prepare kubeconfig Directory

mkdir -p ~/.kube/ && cd ~/.kube/
cp ~/.certs/divakar.crt ~/.certs/divakar.key  ~/.kube

Step 2: Verify Certificate CN (Critical)

openssl x509 -in divakar.crt -text -noout | grep "Subject:.*CN"

Expected output:

Subject: O=group, CN=divakarchakali

Step 3: Configure kubeconfig

3.1 Set Credentials

kubectl config set-credentials divakarchakali \
  --client-certificate=divakar.crt \
  --client-key=divakar.key \
  --embed-certs=true

3.2 Set Context

kubectl config set-context divakar-context \
  --cluster=kops.k8s.local\
  --user=divakarchakali \
  --namespace=default

3.3 Switch Context

kubectl config use-context divakar-context

Step 4: Verify kubeconfig

kubectl config view --minify | grep -A5 users

Test access:

kubectl get nodes

๐Ÿ”น Expected Results

Authentication Success (Authorization Not Yet Granted)

Error from server (Forbidden): nodes is forbidden: User "divakarchakali" cannot list resource "nodes"

โœ… Authentication works
โŒ Authorization not yet configured

This is expected.


Authentication Failure

Unable to connect to the server: x509: certificate signed by unknown authority

Check:

  • CA certificate path

  • Server URL

  • Certificate files


๐Ÿ”น Stage 4 โ€” Admin: Grant RBAC Permissions

Now we move from authentication to authorization.

Default roles in kubernetes:

  • admin: Grants read-write access to all resources within a namespace.

  • cluster-admin: Provides read-write access to many resources across the entire cluster.

  • edit: Allows users to create, update, and delete core resources like deployments, services, and configmaps.

  • view: Offers read-only access to most resources, excluding secrets.

Always grant access based on the principle of Least Privilege โ€” assign the minimal role necessary for a user to perform their tasks. For example:

  • Developers typically need the edit role.

  • Operators or team leads may require admin.

  • Cluster administrators should be limited to cluster-admin only when essential.

  • Use view for monitoring or troubleshooting without modification rights.


Cluster-Wide Access (View Only)

kubectl create clusterrolebinding divakar-view \
  --clusterrole=view \
  --user=divakarchakali

Namespace-Scoped Access

kubectl create rolebinding divakar-editor \
  --clusterrole=edit \
  --user=divakarchakali \
  -n default

โš ๏ธ subjects.name must match the certificate CN exactly.


RBAC Verification

kubectl auth can-i list pods --namespace=default
kubectl auth can-i get nodes --as=divakarchakali

๐Ÿ”น Final Verification (User)

kubectl config use-context divakar-context
kubectl get pods -n default
kubectl get nodes

Access should now succeed based on granted RBAC roles.


๐Ÿ”น Troubleshooting

IssueCommandFix
x509 erroropenssl verify -CAfile ca.crt divakar.crtFix CA path
Forbidden errorkubectl auth can-i list pods --as=divakarchakaliAdd RBAC
Context mismatchkubectl config view --minifyFix user/context

๐Ÿ”น Summary

  • Kubernetes users are authenticated using certificates

  • CN maps to username, O maps to groups

  • Authentication happens before RBAC

  • RBAC decides what the user can do

  • kubectl auth can-i is your best debugging tool

With this, the security lifecycle is complete:

  • Identity

  • Authentication

  • Authorization