Table of Contents
How to Add a New User in Kubernetes with Certificates & RBAC
· Travis Rodgers · 4 min read
Kubernetes doesn’t store “users” as API objects. With client certificate authentication, the API server reads the certificate’s Common Name (CN) as the username and each Organization (O) as a group. You grant access using RBAC (Roles/ClusterRoles + Bindings).
There are three steps for creating a new user in Kubernetes:
- Generating a certificate signing request (CSR)
- Getting the request approved
- Setting up appropriate RBAC permissions.
Let’s walk through this entire process for a new developer added to our team named “Mary”.
Related: If you’re creating non-human identities, use ServiceAccounts instead of user certs. See my guide: Kubernetes Service Accounts: Complete Guide for Beginners
Step 1: Generate a Private Key
First, we need to create a private key for our user in order to create a certificate signing request:
# Create a private key
openssl genrsa -out mary.key 3072
This will generate a new 3072-bit RSA private key and save it (unencrypted, in PEM/PKCS#1 format) to a file named mary.key.
Step 2: Create an X.509 Certificate Signing Request (CSR)
Next, we’ll create a CSR using the private key.
The following command will output a certificate that we will then use in our CertificateSigningRequest Kubernetes resource.
The Common Name (CN
) represents the username and O
the group. Adjust as necessary.
openssl req -new -key mary.key -out mary.csr -subj "/CN=mary/O=developers"
Step 3: Encode the CSR in Base64
Next, let’s encode the CSR that we just created in base64 format for use in the CertificateSigningRequest Kubernetes resource we are about to create:
cat mary.csr | base64 | tr -d "\n"
Here’s a refresher on how the API server authenticates client certificates, if needed.
Step 4: Create a Kubernetes CSR Resource
Now that we have generated the CSR and encoded it into base64, we are ready to create our CertificateSigningRequest Kubernetes resource.
Create a file named mary-csr.yaml
with the following content:
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: mary
spec:
request: <paste-one-line-base64-here>
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 864000 # 10 days
usages:
- client auth
Apply this YAML to create the CSR:
kubectl apply -f mary-csr.yaml
Step 5: Review and Approve the CSR
Check the status of the CSR:
kubectl get csr
Now you can approve the CSR:
kubectl certificate approve mary
Step 6: Retrieve the Certificate
Get the certificate from the approved CSR:
kubectl get csr/mary -o yaml
Export the issued certificate to a .crt file:
kubectl get csr mary -o jsonpath='{.status.certificate}'| base64 -d > mary.crt
Step 7: Configure the User in Kubeconfig
Now you or the new user can take all this data and add the new credentials to your/their kubeconfig:
kubectl config set-credentials mary --client-key=mary.key --client-certificate=mary.crt --embed-certs=true
Create a context for Mary:
kubectl config set-context mary --cluster=kubernetes --user=mary
Step 8: Test the Authentication
Verify that you can authenticate as Mary:
kubectl --context mary auth whoami
You should see output confirming you are “mary”.
Step 9: Create a Role
Now that we’ve created the user Mary, we want to use RBAC to determine what Mary is authorized to do.
Let’s say we don’t have a role for her department yet so let’s create a role for the developers (which would include her)
Create a role with the necessary permissions:
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
Note: Roles are namespaced. For cross-namespace access, use a ClusterRole and bind it cluster-wide. Here’s an article I wrote explaining How to Use ClusterRoleBinding With A ServiceAccount in All Namespaces, or see the Kubernetes documentation on the subject.
Step 10: Create a RoleBinding
And now we can bind this role to Mary via a RoleBinding:
kubectl create rolebinding developer-binding-mary --role=developer --user=mary
Step 11: Test the Authorization
Now you can test Mary’s permissions:
kubectl --context mary get pods
Mary should be able to perform operations on pods as defined in the developer role.
You can also, if you have the right permissions, test her permissions from your own context using:
kubectl auth can-i list pods --as=mary
or
kubectl auth can-i update pods --as=mary
Additional Tips
You can switch contexts to act as Mary:
kubectl config use-context mary
For more granular permissions, consider using ClusterRoles and namespaced RoleBindings.
Remember to secure the private key and certificate files.
Consider setting longer expiration times for production environments.
Want a hands-on sandbox? Spin up a local cluster on a Raspberry Pi 5 with my guide: Install Kubernetes on a Raspberry Pi 5
Kubernetes Certificates & RBAC: Frequently Asked Questions
Does Kubernetes have "User" objects?
No. Kubernetes does not store users as API objects. With client certificate auth, the API server reads CN as the username and each O as a group. Authorization is granted via RBAC (Roles/ClusterRoles + Bindings).
How do I map groups from a client certificate?
Add one or more O=
Should I use Users or ServiceAccounts?
Use Users (certs or OIDC) for humans; use ServiceAccounts for workloads running in the cluster. Bind RBAC to the appropriate identity type.
How do I set a default namespace for a user/context?
Include a namespace on the context, e.g., `kubectl config set-context mary --namespace=dev --cluster=
CSR approved but no certificate issued—why?
Your cluster may not have a signer for `kubernetes.io/kube-apiserver-client`, or a controller must finalize signing after approval. Check `kubectl get csr mary -o yaml` and ensure `.status.certificate` is populated.
How long should the certificate last?
Prefer short-lived certs (e.g., 30–90 days) and rotate regularly. Some signers ignore `spec.expirationSeconds`, so always verify the actual Not After date in the issued cert.
How do I revoke a user's access?
Remove their RoleBindings/ClusterRoleBindings, rotate or revoke the certificate (and CA if necessary), and remove their kubeconfig credentials. There is no user object to delete.
What is the difference between Role and ClusterRole?
Role is namespaced and applies only within a single namespace. ClusterRole is cluster-scoped (or can be referenced by RoleBinding for namespace use) and can grant access across namespaces when bound with a ClusterRoleBinding.
Can I use OIDC instead of client certificates?
Yes. Many orgs prefer OIDC (IdP/SSO + MFA) for human users. Configure the API server for OIDC and map IdP claims to groups, then use RBAC as usual.
How can I verify what identity Kubernetes sees?
Run `kubectl --context mary auth whoami` to print the username and groups from your current credentials.
This page may contain affiliate links. Please see my affiliate disclaimer for more info.