K3s
RBAC
Role Based Access Control
Kubernetes
Access Management

RBAC Role Based Access Control on K3s

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

K3s supports Kubernetes RBAC in the normal Kubernetes way. There is no special K3s-only RBAC syntax to learn. If you know how Role, ClusterRole, RoleBinding, and ClusterRoleBinding work in Kubernetes, the same model applies to K3s.

One Important K3s Detail

K3s ships with an admin kubeconfig, commonly at /etc/rancher/k3s/k3s.yaml, and that config usually grants broad administrative access. This is convenient for bootstrap and local use, but it also means many people start by using credentials that bypass the need to think about RBAC at all.

That is why RBAC can feel invisible in small K3s clusters until you create separate service accounts or user identities with restricted permissions.

The Core RBAC Objects

The main RBAC objects are the same as in upstream Kubernetes:

  • 'Role: permissions inside one namespace'
  • 'ClusterRole: cluster-wide or reusable permissions'
  • 'RoleBinding: attaches a Role or ClusterRole to a subject inside one namespace'
  • 'ClusterRoleBinding: attaches a ClusterRole cluster-wide'

If the permission target is namespace-scoped, start with Role and RoleBinding. If the permission spans all namespaces or cluster-scoped resources, use ClusterRole and probably ClusterRoleBinding.

Example: Read Pods in One Namespace

Here is a simple namespace-scoped example for K3s:

yaml
1apiVersion: v1
2kind: Namespace
3metadata:
4  name: demo
5---
6apiVersion: v1
7kind: ServiceAccount
8metadata:
9  name: pod-reader
10  namespace: demo
11---
12apiVersion: rbac.authorization.k8s.io/v1
13kind: Role
14metadata:
15  name: pod-reader
16  namespace: demo
17rules:
18  - apiGroups: [""]
19    resources: ["pods"]
20    verbs: ["get", "list", "watch"]
21---
22apiVersion: rbac.authorization.k8s.io/v1
23kind: RoleBinding
24metadata:
25  name: pod-reader-binding
26  namespace: demo
27subjects:
28  - kind: ServiceAccount
29    name: pod-reader
30    namespace: demo
31roleRef:
32  apiGroup: rbac.authorization.k8s.io
33  kind: Role
34  name: pod-reader

Apply it with:

bash
kubectl apply -f rbac-demo.yaml

This grants read-only pod access in the demo namespace to the pod-reader service account.

Example: Cluster-Wide Read Access

If you want to allow read access across namespaces, use a ClusterRole.

yaml
1apiVersion: rbac.authorization.k8s.io/v1
2kind: ClusterRole
3metadata:
4  name: pod-reader-global
5rules:
6  - apiGroups: [""]
7    resources: ["pods"]
8    verbs: ["get", "list", "watch"]
9---
10apiVersion: rbac.authorization.k8s.io/v1
11kind: ClusterRoleBinding
12metadata:
13  name: pod-reader-global-binding
14subjects:
15  - kind: ServiceAccount
16    name: pod-reader
17    namespace: demo
18roleRef:
19  apiGroup: rbac.authorization.k8s.io
20  kind: ClusterRole
21  name: pod-reader-global

This is broader than the first example, so use it only when the subject genuinely needs cluster-wide visibility.

Testing RBAC in K3s

A very useful command for verifying access is:

bash
kubectl auth can-i list pods --as=system:serviceaccount:demo:pod-reader -n demo

And a negative check:

bash
kubectl auth can-i delete pods --as=system:serviceaccount:demo:pod-reader -n demo

These commands are excellent for confirming that your RBAC rules actually express the permissions you intended.

K3s-Specific Practical Advice

Because K3s is often used in homelabs, edge environments, and lightweight clusters, people frequently run everything with the default admin kubeconfig longer than they should. That is fine for quick experiments, but once multiple workloads or users exist, create narrower identities and bindings.

In other words, K3s does not remove the need for least privilege just because the cluster is small.

Service Accounts Are Usually the Starting Point

In many K3s deployments, RBAC is most commonly applied to:

  • in-cluster workloads
  • CI jobs
  • GitOps agents
  • automation scripts

That usually means binding permissions to service accounts rather than to human users directly.

This tends to produce clearer, more auditable access boundaries.

Common Pitfalls

One common mistake is editing RBAC rules while still testing everything with the default admin kubeconfig. That can make it look as if the RBAC rules are irrelevant because the admin identity bypasses the restriction.

Another issue is using ClusterRoleBinding when a namespace-scoped RoleBinding would have been enough. That grants far more access than necessary.

Developers also sometimes forget that RoleBinding can point to a ClusterRole. That is useful when you want reusable rules applied only inside one namespace.

Finally, always test with kubectl auth can-i or by using the intended identity directly. RBAC manifests are easy to misread if you rely only on visual inspection.

Summary

  • K3s uses standard Kubernetes RBAC objects and behavior.
  • The default K3s admin kubeconfig has broad permissions, so restricted identities often need to be created explicitly.
  • Use Role and RoleBinding for namespace-scoped access.
  • Use ClusterRole and ClusterRoleBinding only when broader access is actually needed.
  • Verify your rules with kubectl auth can-i instead of assuming the YAML says what you meant.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.