This document provides a comprehensive explanation of how Kubernetes handles users and groups in RBAC, and how to create users even though Kubernetes itself does not store users.
Important Truth: Kubernetes Has No "User Objects"
Kubernetes does NOT store users or groups internally.
There is:
No User API
No Group API
No command like kubectl create user
Instead, Kubernetes trusts external identity that is proven through client certificates, OIDC tokens, or authentication plugins.
RBAC Works Only with "Usernames" and "Groupnames"
RBAC references usernames and groupnames, but Kubernetes does not create them.
Does the incoming request belong to this username?
Does the incoming request contain this group?
The authentication layer decides this, NOT Kubernetes.
How to Create Users in Kubernetes
Users are created by establishing credentials outside of Kubernetes, and then configuring Kubernetes to recognize the user identity.
There are 3 methods for creating users.
1. Create Users Using Client Certificates (kubeadm clusters)
This is the most common method for labs and enterprise clusters without SSO.
Step 1: Create a private key
Step 2: Create CSR
CN = username
O = group
Step 3: Sign CSR with Kubernetes CA
Step 4: Add user to kubeconfig
Step 5: Create context
Assigning/binding a ready-made admin role to the new user
Find Current User (Admin User)
Check context
Check All Roles/ClusterRoles Attached to Current User
Adding newly created user in admin group directly
Minimal OpenSSL Method (no SAN)
1. Create private key
2. Create CSR with CN and O
This is the important part:
CN=deepak - Common Name (username)
O=system:masters - Organization (group that grants admin privileges)
No SAN required
No extra config file needed
Works perfectly for client authentication
3. Sign CSR with Kubernetes CA
Use kubeadm CA:
4. Create kubeconfig entry
Add the user:
Add context:
Switch:
5. Verify it worked
The output should show:
The user now has full cluster-admin privileges.
Important Notes
Certificate Type
SAN Needed?
Why?
Client cert (user)
No
Identity only uses CN + O
Server cert (API server, kubelets)
Yes
Browsers & Kubelet require SAN for hostname/IP
Your use case = client cert, so SAN is not required.
Step 6: Apply RBAC
2. Create Users Using OIDC (Production / SSO)
Kubernetes integrates with:
Keycloak
Dex
Azure AD
Google Workspaces
Okta
GitHub OIDC
This is how enterprise clusters typically create users.
Flow:
User logs into OIDC (e.g., Azure AD, Keycloak)
OIDC issues a JWT token containing:
username
groups
Kubernetes verifies JWT signature
RBAC matches roles based on group membership.
Example token payload:
RBAC:
No user creation occurs in Kubernetes — identity comes from OIDC.
3. Static Password File or Token File (NOT for production)
Used for labs or kubeadm learning.
Example basic_auth.csv:
In apiserver run:
This method is not recommended for production, but useful for educational purposes.
How Groups Are Created in Kubernetes
Kubernetes does not create groups.
Groups can only come from:
Certificate O=<group-name>
OIDC token groups claim
Static password/token files
The group name is simply referenced in RBAC, even though Kubernetes never stored it.
Minimal Lab Example
User Certificate → User deepak
Group → dev
CSR:
RBAC:
User’s certificate defines their identity.
Understanding the Architecture
Authentication Layer → "Who is the user?"
Authorization Layer (RBAC) → "What can the user do?"
Kubernetes never stores identity information.
Summary
Concept
Kubernetes Stores It?
Who Creates It?
Usernames
No
Cert CN / OIDC token
Groups
No
Cert O / OIDC token
Credentials
No
Admin, SSO, certificate
RBAC
Yes
Kubernetes
The following section describes the method to run the Kubernetes API server with a basic-auth password file. This works ONLY for kubeadm-based clusters or clusters where the API server is manually controlled (not for EKS, AKS, GKE, K3s unless modified).
Important Warning
Basic authentication is deprecated and insecure. It only works when:
You manually modify the kube-apiserver manifest located in /etc/kubernetes/manifests/kube-apiserver.yaml
And only on the control-plane node.
Step 1: Create the Password File
Create a file (e.g., /etc/kubernetes/pwfile.csv):
Add entries in CSV format:
Format:
Example:
username = deepak
uid = 1001
groups = dev, ops
Step 2: Edit the kube-apiserver Manifest
Open:
Add the following flags under command: of the container:
Example snippet:
Step 3: Kubelet Automatically Restarts API Server
Because /etc/kubernetes/manifests/*.yaml runs as a static pod, changes automatically recreate the API server.
Check pod:
Wait for it to restart.
Step 4: Use the New User with kubectl
Edit (or create) a kubeconfig entry:
Add user
Add context
Switch to user
Step 5: Apply RBAC for this User
Apply RBAC as follows:
Apply:
Step 6: Test Access
Execute:
The output should indicate:
Allowed commands based on RBAC
Forbidden when not authorized
Notes / Gotchas
This does NOT work in:
EKS
GKE
AKS
K3s (unless you patch API server arguments manually)
In highly secure production clusters, this method is deliberately disabled.