KCSA — User & Group Management
Users in Kubernetes — There Is No User Object
One of the most important things to understand for the KCSA exam:
Kubernetes has no User API resource. There is no kubectl create user command. There is no user database inside the cluster.
Human users exist entirely outside of Kubernetes. The API server determines user identity from the authentication layer — certificates, OIDC tokens, or webhook responses — but it never stores or manages users.
This design is intentional. Kubernetes delegates user management to external systems that organizations already have (Active Directory, LDAP, OIDC providers), rather than reinventing identity management.
Where Does User Identity Come From?
| Authentication Method | Username Source | Group Source |
|---|---|---|
| X.509 Client Certificate | Common Name (CN) |
Organization (O) fields |
| OIDC Token | Configured claim (e.g., email) |
Configured claim (e.g., groups) |
| Webhook Token Auth | status.user.username in response |
status.user.groups in response |
| Service Account Token | system:serviceaccount:<ns>:<name> |
system:serviceaccounts, system:serviceaccounts:<ns> |
The API server treats the identity information from any authenticator the same way — as a username, a UID, and a list of groups. RBAC does not care how the identity was established, only what the identity is.
Groups in Kubernetes
Groups are strings associated with an authenticated identity. They have special significance in RBAC because you can bind roles to groups rather than individual users.
Built-in Groups
| Group | Members | Description |
|---|---|---|
system:masters |
Users in this group | Superuser — bypasses all RBAC. Bound to cluster-admin ClusterRole by default |
system:authenticated |
All authenticated users | Automatically assigned to every authenticated request |
system:unauthenticated |
Anonymous requests | Assigned when no authentication succeeds |
system:serviceaccounts |
All service accounts | Every SA in every namespace |
system:serviceaccounts:<ns> |
SAs in namespace <ns> |
Useful for namespace-scoped RBAC |
How Groups Are Assigned
Groups come from the authenticator. For example:
Certificate-based: The O (Organization) fields in the certificate subject become groups.
Subject: CN=jane, O=developers, O=platform-team
→ User jane belongs to groups developers and platform-team.
OIDC-based: The claim configured via --oidc-groups-claim is parsed as a list of groups.
{
"sub": "jane@example.com",
"email": "jane@example.com",
"groups": ["developers", "platform-team"]
}
→ User jane@example.com belongs to groups developers and platform-team.
The system:masters Group — Handle with Care
The system:masters group is hard-coded into the Kubernetes API server. Members of this group:
- Bypass all RBAC authorization — even if no ClusterRoleBinding exists.
- Cannot have their access restricted via RBAC.
- Should be used for break-glass emergency access only.
Never include system:masters in OIDC group claims or certificate organizations for regular users. This effectively gives them unrestricted cluster-admin access that cannot be revoked via RBAC.
Who Should Be in system:masters?
| Appropriate | Not Appropriate |
|---|---|
| Break-glass emergency admin certificates | Developer accounts |
| Initial cluster bootstrap identity | CI/CD service accounts |
| OIDC-mapped groups | |
| Regular admin accounts |
Regular administrators should receive permissions via RBAC bindings (e.g., binding cluster-admin ClusterRole), not via system:masters membership. The difference: RBAC bindings can be audited and revoked.
OIDC Integration — The Recommended Approach
OIDC (OpenID Connect) is the recommended method for managing human user access to Kubernetes.
OIDC Flow
┌───────────┐ ┌─────────────────┐
│ User │ 1. Authenticate │ Identity Provider│
│ (browser/ │ ──────────────────► │ (Keycloak, Dex, │
│ kubectl) │ │ Azure AD, Okta) │
│ │ 2. Receive tokens │ │
│ │ ◄────────────────── │ │
└─────┬─────┘ └────────┬────────┘
│ │
│ 3. kubectl with │ IdP publishes
│ --token=<id_token> │ public keys at
│ │ /.well-known/openid-configuration
▼ │
┌──────────────┐ │
│ API Server │ 4. Validate JWT signature │
│ │ using IdP public keys ◄─┘
│ │ 5. Extract claims:
│ │ username = email claim
│ │ groups = groups claim
│ │ 6. Authorize via RBAC
└──────────────┘
API Server OIDC Configuration Flags
| Flag | Purpose | Example |
|---|---|---|
--oidc-issuer-url |
The URL of the IdP issuer | https://keycloak.example.com/realms/k8s |
--oidc-client-id |
The client ID registered with the IdP | kubernetes |
--oidc-username-claim |
JWT claim to use as username | email |
--oidc-groups-claim |
JWT claim to use as group list | groups |
--oidc-username-prefix |
Prefix added to the username | oidc: (prevents name collisions) |
--oidc-groups-prefix |
Prefix added to each group | oidc: |
--oidc-required-claim |
Key-value claim that must be present | iss=https://keycloak.example.com |
--oidc-ca-file |
CA certificate for the IdP | /etc/kubernetes/pki/oidc-ca.crt |
Using Prefixes to Avoid Conflicts
Without prefixes, an OIDC user named admin could collide with a certificate-based user also named admin. Prefixes prevent this:
--oidc-username-prefix=oidc:
--oidc-groups-prefix=oidc:
OIDC user jane@example.com in group developers becomes:
- Username:
oidc:jane@example.com - Group:
oidc:developers
RBAC bindings then target the prefixed names:
subjects:
- kind: Group
name: "oidc:developers"
apiGroup: rbac.authorization.k8s.io
Popular Identity Providers
| Provider | Type | Notes |
|---|---|---|
| Keycloak | Open-source | Full-featured; supports LDAP/AD federation |
| Dex | Open-source | Lightweight OIDC connector; aggregates multiple IdPs |
| Azure Active Directory | Cloud | Native integration with AKS |
| Google Identity | Cloud | Native integration with GKE |
| Okta | SaaS | Enterprise SSO platform |
| AWS IAM + OIDC | Cloud | EKS uses IAM roles for service accounts (IRSA) |
| GitHub (via Dex) | SaaS | Map GitHub org/team membership to K8s groups |
Exam Tip: You don’t need to know how to configure a specific IdP for the KCSA. Know that OIDC is the recommended method and understand the general flow.
Certificate-Based User Identity
For clusters that use X.509 client certificates, user identity is embedded in the certificate fields.
Certificate Fields to Kubernetes Identity
| Certificate Field | Kubernetes Mapping |
|---|---|
Common Name (CN) |
Username |
Organization (O) |
Group(s) |
Generating a User Certificate
# 1. Generate a private key
openssl genrsa -out jane.key 2048
# 2. Create a CSR with the desired username (CN) and groups (O)
openssl req -new -key jane.key -out jane.csr \
-subj "/CN=jane/O=developers/O=platform-team"
# 3. Sign with the cluster CA
openssl x509 -req -in jane.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial \
-out jane.crt -days 365
# 4. Configure kubectl
kubectl config set-credentials jane \
--client-certificate=jane.crt \
--client-key=jane.key
CertificateSigningRequest API
Since Kubernetes 1.19+, you can use the CSR API to request certificates:
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: jane-csr
spec:
request: <base64-encoded-CSR>
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
An administrator then approves the CSR:
kubectl certificate approve jane-csr
Certificate Limitations
| Limitation | Impact |
|---|---|
| No built-in revocation | Must use short-lived certs or maintain a CRL |
| No central management | Each certificate is independent |
| Group changes require new cert | Cannot update groups without reissuing |
| No MFA support | Certificate possession is the only factor |
Combining Identity Sources
In production, most clusters use multiple identity sources simultaneously:
| Client Type | Authentication Method | Identity |
|---|---|---|
| Control plane components | Client certificates | system:kube-controller-manager, etc. |
| Human operators | OIDC via IdP | oidc:jane@example.com |
| CI/CD pipelines | Service account tokens | system:serviceaccount:ci:deploy-bot |
| Emergency admin | Client certificate | CN=break-glass, O=system:masters |
This layered approach provides:
- Separation of concerns — each client type uses the most appropriate method.
- Centralized user management — human users managed in one IdP.
- Resilience — certificate-based emergency access works even if the IdP is down.
Key Takeaways for the Exam
| Concept | What to Remember |
|---|---|
| No User object | Kubernetes has no user API resource — users are external |
| Identity sources | Cert CN/O, OIDC claims, webhook response |
system:masters |
Hard-coded superuser group — bypasses all RBAC |
system:authenticated |
All authenticated users are in this group |
system:unauthenticated |
Anonymous requests — system:anonymous user |
| OIDC is recommended | For human users — centralized, short-lived, standard protocol |
| Use prefixes | --oidc-username-prefix and --oidc-groups-prefix prevent collisions |
| Certificate identity | CN = username, O = group(s) |
| Multiple sources | Production clusters use certs + OIDC + SA tokens together |
What’s Next?
The final topic in this chapter covers the different authorization modes available in Kubernetes and the best practices for configuring them.