Hardening containers and closing a 135-CVE dependency gap

Rebuilt backend services on hardened, non-root container images and cleared a full dependency vulnerability scan — 135 CVEs flagged, 7 rated critical, all remediated.

01

Context

This is my evidence for security as an engineering practice, not a one-off fire drill. Security was one of the six competency areas in my promotion dossier, and this is the concrete work behind that: I didn't wait for an audit to force the issue — I closed the gap and made hardening the default for how backend services ship.

It's the case I point to whenever an interviewer asks whether I've worked on security specifically, rather than picking it up as a side effect of other work.

02

Problem

Backend services ran in containers on Kubernetes (GKE) without a formal hardening or CVE-remediation practice. Vulnerability exposure in base images and dependencies is easy to defer: it doesn't fail a build, a test, or a deploy — it just accumulates until an audit or an incident forces attention.

03

Constraints

The exposure was spread across two services and their full dependency trees, not a single fixable line — 135 CVEs flagged in the scan, of varying severity.
Non-root containerization touches the whole runtime, not just the Dockerfile: file permissions, process ownership, and anything that assumed root have to be re-verified.
Remediating a CVE isn't always a version bump — some require reworking how a dependency is used, or replacing it, without regressing behavior.
Prioritization mattered. With 135 flagged, treating all of them as equally urgent would have meant treating none of them as urgent.
04

Decision

Rebuilt service images on hardened, non-root Docker bases, so containers no longer ran as root by default.
Ran a full dependency vulnerability scan across both services, surfacing 135 CVEs in total.
Prioritized by severity first — remediated the 7 rated critical across the two services before working down the rest.
Made hardening a standing practice, not a one-time cleanup, so new dependencies and images are checked going forward rather than accumulating silently again.
05

Trade-offs

Non-root images over root (the default). Non-root containers reduce blast radius if a container is compromised, at the cost of re-verifying every place that assumed root access. I accepted the migration cost for the security guarantee.
Remediating by severity over chronological/alphabetical order. Working the 7 critical CVEs first meant the highest-risk exposure closed fastest, even though it meant leaving lower-severity items open longer.
06

Impact

Cleared the 135-CVE dependency scan, with all 7 critical vulnerabilities remediated.
Containers run as non-root by default across the hardened services.
Security hardening became a standing part of how backend services ship, not an audit-triggered scramble — one of the six areas cited in my promotion to mid-level.
07

Lessons Learned

Reusable engineering knowledge I carry forward from this:

Vulnerability exposure accumulates silently. Nothing in a normal build/test/deploy cycle forces attention to it — it needs its own standing practice, not just a response to an audit.
Prioritize remediation by severity, not by volume. With well over a hundred flagged items, working the highest-risk ones first is what makes the list tractable.
Non-root by default is a runtime decision, not just a Dockerfile line. It has to be verified across the whole service, not just declared.
08

Evidence

Cleared a 135-CVE dependency scan with all 7 critical vulnerabilities remediated across two services.
Rebuilt service images on hardened, non-root Docker bases.
Cited as one of six competency areas (security) in my promotion dossier (see companies/dynamox.md).
Source (private): consolidated career knowledge base.