Skip to content

3. Identity and Access Management (IAM)

Identity and Access Management (IAM) in Kubernetes is how we define who can do what inside a cluster. As you start building systems or automating tasks, it’s critical to ensure that access is restricted, deliberate, and traceable. Kubernetes uses declarative resources to manage access at scale—and you’re about to get hands-on with those.


What You’ll Learn

  • How to inspect your kubeconfig to see which user and cluster you’re using
  • What role-based access control (RBAC) is and how it’s applied in Kubernetes
  • How to define and bind roles using YAML manifests
  • How to create and use service accounts
  • How to impersonate accounts for debugging access

KubeConfig

Before diving into access control, get a clear view of who you are and what cluster you’re talking to. This information is stored in the kubeconfig file, which is how kubectl knows what to connect to and with which credentials.

To inspect your kubeconfig, run:

Solution

kubectl config view

Take a look through the output. You’ll see one or more users, clusters, and contexts.

Try to answer

  • What is your current user?
  • Which cluster are you using?

Where does this information live? Typically, it’s sourced from a file on your machine. If you’re not sure where kubectl is getting this data:

Solution

Check the default location:

~/.kube/config

Authorization

Now that you know who you are, it’s time to explore what you’re allowed to do.

Info

Kubernetes supports several authorization modes, but RBAC (Role-Based Access Control) is the most commonly used. In RBAC, we grant permissions through Roles, and attach them to users or service accounts via RoleBindings.

Let’s see what you, the current user, are authorized to do. A good place to start is with the kubectl auth subcommand:

Solution

kubectl auth can-i --list

That shows your effective permissions. Now let’s take a wider look. How many roles are defined across all namespaces?

Solution

kubectl get roles -A

Roles define what can be done. But who can do it is defined by RoleBindings. First, pick a role that looks interesting, and examine what permissions it grants.

Solution

kubectl describe role <role-name> -n <namespace>

Then find out which users or service accounts are bound to that role. Look at the RoleBindings in the same namespace:

Solution

kubectl get rolebinding -n kube-system

Service Account

Let’s get practical. Soon, you’re about to create an operator that watches for participants “joining” the namespace classroom. Operators are automated controllers, and they typically run under a Service Account with scoped access.

Start by creating a new namespace classroom for this use case:

Solution

kubectl create ns classroom

Then create a service account named participant-notifier in that namespace. This is the identity your operator will use. Again kubectl create -his your best friend.

Solution

kubectl create serviceaccount participant-notifier -n classroom
If you use a dry-run, the created yaml should look like this:
apiVersion: v1
kind: ServiceAccount
metadata:
  name: participant-notifier
  namespace: classroom

Now define what this account is allowed to do. You’ll grant it permission to get, list, and watch pods — essentially allowing it to observe activity in the namespace.

Let’s do this via a ClusterRole defined in a manifest file. The reason? You’ll want to update and track this Role over time.

Info

A Role in Kubernetes defines permissions within a specific namespace, while a ClusterRole defines permissions across the entire cluster and can be used for both cluster-scoped and namespace-scoped resources.

Solution

kubectl create clusterrole participant-notifier-role \
  --verb=get,list,watch \
  --resource=pods \
  --dry-run=client -o yaml > participant-notifier-role.yaml

kubectl apply -f participant-notifier-role.yaml
The created yaml should look like this:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: null
  name: participant-notifier-role
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch

With the Role created, you now need to bind it to your service account using a RoleBinding. This tells Kubernetes: “Allow this account to do what the role defines.”

If you’re unsure how the RoleBinding command works, run kubectl create rolebinding -h.

Solution

kubectl create rolebinding participant-notifier-binding \
  --clusterrole=participant-notifier-role \
  --serviceaccount=classroom:participant-notifier \
  -n classroom \
  --dry-run=client -o yaml > participant-notifier-rolebinding.yaml

kubectl apply -f participant-notifier-rolebinding.yaml
The created yaml should look like this:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: participant-notifier-binding
  namespace: classroom
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: participant-notifier-role
subjects:
- kind: ServiceAccount
  name: participant-notifier
  namespace: classroom

Impersonate the Service Account

Admins often want to check the permissions of a certain user or test the access as if they were a different user. To check the permissions of a user, we can use the kubectl auth can-i command. Check the permissions of the participant-notifier service account with this command by asking if its possible to read pods and deployments.

Solution

kubectl auth can-i get pods -n classroom --as=system:serviceaccount:classroom:participant-notifier
kubectl auth can-i get deploy -n classroom --as=system:serviceaccount:classroom:participant-notifier

Furthermore, kubectl allows you to impersonate a user or service account using a special flag. So, we will try using the --as flag to act as our new service account:

Solution

kubectl get pods -n classroom --as=system:serviceaccount:classroom:participant-notifier  # should succeed
kubectl get deploy -n classroom --as=system:serviceaccount:classroom:participant-notifier  # should fail

This is a great way to verify that your permissions are scoped just right—not too broad, not too narrow.

End of Lab