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]>
52 lines
2.7 KiB
Markdown
52 lines
2.7 KiB
Markdown
# Guided Exercise: Planning Egress Restriction
|
|
|
|
Paper-and-thinking exercise before the Labs.
|
|
|
|
## The scenario
|
|
|
|
A `payment-processor` Pod handles sensitive transactions. It legitimately needs to reach:
|
|
- an internal `payments-db` Service, and
|
|
- one external payment gateway API.
|
|
|
|
It should NOT be able to reach anything else — including the public internet in general, other
|
|
internal services, or any other namespace.
|
|
|
|
## Your task
|
|
|
|
1. Why is restricting this Pod's OUTBOUND (egress) traffic just as important as restricting who
|
|
can reach IT (ingress), given what this Pod handles?
|
|
2. If this Pod were compromised via a vulnerable dependency, what would UNRESTRICTED egress let
|
|
an attacker do that restricted egress would prevent?
|
|
3. Sketch (in words) what an egress policy for this Pod needs to allow, and — just as
|
|
important — what it must NOT allow by omission.
|
|
4. Why might a security review flag a Pod with `policyTypes: ["Egress"]` but an EMPTY `egress`
|
|
list as suspicious, rather than assume it's simply "not configured yet"?
|
|
|
|
## A worked answer to check yourself against
|
|
|
|
1. A Pod handling sensitive data that's compromised is far more dangerous if it can freely
|
|
exfiltrate that data anywhere (unrestricted egress) than if its only reachable destinations
|
|
are pre-approved and narrow.
|
|
2. Unrestricted egress would let an attacker exfiltrate transaction data to an external server,
|
|
or download additional malicious tooling. Restricted egress limits it to only the
|
|
pre-approved destinations, even after compromise.
|
|
3. Allow: egress to `payments-db` (internal, by label/namespace selector) and the specific
|
|
external payment gateway (by IP range or, if supported, a domain-based egress rule). Must NOT
|
|
allow: general internet access, other internal Services, or any other namespace by default.
|
|
4. An empty `egress` list under `policyTypes: ["Egress"]` means DENY ALL outbound — exactly like
|
|
the ingress case from the lesson. A reviewer seeing this should confirm it's intentional
|
|
(a Pod that genuinely needs zero outbound network access) rather than assume it's an
|
|
oversight, since the two look identical in the YAML.
|
|
|
|
## Instructor Notes
|
|
|
|
**Facilitation:** Question 4 reinforces the same "empty rules list means deny-all, not
|
|
unconfigured" point from earlier lessons — a good moment to confirm it generalizes correctly to
|
|
egress, not just ingress.
|
|
|
|
**Approximate timing:** 10-12 minutes live with discussion; 10 minutes self-paced.
|
|
|
|
**Optional extension:** ask what additional control (beyond NetworkPolicy) a team might want for
|
|
truly sensitive egress, like restricting DNS resolution itself for this Pod — a forward pointer
|
|
to defense-in-depth without requiring a hands-on Lab here.
|