Files
rootnode-academy/content/root/root-09-kubernetes-security/m02-serviceaccounts-and-rbac/04-guided-exercise-least-privilege-role.md
T
ced4568andClaude Sonnet 5 7f6e1857c0 feat(curriculum): Phase 6C module upgrades, security assessment bank, ROOT 11 orientation
Upgrades six PARTIAL modules to the gold-module standard (lesson/demonstration/
knowledge-check/guided-exercise/lab(s)/reflection), preserving every existing lab
activity_id and scenario_id: root-06-m03 (jobs/cronjobs/daemonsets), root-07-m04
(ingress/networkpolicy), root-07-m02 (configuration/secrets, converted in place
from a bare 5-lab bank), root-09-m02 (serviceaccounts/rbac), root-09-m03
(network/supply-chain security), root-10-m03 (troubleshooting framework).

root-05-m01 (20-task kubectl-fluency bank) gets a minimal bookending lesson +
reflection rather than a full redesign, since each task already carries its own
explanation. root-12-m01, root-capstone-m01, and root-09-m04 are promoted to
READY via documented exceptions (no new activities) where adding one would
misrepresent their intentional design.

Wires a new rootnode-security-assessment (exam, 60min, hint_policy disabled)
using the existing Phase 3B assessment engine: 3 required hands-on CORE
scenarios + 4 random-draw pools covering SecurityContext, RBAC, network
policy, and the 7 previously-unwired CKS MCQs. Wires the previously-unwired
readiness-probe-task scenario as an OPTIONAL practice lab in root-10-m01,
using the existing is_required model.

Adds root-11-m01-devops-platform-thinking — an honest, lesson-only ROOT 11
orientation module naming DevOps/platform engineering practices already
exercised in ROOT 05-10/12, explicit that GitOps/CI-CD/IaC/observability need
lab infrastructure this platform doesn't yet provide. No fake labs.

Adds infra/scripts/validate-course-content.js: cross-checks the DB against
scenario/content files for duplicate ids, orphans, invalid references, cycles,
sequence collisions, instructor-notes leakage, and (new) self-paced content
deferring explanation to a live instructor. 0 errors against the resulting
22 courses/modules, 163 activities, 98 scenario files.

No application code changed — every gap was satisfiable with existing tables
(course_modules, module_activities, assessment_definitions) and the existing
content-delivery pipeline.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-26 11:20:17 -05:00

2.4 KiB

Guided Exercise: Writing a Least-Privilege Role

Paper-and-thinking exercise before the Labs.

The scenario

A monitoring agent needs to run inside your cluster. Its ONLY job is to periodically list Pods and read their status, across the whole cluster, to report health metrics elsewhere. It never needs to create, modify, or delete anything, and it never needs to touch Secrets, ConfigMaps, or any object type other than Pods.

Your task

  1. Should this use a Role or a ClusterRole? Justify your answer based on scope.
  2. Which verbs does it actually need? Which common verbs (create, update, delete, patch) should be deliberately left OUT?
  3. Does it need access to Secrets? Why is it tempting to grant broader access "just in case," and why should you resist that?
  4. What would you check, using kubectl auth can-i, to CONFIRM your Role is exactly as narrow as intended before deploying it?

A worked answer to check yourself against

  1. ClusterRole (bound via a ClusterRoleBinding) — it needs to see Pods across the WHOLE cluster, not just one namespace, so a namespace-scoped Role can't satisfy the requirement.
  2. get, list, watch on pods — read-only verbs only. Deliberately exclude create, update, patch, delete — this workload never legitimately needs to change anything.
  3. No — it never touches Secrets, so it should get zero permission on them. The temptation to "just in case" grant broader access is exactly what least privilege exists to resist: every unused permission is pure risk with no corresponding benefit if this workload is ever compromised.
  4. Run kubectl auth can-i delete pods --as=<the ServiceAccount> and confirm it returns no — and similarly check a Secrets verb returns no — proving the Role is bounded, not just assuming it from reading the YAML.

Instructor Notes

Facilitation: Question 3 is the core judgment call this exercise is testing — push on WHY "just in case" access is a real anti-pattern, not just point out that it is one.

Approximate timing: 10-12 minutes live with discussion; 10 minutes self-paced.

Optional extension: ask what would change about the answer if this monitoring agent later needed to also restart crash-looping Pods automatically — a good check that students can reason about incrementally expanding a Role's scope only as far as a genuinely new requirement demands.