# Exercise 2: Triage a Scan Report and Write a Pod Security Policy

## Part A — Scan Triage

`trivy image registry.acme.io/orders:2.3.1` reports:

| CVE | Package | Installed | Fixed in | Severity | Notes |
|---|---|---|---|---|---|
| CVE-2024-AAAA | openssl (libssl3) | 3.0.11-1 | 3.0.13-1 | HIGH | base image package |
| CVE-2024-BBBB | glibc | 2.36-9 | — | CRITICAL | no fix available yet |
| CVE-2024-CCCC | curl | 7.88.1-10 | 7.88.1-10+deb12u5 | MEDIUM | curl isn't used by the app |
| CVE-2024-DDDD | express (npm) | 4.18.2 | 4.19.2 | HIGH | open redirect in `res.redirect` |
| CVE-2024-EEEE | semver (npm) | 5.7.1 | 5.7.2 | HIGH | ReDoS, transitive via a devDependency |
| CVE-2024-FFFF | perl-base | 5.36.0-7 | — | LOW | |

The image is `node:20-bookworm` (not slim) with a single stage.

1. For each finding, decide: **fix now**, **fix by rebuilding**, **remove the package**, **accept with justification (time-boxed)**, or **false positive for our usage** — and explain.
2. Which **two changes to the Dockerfile** would eliminate the most findings at once?
3. Propose the CI policy: which severities block a deploy, how "no fix available" is handled, and how accepted risks expire.

## Part B — Kubernetes Pod Hardening

Write the `securityContext` (pod and container level) and a `NetworkPolicy` for the `orders` Deployment, given:

- the app listens on 8080, needs to write only to `/tmp`, talks to `postgres` (port 5432) and `payments` (port 443) in the same namespace, and receives traffic only from the `api-gateway` pods;
- it needs no Kubernetes API access;
- the namespace should comply with the **restricted** Pod Security Standard.

## Requirements Checklist

- [ ] OpenSSL/curl: fixed by rebuilding on the patched base (and curl removed entirely by moving to slim/distroless).
- [ ] glibc with no fix: accepted temporarily with a documented assessment and expiry date, or mitigated by moving to a base without it (distroless/static for compatible runtimes) — not silently ignored.
- [ ] express: fix now by upgrading the dependency (it's in the runtime path).
- [ ] semver via a devDependency: disappears from the runtime image with a multi-stage build / `--omit=dev`.
- [ ] The two highest-impact Dockerfile changes: switch to a slim/distroless runtime and multi-stage with production-only dependencies.
- [ ] securityContext includes `runAsNonRoot: true`, a non-zero `runAsUser`, `allowPrivilegeEscalation: false`, `readOnlyRootFilesystem: true` (+ `emptyDir` for /tmp), `capabilities: { drop: ["ALL"] }`, `seccompProfile: RuntimeDefault`, and `automountServiceAccountToken: false`.
- [ ] NetworkPolicy: default-deny ingress/egress, allow ingress from `api-gateway` on 8080, egress to `postgres:5432`, `payments:443`, and DNS (UDP/TCP 53 to kube-dns).
