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]>
46 lines
2.4 KiB
Markdown
46 lines
2.4 KiB
Markdown
# 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.
|