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:

  1. Generating a certificate signing request (CSR)
  2. Getting the request approved
  3. 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

  1. You can switch contexts to act as Mary:

    kubectl config use-context mary
  2. For more granular permissions, consider using ClusterRoles and namespaced RoleBindings.

  3. Remember to secure the private key and certificate files.

  4. Consider setting longer expiration times for production environments.

  5. 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=entries to the certificate subject. Each O value becomes a Kubernetes group (e.g., /CN=mary/O=developers/O=qa).

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=--user=mary`. You can still override with `-n` per command.

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.

Related Posts

View All Posts »
Manage Docker Easily With VS Code

Manage Docker Easily With VS Code

I manage Docker tasks almost exclusively using VS Code. I can visualize my Docker images, containers, etc., and can run all commands, one-click, with it. Here's how.