# Identity for Workloads: ServiceAccounts & RBAC ## Workloads need an identity too, separate from yours When YOU run `kubectl`, you're authenticated as yourself. But a Pod running INSIDE the cluster that needs to call the Kubernetes API (to list other Pods, read a ConfigMap, whatever) needs its own identity — it can't and shouldn't use your personal credentials. That identity is a **ServiceAccount**. Every Pod runs as SOME ServiceAccount — if you don't specify one, it uses the `default` ServiceAccount in its Namespace, which by default has essentially no permissions. A Pod's ServiceAccount token is automatically mounted into the container unless you explicitly disable that (`automountServiceAccountToken: false`) — worth doing for any Pod that never actually needs to call the Kubernetes API at all, since an unused, mounted credential is still something an attacker could steal and use. ## RBAC: what that identity is actually allowed to do Having an identity (a ServiceAccount) doesn't grant any permissions by itself — **RBAC (Role-Based Access Control)** is the separate system that defines what an identity can DO. - A **Role** (namespace-scoped) or **ClusterRole** (cluster-wide) defines a set of permissions: which API resources, which verbs (get/list/watch/create/update/delete). - A **RoleBinding** (or **ClusterRoleBinding**) connects a Role/ClusterRole to a specific identity (a ServiceAccount, a user, or a group) — the Role alone grants nothing to anyone until it's bound. ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: pod-reader namespace: default rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods namespace: default subjects: - kind: ServiceAccount name: my-app roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io ``` This grants the `my-app` ServiceAccount permission to `get`/`list` Pods in the `default` Namespace — and nothing else. It cannot delete Pods, cannot touch Secrets, cannot do anything not explicitly listed. ## Role vs. ClusterRole: scope matters A Role only grants permissions within the ONE Namespace it's defined in. A ClusterRole can grant permissions across the entire cluster (or, bound via a RoleBinding instead of a ClusterRoleBinding, can also be reused namespace-by-namespace) — reach for a ClusterRole only when the workload genuinely needs cluster-wide visibility, not by default. ## Least privilege, applied to permissions specifically The same principle from the previous module applies directly here: grant the narrowest set of verbs on the narrowest set of resources that the workload actually needs. A Role granting `get`/`list` on Pods is very different from one granting `*` on `*` — the latter is "root-equivalent" API access, and should be treated with exactly that level of caution. ## Instructor Notes **Approximate timing:** 15 minutes read; 10 minutes live. **Likely misconceptions to watch for:** - Students often conflate "ServiceAccount" with "user account for logging in." A ServiceAccount is specifically an identity for WORKLOADS, not a human login mechanism. - The Role/RoleBinding two-step (define permissions, then separately grant them to someone) is sometimes seen as redundant. Emphasize the reuse benefit: the same Role can be bound to multiple identities without redefining the permission set each time. **Discussion question:** "Why might you explicitly disable automounting a ServiceAccount token for a Pod that never calls the Kubernetes API?" (Answer: an unused but present credential is still something an attacker who compromises the container could steal and use elsewhere — removing it entirely removes that risk for a Pod that never needed it.) **Optional extension:** ask what the practical difference is between granting a ClusterRole via a RoleBinding (scoped to one Namespace) versus a ClusterRoleBinding (cluster-wide) — a good check that students understand the Role/ClusterRole and Binding-type distinctions are independent axes, not the same choice.