Amazon ECR's enhanced scanning finds vulnerabilities in container images the moment they're pushed. That's useful, but it answers a different question than the one a SOC 2 auditor or your own security team actually cares about: not "was this image vulnerable when built," but "is a vulnerable image currently running in production, and what's being done about it."
The Gap Between Scan-on-Push and Runtime Reality
An image can scan clean on push and become vulnerable days later when a new CVE is disclosed for a package already baked into that image — ECR's continuous scanning re-evaluates pushed images against updated vulnerability databases, but that re-scan doesn't automatically tell you which of those images are actually deployed and serving traffic right now versus sitting unused in the registry.
Building the Digest-to-Deployment Map
The pipeline we build correlates scan findings against what's actually running, using the image digest as the join key across ECR, ECS/EKS deployment state, and the finding itself:
import boto3
ecr = boto3.client("ecr")
ecs = boto3.client("ecs")
def find_running_images_with_critical_findings(cluster_name, repository_name):
"""Cross-references ECR scan findings against currently running
ECS task definitions by image digest."""
findings = ecr.describe_image_scan_findings(
repositoryName=repository_name, imageId={"imageTag": "latest"}
)
critical_cves = [
f for f in findings["imageScanFindings"]["findings"]
if f["severity"] in ("CRITICAL", "HIGH")
]
if not critical_cves:
return None
services = ecs.list_services(cluster=cluster_name)["serviceArns"]
running_digests = set()
for service_arn in services:
task_def = ecs.describe_services(cluster=cluster_name, services=[service_arn])
task_def_arn = task_def["services"][0]["taskDefinition"]
containers = ecs.describe_task_definition(taskDefinition=task_def_arn)
for c in containers["taskDefinition"]["containerDefinitions"]:
running_digests.add(c["image"])
image_digest = findings["imageId"]["imageDigest"]
is_running = any(image_digest in d for d in running_digests)
return {
"repository": repository_name,
"critical_findings": len(critical_cves),
"currently_deployed": is_running,
"priority": "P1" if is_running else "P3",
}
An image with critical findings that's actually deployed and serving traffic gets a P1 ticket immediately. The same findings on an image sitting unused in the registry (an old tag from a previous deployment, a build artifact from a branch that never merged) get a lower priority — still worth cleaning up, but not an active production risk demanding an immediate patch cycle.
Why This Prioritization Matters for CC7.1 Evidence
Auditors reviewing vulnerability management (typically CC7.1) want to see that findings get triaged by actual risk, not just that scanning is enabled. A vulnerability management program that treats every finding with equal urgency regardless of deployment status either burns out the team chasing low-risk findings or, more commonly, produces alert fatigue that causes real production-risk findings to get lost in the noise.
Closing the Loop With Remediation Tracking
Every P1 finding routes to a tracked remediation ticket with an SLA (commonly 7-14 days for critical findings actively running in production, longer for lower-priority items), and the evidence pack for an audit period exports the full history: finding detected, deployment status at detection time, ticket created, SLA, and resolution — the structured record that survives sampling far better than a scan report alone.
Frequently Asked Questions
Does this work with Kubernetes/EKS as well as ECS?
Yes — the same digest-correlation pattern applies to EKS, cross-referencing running pod image digests against ECR scan findings via the Kubernetes API instead of the ECS API, with the same triage logic downstream.
How often does ECR re-scan images for new vulnerabilities?
With enhanced scanning enabled, ECR continuously monitors pushed images against updated vulnerability databases, so a previously clean image can surface new findings without a new push — which is exactly why runtime correlation matters more than a one-time scan-on-push check.
What's a reasonable SLA for critical findings on production-deployed images?
This varies by organization risk tolerance and the specific CVE's exploitability, but 7-14 days for actively-exploited or high-severity findings on production workloads is a common baseline that auditors generally find reasonable.
Can this reduce our overall finding volume, or just prioritize it?
It doesn't reduce the underlying vulnerability count, but it dramatically reduces the number of findings requiring immediate action by separating genuine production risk from registry noise — which is usually the more actionable outcome for a team with limited remediation capacity.
Ask us what your GRC platform isn't covering on container vulnerability evidence → rutagon.com/contact or call 907-841-8407.