Skip to content

RBAC — Imperative Commands Reference

Reference: https://kubernetes.io/docs/reference/access-authn-authz/rbac/

See also: service_account_cluster_role_binding_role.md.md for full RBAC theory, Role vs ClusterRole, RoleBinding vs ClusterRoleBinding, YAML structure, and apiGroups.


The Exercise

Create a ServiceAccount app-account, Role app-role-cka, and RoleBinding app-role-binding-cka. The service account should be able to get pods only in the default namespace.

Fastest path — three commands:

kubectl create serviceaccount app-account
kubectl create role app-role-cka --verb=get --resource=pods
kubectl create rolebinding app-role-binding-cka --role=app-role-cka --serviceaccount=default:app-account

Done. No YAML needed.


The Mistake in the Raw Notes

# WRONG
kubectl create rolebinding app-role-binding-cka --role=app-role-cka --serviceaccount=app-account
# error: serviceaccount must be <namespace>:<name>

# CORRECT
kubectl create rolebinding app-role-binding-cka --role=app-role-cka --serviceaccount=default:app-account

--serviceaccount always requires the format <namespace>:<name>. Never just the name alone.

Why? ServiceAccounts are namespace-scoped. Two different namespaces can each have a ServiceAccount named app-account — they're different objects. Without the namespace prefix, Kubernetes can't tell which one you mean.


The Other Mistake — k get current-namespace

k get current-namespace
# error: the server doesn't have a resource type "current-namespace"

current-namespace is not a Kubernetes resource. It's not something the API server knows about. To find which namespace you're currently targeting:

kubectl config view --minify | grep namespace     # shows current context's namespace
kubectl config get-contexts                        # shows all contexts with their namespaces

If the namespace column is blank, you're in default.


All Imperative RBAC Commands — Broken Down

ServiceAccount

kubectl create serviceaccount app-account
kubectl create serviceaccount app-account -n my-namespace    # in specific namespace
kubectl get serviceaccounts
kubectl get sa                                               # short name
kubectl describe sa app-account
kubectl delete sa app-account

Role (namespace-scoped)

kubectl create role app-role-cka \
  --verb=get \
  --resource=pods

Multiple verbs:

kubectl create role app-role-cka \
  --verb=get,list,watch \
  --resource=pods

Multiple resources:

kubectl create role app-role-cka \
  --verb=get,list \
  --resource=pods,services,configmaps

Specific resource names only (restrict to one named resource):

kubectl create role app-role-cka \
  --verb=get \
  --resource=pods \
  --resource-name=specific-pod-name

In a specific namespace:

kubectl create role app-role-cka --verb=get --resource=pods -n my-namespace

ClusterRole (cluster-scoped, no namespace)

kubectl create clusterrole app-clusterrole \
  --verb=get,list,watch \
  --resource=pods,nodes

Use ClusterRole when: - The resource is cluster-scoped (nodes, PersistentVolumes, namespaces) - You want the same permissions to apply across all namespaces

RoleBinding

kubectl create rolebinding app-role-binding-cka \
  --role=app-role-cka \
  --serviceaccount=default:app-account

Bind to a user instead:

kubectl create rolebinding app-role-binding-cka \
  --role=app-role-cka \
  --user=jane

Bind to a group:

kubectl create rolebinding app-role-binding-cka \
  --role=app-role-cka \
  --group=developers

In a specific namespace:

kubectl create rolebinding app-role-binding-cka \
  --role=app-role-cka \
  --serviceaccount=default:app-account \
  -n my-namespace

Bind a ClusterRole with a RoleBinding (limits the ClusterRole's permissions to one namespace):

kubectl create rolebinding app-role-binding-cka \
  --clusterrole=app-clusterrole \           # ClusterRole, not --role
  --serviceaccount=default:app-account

ClusterRoleBinding (cluster-wide)

kubectl create clusterrolebinding app-crb \
  --clusterrole=app-clusterrole \
  --serviceaccount=default:app-account

--serviceaccount Format — The Rule

--serviceaccount=<namespace>:<name>

Always. No exceptions.

Scenario Flag value
SA app-account in default namespace --serviceaccount=default:app-account
SA app-account in team-a namespace --serviceaccount=team-a:app-account
SA app-account in kube-system --serviceaccount=kube-system:app-account

Verify Permissions — kubectl auth can-i

After creating, always verify it works:

# Can app-account get pods in default namespace?
kubectl auth can-i get pods --as=system:serviceaccount:default:app-account

# Can app-account list pods?
kubectl auth can-i list pods --as=system:serviceaccount:default:app-account

# Can app-account delete pods? (should be no)
kubectl auth can-i delete pods --as=system:serviceaccount:default:app-account

# Can a user do something?
kubectl auth can-i get pods --as=jane

# Check in a specific namespace
kubectl auth can-i get pods --as=system:serviceaccount:default:app-account -n my-namespace

--as format for service accounts: system:serviceaccount:<namespace>:<name>

This is different from the --serviceaccount flag format — note it's system:serviceaccount: prefix, not just namespace:name. Kubernetes identifies service accounts internally as system:serviceaccount:<ns>:<name>.

List all permissions for a subject:

kubectl auth can-i --list --as=system:serviceaccount:default:app-account


Inspect Existing RBAC Objects

# Roles
kubectl get roles
kubectl get roles -n my-namespace
kubectl describe role app-role-cka

# ClusterRoles
kubectl get clusterroles
kubectl describe clusterrole app-clusterrole

# RoleBindings
kubectl get rolebindings
kubectl describe rolebinding app-role-binding-cka     # shows who is bound and to what role

# ClusterRoleBindings
kubectl get clusterrolebindings
kubectl describe clusterrolebinding app-crb

kubectl describe rolebinding is especially useful — it shows both the role being referenced and the subjects (users, service accounts, groups) bound to it.


Generate YAML Without Creating (dry-run)

kubectl create role app-role-cka \
  --verb=get,list \
  --resource=pods \
  --dry-run=client -o yaml

kubectl create rolebinding app-role-binding-cka \
  --role=app-role-cka \
  --serviceaccount=default:app-account \
  --dry-run=client -o yaml

Use this when the question needs you to apply from a file, or when you want to inspect what the imperative command would create before committing.


Common Exam Patterns

"Create SA + Role + RoleBinding, SA can get pods in namespace X":

kubectl create sa my-sa -n my-namespace
kubectl create role my-role --verb=get --resource=pods -n my-namespace
kubectl create rolebinding my-rb --role=my-role --serviceaccount=my-namespace:my-sa -n my-namespace
kubectl auth can-i get pods --as=system:serviceaccount:my-namespace:my-sa -n my-namespace

"SA should be able to list deployments cluster-wide":

kubectl create clusterrole my-cr --verb=list --resource=deployments
kubectl create clusterrolebinding my-crb --clusterrole=my-cr --serviceaccount=default:my-sa
kubectl auth can-i list deployments --as=system:serviceaccount:default:my-sa

"What can this SA do?":

kubectl auth can-i --list --as=system:serviceaccount:default:my-sa


Quick Reference

# Create
kubectl create sa <name> [-n <ns>]
kubectl create role <name> --verb=<verbs> --resource=<resources> [-n <ns>]
kubectl create clusterrole <name> --verb=<verbs> --resource=<resources>
kubectl create rolebinding <name> --role=<role> --serviceaccount=<ns>:<sa> [-n <ns>]
kubectl create clusterrolebinding <name> --clusterrole=<cr> --serviceaccount=<ns>:<sa>

# Verify
kubectl auth can-i <verb> <resource> --as=system:serviceaccount:<ns>:<sa>
kubectl auth can-i --list --as=system:serviceaccount:<ns>:<sa>

# Inspect
kubectl describe rolebinding <name>
kubectl describe clusterrolebinding <name>
kubectl get roles,rolebindings -n <ns>
kubectl edit role app-role-cka
kubectl create role app-role-cka --verb=get,list,watch --resource=pods --dry-run=client -o yaml | kubectl apply -f -