Create a Role for Read-Only Pod and Log Access
The support team needs to inspect application pods without changing workloads or reading credentials. Namespace `access-review`, ServiceAccount `log-reader`, and Deployment `api` already exist. Work in this namespace.
Live lab access
This scenario is included in Free Practice. Choose from 6 fixed labs with 5 shared sessions per week, automatic grading, hints, solutions, AI Lab Coach and saved progress.
Create an account for this free lab →
Explore the six free labs with AI Lab Coach →
Read the brief on any device. Use a desktop or laptop for the terminal lab. Nothing starts until you choose Start.
The task
The support team needs to inspect application pods without changing workloads or reading credentials. Namespace access-review, ServiceAccount log-reader, and Deployment api already exist. Work in this namespace.
Requirements
1. Create Role pod-observer granting get and list on core-API pods, and get on pods/log.
2. Create RoleBinding observe-pods binding that Role only to ServiceAccount log-reader in access-review.
3. Grant no additional resource permissions: no wildcard verbs, Secrets access, pod changes, or access to another namespace. Verify the effective permissions by impersonating the ServiceAccount.
Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster. Run the checks with an admin kubeconfig, because --as needs impersonation rights.
Least-privilege RBAC for a ServiceAccount, including subresources, proved with impersonation
RBAC only ever adds permissions: there are no deny rules, so anything a rule does not list is refused. A Role holds rules (API group, resource, verbs) inside one namespace, a RoleBinding attaches it to subjects, and a ServiceAccount is just another subject with the username system:serviceaccount:<namespace>:<name>. The part people miss is that subresources such as pods/log or deployments/scale are separate entries in a rule; permission on the parent resource does not include them.
ServiceAccount scale-bot ──(RoleBinding replica-tuner-bot)──→ Role replica-tuner
├─ apps/deployments get, list
└─ apps/deployments/scale get, patch, update
scope: namespace prepium-tutorial only
1. Create the subject and something to act on
kubectl create namespace prepium-tutorial
kubectl -n prepium-tutorial create serviceaccount scale-bot
kubectl -n prepium-tutorial create deployment metronome --image=nginx:1.27-alpine
The goal: a bot that can see Deployments and change their replica count, but cannot edit their image, read Secrets, or touch any other namespace.
2. Write the Role with two rules
kubectl create role applies one verb list to every resource you give it, so differing verbs per resource are easier in YAML. Save as replica-tuner.yaml:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: replica-tuner
namespace: prepium-tutorial
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments/scale"]
verbs: ["get", "patch", "update"]
Deployments live in the apps group; core objects such as Pods, Services and Secrets use the empty group "". The slash notation is how RBAC names a subresource, exactly as the official example does for pod logs.
3. Bind it to the ServiceAccount
kubectl apply -f replica-tuner.yaml
kubectl -n prepium-tutorial create rolebinding replica-tuner-bot \
--role=replica-tuner --serviceaccount=prepium-tutorial:scale-bot
kubectl -n prepium-tutorial get rolebinding replica-tuner-bot -o yaml
The --serviceaccount value is namespace:name, and the resulting subject has kind: ServiceAccount with its own namespace field. A binding's roleRef cannot be changed after creation; to point it at a different Role, delete and recreate the binding.
4. Prove allowed and denied actions
SA=system:serviceaccount:prepium-tutorial:scale-bot
kubectl auth can-i list deployments.apps -n prepium-tutorial --as=$SA
kubectl auth can-i patch deployments.apps --subresource=scale -n prepium-tutorial --as=$SA
kubectl auth can-i patch deployments.apps -n prepium-tutorial --as=$SA
kubectl auth can-i get secrets -n prepium-tutorial --as=$SA
kubectl auth can-i list deployments.apps -n default --as=$SA
kubectl auth can-i --list -n prepium-tutorial --as=$SA
Expect yes, yes, then no, no, no. The third line is the interesting one: the bot may resize a Deployment through its scale subresource yet cannot patch the Deployment object itself, so it can never swap the image. can-i exits 0 for yes and 1 for no, which makes it handy in scripts. The --list view shows your rules plus generic discovery and self-review entries, because an impersonated ServiceAccount is also in system:authenticated, which default ClusterRoles are bound to.
Common mistakes
- Putting
deploymentsunderapiGroups: [""]. The API server stores the Role, but no Deployment request matches it, so every check says no. - Granting
getonpodsand expectingkubectl logsto work. Logs needgetonpods/log, a separate entry. - Binding the wrong ServiceAccount namespace. A subject
scale-botin another namespace is a different identity, and impersonation checks reveal it at once. - Reaching for a ClusterRoleBinding or wildcard verbs to "make it work". That silently grants every namespace or every action.
| Example check | Evidence |
|---|---|
| Rules are exact | kubectl get role -o yaml lists only the intended groups, resources and verbs |
| Binding targets the right identity | Subject kind: ServiceAccount with matching name and namespace |
| Allowed actions work | kubectl auth can-i ... --as=system:serviceaccount:... answers yes |
| Everything else is refused | Same check for Secrets, parent-object writes and other namespaces answers no |
Cleanup: kubectl delete namespace prepium-tutorial removes the Role, binding and ServiceAccount with it. References: Using RBAC Authorization, kubectl auth can-i, kubectl create rolebinding. Next, try CKAD RBAC or ServiceAccount troubleshooting.
Practice scope
This additional curriculum lab is available in single-task practice with the existing 12-minute limit. Its alternate scenario also appears in one of the two mixed curriculum mocks. The first three 17-task mocks keep their original task sets. Hints, an explained solution and requirement-by-requirement feedback are available in the lab.
Browse CKA practice tasks →