Guide 147 worked guide

How to review a container image alert in application context

Review container image alerts against shipped bytes, workload use and launch paths, including queued jobs and future tasks that could still run an old image.

Review a container image alert by first identifying the exact image digest and deployment, then checking the advisory's affected component and version, whether that component is in the final running image, and what application path could invoke the vulnerable behavior. Record exposure, privileges, available fix, and missing evidence separately. A package match establishes a review lead, not an exploit. It can still justify a compatible, low-risk upgrade before reachability is fully resolved; use reachability to set urgency and containment, not as a mandatory delay before repair. Conversely, “our code never imports it” is too weak to dismiss a library or operating-system package that a framework, subprocess, sidecar, or startup path may use. The answer changes with the vulnerability mechanism: a remotely reachable parser and a local-only build tool need different evidence and response times.

This is a security engineer's decision about a specific deployed artifact, not a vote on the scanner's severity badge. Docker documents that an image digest selects an immutable image version, while a tag can point to a newer image later. Kubernetes also accepts image tags or digests. Record the digest actually running before comparing scan reports, source, and remediation.

Illustrative case: a parser alert in a payments image

Illustrative case; names, package, version, and advisory are invented. No exploit was executed. The security team receives alert P-17: image AtlasPay API contains example package ArchiveKit 2.4.1, reportedly affected when it parses a crafted archive. The scanner assigns “critical.” The deployment inventory says the production payment API currently uses image digest D1, but the alert names a mutable tag, “atlas-api:stable.”

The first question is whether P-17 scanned D1. The release owner supplies the registry manifest and deployment record; they show that P-17 belongs to earlier digest D0. Keep P-17 attached to D0. A fresh scan of D1 creates a separate observation, P-18, that also reports ArchiveKit 2.4.1. P-18 supports a package-presence question for the running image; neither scan has established whether the unsafe parser is reachable.

The API itself accepts JSON payment requests. A background settlement job, built from the same image digest, receives customer-supplied ZIP files from a separate upload service and calls a wrapper that may invoke ArchiveKit. The job runs with permission to read settlement objects. The security engineer can now state a source-supported, conditional path: “If the wrapper passes untrusted ZIP data to the affected ArchiveKit parser in the deployed job, a crafted file could reach the vulnerable operation.” The wrapper's resolved dependency and job configuration still need review. There is no basis yet to claim an executed attack or to dismiss the finding because the public API accepts JSON.

Question AtlasPay evidence Current conclusion
Which artifact? P-17 belongs to D0; D1 deployment and P-18 scan match Investigate P-18 for the running image; retain P-17 as a D0 record
Component present? Final-image inventory reports ArchiveKit 2.4.1 Version match; scanner attribution needs confirmation
Trigger path? Settlement worker accepts ZIP data; wrapper calls an archive operation Plausible, not independently resolved
Actor and exposure? Customer upload flows to worker after validation Input control and validation behavior need inspection
Privilege and effect? Worker reads settlement objects Possible effect depends on the advisory and worker boundary
Fix? Maintainer lists a corrected version in the illustrative advisory Rebuild and verify a new digest before closure

This record gives the worker owner a bounded question rather than “fix a critical CVE in all containers.”

Locate the copy that the package inventory found

Continue AtlasPay with a synthetic final-image map. D1 is a symbolic label for a full digest, not an actual hash. Docker's multi-stage build guidance explains why build-stage packages and copied runtime outputs can differ.

Final-image location Origin Runtime use Advisory work
/app/api Application build output API command handles JSON No ArchiveKit path found in the supplied API call graph
/opt/settlement/unpack Executable copied from builder stage Settlement command invokes it for uploaded ZIPs Bundled ArchiveKit 2.4.1 identified by build/link records
OS package libarchive-demo Base distribution package Separate library copy Supplier claims backport; exact distribution revision/advisory still required

“No ArchiveKit package installed by the final package manager” would miss the copied executable's bundled library. “The builder stage was discarded” would also be insufficient: the executable crossed the stage boundary. The reviewer needs provenance of the final bytes, not just a package-manager database or a Dockerfile search.

The OS package is a separate identity. A supplier backport claim must name the actual distribution, release, package revision and fix. It cannot clear the bundled executable's upstream copy. All names and patch claims here are fictional; a real review must use the maintainer or distribution's current primary advisory.

One image, two process roles

The supplied entrypoint records show api for the payment service and settlement-import for the scheduled worker. Both use D1. The worker's call chain is upload object → settlement command → copied unpack executable → ArchiveKit. The API path does not call the executable in the reviewed configuration.

This changes the response. The image contains an affected copy regardless of which command runs. The supplied worker path supports investigating the advisory condition on customer-controlled input. The API evidence supports rejecting the same settlement-command path for that workload, not declaring the whole image safe or the API immune to every use of the library.

Record Component status Workload action
Image D1 Bundled affected version present; OS backport claim unresolved Image owner rebuilds from reviewed corrected inputs
API command No path to the bundled parser found in supplied call graph/configuration Schedule new image; retain scope and change triggers
Settlement command Customer ZIP reaches bundled parser; prerequisite/control review supplied as next task Consider restricting archive admission while resolving applicability; worker owner owns path review
Historical D0/P-17 Separate older artifact Preserve its release/exposure window; do not overwrite with D1 result

The rebuild may be shared, while containment is workload-specific. Pausing the public JSON API would not necessarily stop the settlement queue. Conversely, stopping new uploads without accounting for queued objects may leave the worker processing the same input class.

Close composition and deployment separately

The new image D2 must show that the copied executable was rebuilt or removed; merely updating the OS package could leave the bundled copy unchanged. Check the final-image inventory and build-copy map, then prove both API and settlement workloads use D2, including scheduled launch configuration and old attempts. The deployment-presence guide supplies the detailed identity joins.

No build or exploit was run for this article. A real closure needs the new artifact, the original vulnerable-operation check and authorized behavior evidence where required. Runtime presence, workload reachability and historical exploitation remain different conclusions.

Choose a response for queued work and future launches

AtlasPay's settlement worker introduces a timing question that an image dashboard cannot answer. Rebuilding D2 changes the candidate artifact; it does not tell the team what will happen to customer archives already queued for D1. The worker owner should map new admission, waiting objects, active attempts, retry policy and the next scheduled launch. These are distinct places where the old artifact may still be used.

In a synthetic response plan, the owner pauses new archive admission while preparing D2, identifies waiting settlement objects without opening customer content, and confirms which active attempts are still processing. The incident or service owner chooses how to handle those attempts according to the credible advisory effect and the operational cost of interruption. The article does not prescribe killing every process: that decision depends on the actual exposure and workload. It does require recording the old attempts rather than assuming a changed deployment template removed them.

A retry can matter even after the main rollout. If a failed task is relaunched from an older job definition, the corrected API deployment may coexist with a newly started D1 worker. The verification question is therefore about the effective launch source, not only the currently visible service image. Ask the release owner to show which digest the next scheduled and retried job would select, along with any remaining pinned older configuration.

Separate the fix candidates before rebuilding

AtlasPay has two package identities and two workload roles. Prepare a short change note for each candidate. The copied settlement executable needs corrected build inputs or removal of the affected bundled code. The distribution package needs its own advisory determination; replacing it merely to quiet a broad upstream match might add disruption without changing the bundled parser. Conversely, accepting a valid distribution backport does not remove the need to repair the executable.

The image owner should make the intended outcome explicit before starting a rebuild: which component changes, which build stage produces it, which final-image location contains it, and which command uses that location. That note lets a reviewer detect a rebuild that updated the base image while copying the same old executable from a cache or prebuilt artifact. The decisive comparison is the final component evidence for D1 and D2, with the production workload mapping attached.

Once D2 is available, functional acceptance should focus on the changed operation. AtlasPay's ordinary JSON API behavior and settlement archive handling have different contracts. A successful health check may establish that the container starts; it cannot establish that the copied unpack executable changed or that settlement imports still work. Use authorized safe representative inputs and the application's expected rejection behavior where validation is needed. Do not execute an exploit or customer archive merely to make the remediation record look stronger.

If compatibility blocks D2, record the specific failure and choose a temporary workload restriction or an alternative corrected build. The alert remains open for the affected digest, while the operational action can still reduce current exposure. That separation prevents a failed upgrade from becoming either a false closure or a reason to abandon containment.

Make the disposition reviewable

Use one of four working dispositions: affected path supported, not affected with a specific reason, under investigation, or fixed at a named digest. CISA's VEX minimum requirements similarly distinguish affected, not affected, fixed, and under investigation and require a justification or impact statement for “not affected.” You need not issue a formal VEX document to borrow that discipline.

For AtlasPay, the completed source handoff is:

P-18/D1: final-image provenance identifies ArchiveKit2.4.1 bundled into the copied settlement executable. The supplied settlement command reaches it with customer ZIP input; the API command does not use that path in the reviewed configuration. Image owner repairs the bundled copy, worker owner assesses/contains archive admission, and platform verifies both workload rollouts. The separate OS-package backport claim remains unresolved. No executed exploit is claimed.

If the wrapper proves it never invokes vulnerable code, record the exact control and scope of that conclusion. Do not use “not affected” as a permanent exception when the image, job, or parser path changes. For a concrete next step, select one noisy image alert and fill the six checks before assigning its severity to a sprint. Use the prioritization method for limited engineering time once the path is clear, or the cloud ownership guide when image and deployment fixes have different owners.