Creating a Kubernetes User with RBAC and Custom Kubeconfig: Step-by-Step Guide

•3 min read
rbackubernetes
Creating a Kubernetes User with RBAC and Custom Kubeconfig: Step-by-Step Guide

Introduction

Kubernetes offers fine-grained access control through RBAC (Role-Based Access Control). By creating dedicated users with specific permissions, we can ensure secure and controlled cluster access.

In this guide, I’ll walk through creating a Kubernetes user, generating and approving a certificate signing request (CSR), and configuring a custom kubeconfig file all with RBAC in place.

Why Use RBAC in Kubernetes?

RBAC enables you to:

  • Assign permissions per user or service account
  • Restrict actions to specific namespaces or resources
  • Enforce the principle of least privilege
  • Maintain an audit trail for compliance and security

Step 1: Generate Certificates for the User

Kubernetes client authentication can use certificates. Let’s generate a private key for our user saurav:

openssl genrsa -out saurav.pem 2048

First Install openssl if not installed.

Create a Certificate Signing Request (CSR):

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

Here, CN (Common Name) represents the username recognized by Kubernetes.

Step 2: Create a Kubernetes CertificateSigningRequest Resource

Kubernetes requires the CSR in base64 format:

cat saurav.csr | base64 | tr -d "\n" && echo

Use the output to create a CSR manifest:

sudo vim saurav_CSR.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: saurav
spec:
  request: <base64_encoded_csr>
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400
  usages:
  - digital signature
  - key encipherment
  - client auth

Apply it:

kubectl apply -f saurav_CSR.yaml

Step 3: Approve the CSR

List pending CSRs:

kubectl get csr

Approve the request:

kubectl certificate approve saurav

Extract the issued certificate:

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

Step 4: Create a Custom Kubeconfig for the User

We now embed:

  • client-certificate-data (base64 of saurav.crt)
  • client-key-data (base64 of saurav.pem)
cat saurav.crt | base64 | tr -d "\n" && echo # output of this command goes to  <client-certificate-data>
cat saurav.pem | base64 | tr -d "\n" && echo # output of this command goes to  <client-key-data>

Add these into a kubeconfig template that points to your cluster’s CA data and API server URL.

Sample kubeconfig.yaml

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRV45Q0FURS0tLS0tCk1JSUJlVENDQVIrZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWtNU0l3SUFZRFZRUUREQmx5YTJVeUxYTmwKY25abGNpMWpZVUF4TnpJek1qa3hOelE0TUI0WERUSTBNRGd4TURFeU1Ea3dPRm9YRFRNME1EZ3dPREV5TURrdwpPRm93SkRFaU1DQUdBMVVFQXd3WmNtdGxNaTF6WlhKMlpYSXRZMkZBTVRjeU16STVNVGMwT0RCWk1CTUdCeXFHClNNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJJRlUxZjY3NjRiNEMwMW5NcEd2d2V1enJ3dW5SY0tTdXNnOExjWEYKa2Y5bHEydm95bXRJYndHQ3lnRzZqamF6bkhjMUgwUE5DZEx5M2xGVkhaWWV0N09qUWpCQU1BNEdBMVVkRHdFQgovd1FFQXdJQ3BEQVBCZ05WSFJNQkFmsfsrwr432dBMVVkRGdRV0JCUjJTRW01czJmZ1V5enNsOEF0CjBYbkVrcExrQVRBS0JnZ3Foa2pPUFFRREFnTklBREJGQWlFQXpTalFIZWYwNzRkZWZ6TG5WVExpL0xadkNiancKOTlsN09qQisvUHRhQ09zQ0lHM2trQ2ZvdFFJRmZoS2NLaThxTmpqcVFGaVo0UzV1Zjg3VVlhbm9vZDRzCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://<pubip-k8s-server-node>:6443
  name: default
contexts:
- context:
    cluster: default
    user: default
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: default
  user:
    client-certificate-data: <replace with output of this cat saurav.crt | base64 | tr -d "\n" && echo>
    client-key-data: <output of these here: cat saurav.pem | base64 | tr -d "\n" && echo>

Step 5: Create RBAC Role and RoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: recharge-v2
  name: recharge-prod-role
rules:
- apiGroups: [""]
  resources: ["pods","pods/log"]
  verbs: ["get", "watch", "list", "delete"]

Bind the role to the user:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: recharge-prod-rolebinding
  namespace: default
subjects:
- kind: User
  name: saurav
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: recharge-prod-role
  apiGroup: rbac.authorization.k8s.io

Apply the manifests role and rolebinding.

Step 6: Test the User Access

Use the new kubeconfig:

kubectl - kubeconfig=kubeconfig.yaml get pods -n dev

The user should only be able to list, watch, get, and delete pods in the default namespace.

rbac namespace wise

Conclusion

By combining RBAC, certificates, and a custom kubeconfig, we created a secure, limited-access Kubernetes user. This approach:

  • Protects sensitive resources
  • Limits user permissions
  • Enables compliance and audit readiness

This process is ideal for granting developers, testers, or external partners controlled access to your cluster.

Written by Saurav Karki, DevOps Engineer Trainee at HamroPatro.