← BLOG INDEX

Guardian: Turning Container Scan Results into Defensible Decisions

Why I built a container-security workflow that goes beyond vulnerability counts to policy, context, remediation and auditable exceptions.

Container scanners are very good at producing findings. That is not the same as helping someone decide whether an image should be deployed.

I built Guardian after repeatedly encountering the gap between a scan report and an operational decision. A result might contain hundreds of CVEs, several marked Critical, conflicting vendor severities, packages that are not reachable by the application and vulnerabilities for which no fix exists. “Fail” is easy to print. Explaining what must happen next is much harder.

Guardian is my attempt to turn that gap into a controlled workflow.

Start with evidence, not a magic score

Guardian scans container images and preserves the evidence behind the result. Trivy supplies package and vulnerability data, but the dashboard does not reduce the entire image to a single unexplained colour.

The workflow separates several questions:

  • What did the scanner find?
  • Which findings violate the current policy?
  • Are fixes available?
  • Does the image appear to be running on the observed Docker host?
  • Is that workload exposed?
  • Is there evidence of known exploitation or elevated likelihood?
  • What would a remediation change, and what risk would remain?

That distinction matters. CVSS describes technical severity; it does not by itself describe the risk of this package in this image, running in this environment. Runtime and exposure context can change urgency, but absence of evidence must not be presented as proof of safety.

Policy is part of the product

One Guardian investigation made the problem concrete. An nginx image contained hundreds of findings, including Critical and High vulnerabilities. A rebuilt candidate passed the configured gate even though unfixed serious findings remained.

The explanation was in policy: unfixed vulnerabilities were excluded from the blocking gate. The candidate had successfully removed the fixable violations, so “pass” meant that it complied with that rule. It did not mean the image contained no unacceptable residual risk.

That wording is more than interface polish. Security tools need to show exactly what a pass asserts. Guardian therefore treats policy configuration, the matching rule and the remaining findings as evidence that belongs beside the result.

Remediation is an experiment with controls

Guardian can generate a remediation proposal, but AI-generated Dockerfiles do not receive automatic trust. The proposal is reviewed, rebuilt without cache, rescanned and exercised inside an isolated smoke test. Registry push remains locked until the control gate succeeds.

The test environment is intentionally constrained: network disabled, read-only root filesystem, capabilities removed and no-new-privileges enabled. Those controls sometimes expose compatibility requirements that a normal container start would conceal.

For example, an nginx candidate rebuilt and rescanned successfully but failed its smoke test because nginx wanted to create a cache directory on a read-only filesystem. The right response was not a global “allow root” button. Guardian added a narrow, explicit compatibility exception: a small ephemeral tmpfs for the required cache path, only the necessary capabilities, no published ports, an owner, a reason and an expiry.

Crucially, that runtime exception did not waive the vulnerability policy. Compatibility risk and vulnerability risk remained separate decisions.

Context without false confidence

Guardian can enrich a scan with signals such as running-container matches, public exposure, CISA Known Exploited Vulnerabilities and EPSS. These are prioritisation aids, not escape hatches.

If no matching container is currently running, immediate exposure may be lower. It does not prove a vulnerable package is unreachable when the image is deployed tomorrow. If a CVE is absent from a known-exploited catalogue, that means no corresponding evidence was found in that source—not that exploitation is impossible.

I want the interface to make those limits explicit. Useful states include reachable, not reachable, not applicable, mitigated and unconfirmed, backed by evidence and a review date.

What Guardian is really testing

The technical project includes scanning, policy evaluation, container rebuilding, runtime tests, evidence storage and a web dashboard. The more interesting project is the decision model around them.

A defensible result should let another engineer answer:

  1. What was scanned?
  2. Which policy version judged it?
  3. What changed in remediation?
  4. Which tests passed?
  5. What serious findings remain?
  6. Who accepted any exception, why, and until when?

That is the difference between automating a scanner and building a security control. Guardian is still evolving, but its direction is clear: fewer unexplained verdicts, more reproducible evidence, and no claim of safety that the system cannot support.