This chapter covers two critical features of Amazon Elastic Container Registry (ECR): image scanning and lifecycle policies. Both are essential for maintaining secure and cost-efficient container image repositories in production. On the SAA-C03 exam, these topics appear in roughly 5-8% of questions, often embedded within larger scenarios about CI/CD, security automation, or cost optimization. You must understand how scanning works (both basic and enhanced), how to interpret scan results, and how to automate image cleanup using lifecycle policy rules. The exam tests your ability to select the correct scanning mode, configure lifecycle rules with specific tag prefixes and age conditions, and integrate these features with AWS Security Hub and other services.
Jump to a section
Imagine you run a large library that receives new books daily. Each book must be scanned for mold, torn pages, or missing covers before it can be shelved. You hire a scanning service that uses a specialized machine: it runs a set of known defect signatures against each page. The scan completes in a few seconds per book, and results are recorded in a log. For books already on shelves, you can request a rescan at any time. Separately, you have a shelf management policy: every month, you automatically remove books that haven't been borrowed in 3 years to make space for new arrivals. You set rules like 'if last borrowed date > 3 years, move to storage' or 'if book is damaged beyond repair, discard'. The policy runs nightly, evaluating each book's metadata and taking action only when conditions match. This mirrors Amazon ECR: images are scanned against known vulnerabilities using a scanner (like the machine), and lifecycle policies automatically expire old or untagged images based on rules you define (like shelf clearance). The scan results are stored as image metadata, and lifecycle rules evaluate tags and age to prune the repository.
What is Amazon ECR Image Scanning?
Amazon ECR image scanning automatically inspects container images for known software vulnerabilities. When you push an image to a repository, ECR can trigger a scan using a Common Vulnerabilities and Exposures (CVE) database. The scan identifies packages in the image that have known vulnerabilities and reports them with severity levels (CRITICAL, HIGH, MEDIUM, LOW, UNSPECIFIED). The exam expects you to know the two scanning types: Basic scanning and Enhanced scanning.
Basic Scanning
Basic scanning uses the open-source Clair project (originally from CoreOS) and the Amazon-provided CVE dataset. It scans images on push or on-demand. Key characteristics:
No additional cost beyond standard ECR storage and data transfer.
Scan results are stored as image metadata and can be retrieved via the AWS Management Console, AWS CLI (describe-image-scan-findings), or AWS SDK.
Scans are performed against the layers of the image; each layer is inspected for package versions and matched against the CVE database.
The scan completes asynchronously; you can check the status (IN_PROGRESS, COMPLETE, FAILED).
Basic scanning supports scanning on push (automatic) or manual (on-demand) via StartImageScan API.
The scan frequency: on push only, unless you trigger a rescan manually.
Enhanced Scanning
Enhanced scanning is a paid feature that integrates with Amazon Inspector. It provides continuous scanning of images, not just on push. Key characteristics:
Automatically rescans images when new CVEs are published (typically within 24 hours).
Uses Amazon Inspector’s vulnerability database, which includes CVEs from NVD, vendor-specific advisories, and AWS security bulletins.
Provides a consolidated view in Amazon Inspector dashboard, including network reachability findings.
Supports scanning for operating system and programming language packages (e.g., Python, Java, Node.js).
Can be enabled at the account level or per repository.
Pricing: based on the number of images scanned per month (see AWS pricing page).
How Scanning Works Internally
When an image is pushed:
1. ECR receives the image and stores its layers.
2. If scanning on push is enabled, ECR places a scan request in an internal queue.
3. The scanner (Clair for basic, Inspector for enhanced) pulls the image manifest and extracts package metadata from each layer.
4. It compares package names and versions against the CVE database.
5. Results are compiled into a scan findings report, which is attached to the image digest.
6. You can retrieve findings via DescribeImageScanFindings API. The report includes:
- imageScanStatus: status (COMPLETE, FAILED, IN_PROGRESS)
- imageScanFindings: list of findings with name, description, uri, severity, attributes (e.g., package name, version, CVE ID)
- enhancedFindings: (enhanced only) additional network reachability and exploitability details.
Example CLI command to initiate a scan:
aws ecr start-image-scan --repository-name my-repo --image-id imageTag=latestExample to retrieve findings:
aws ecr describe-image-scan-findings --repository-name my-repo --image-id imageTag=latestLifecycle Policies: What They Are
Lifecycle policies are a set of rules that automatically expire (delete) images from an ECR repository based on age or count. They help manage storage costs and keep repositories clean by removing stale images. The exam tests your ability to write policies using the JSON syntax with rules array, each containing a rulePriority, description, selection (with tagStatus, tagPrefixList, countType, countNumber, countUnit), and action (which is always expire).
Lifecycle Policy Rules Structure
Each rule has:
- rulePriority: integer, unique within the policy. Lower number = higher priority. Rules are evaluated in order; once an image matches a rule, it is marked for expiration and not evaluated against subsequent rules.
- description: free text.
- selection:
- tagStatus: tagged, untagged, or any. tagged means the image must have at least one tag. untagged means no tags. any includes both.
- tagPrefixList: (only for tagged) list of tag prefixes to match. E.g., ["dev-", "test-"].
- countType: imageCountMoreThan or sinceImagePushed.
- imageCountMoreThan: expire images when the number of images matching the selection exceeds countNumber.
- sinceImagePushed: expire images older than countNumber in countUnit (DAYS).
- countNumber: integer.
- countUnit: DAYS (only for sinceImagePushed).
- action: {"type": "expire"}.
Lifecycle Policy Evaluation
ECR evaluates lifecycle policies approximately once per day (every 24 hours). It is not real-time. The evaluation processes images in batches. If an image is referenced by a manifest list (multi-architecture image), the policy evaluates the manifest list as a single image. When an image is expired, its associated layers are deleted if no other image references them.
Example Lifecycle Policy
{
"rules": [
{
"rulePriority": 1,
"description": "Expire images older than 14 days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countNumber": 14,
"countUnit": "DAYS"
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 2,
"description": "Keep only 5 tagged images with prefix 'prod-'",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["prod-"],
"countType": "imageCountMoreThan",
"countNumber": 5
},
"action": {
"type": "expire"
}
}
]
}Common Exam Scenarios
You need to automatically delete untagged images older than 30 days. Answer: Use sinceImagePushed with countNumber: 30 and tagStatus: untagged.
You want to retain the latest 10 images for each tag prefix dev-. Answer: Use imageCountMoreThan with countNumber: 10 and tagPrefixList: ["dev-"].
You want to expire all images except those tagged latest. Answer: Use two rules: first rule for tagged with tagPrefixList: ["latest"] with a high countNumber (e.g., 100000) to effectively keep them, second rule for any with low count.
Integration with Other Services
Amazon EventBridge: ECR image scan findings can be sent to EventBridge as events. You can trigger Lambda functions to remediate (e.g., send notification, block deployment).
AWS Security Hub: Enhanced scanning findings appear in Security Hub for centralized security management.
AWS CodeBuild/CodePipeline: Integrate scanning as a step in CI/CD; fail the pipeline if critical vulnerabilities found.
Amazon Inspector: Enhanced scanning uses Inspector; you can view aggregated findings across accounts.
Default Values and Limits
Maximum number of lifecycle policy rules per repository: 10 (can be increased via service quota).
Maximum lifecycle policy document size: 30 KB.
Scan results retention: indefinitely (as long as image exists).
Basic scanning: no additional cost.
Enhanced scanning: charged per image scan (see AWS Inspector pricing).
Lifecycle policy evaluation: runs once per day, no manual trigger.
Trap Patterns on the Exam
Trap: Confusing imageCountMoreThan with sinceImagePushed. Remember: imageCountMoreThan counts the number of images matching the selection; if the count exceeds countNumber, the oldest images (by push date) are expired. sinceImagePushed expires images older than a specified number of days.
Trap: Thinking lifecycle policies run in real-time. They run daily.
Trap: Assuming scanning on push is enabled by default. It is not; you must enable it per repository or use enhanced scanning at account level.
Trap: Believing enhanced scanning is free. It has a cost.
Trap: Mixing up tagStatus values: untagged means images with no tags; any includes both tagged and untagged.
Trap: Forgetting that lifecycle policies only delete images, not the underlying layers if shared. Layers are reference-counted.
Configuration via CLI
Enable scanning on push for a repository:
aws ecr put-image-scanning-configuration --repository-name my-repo --image-scanning-configuration scanOnPush=truePut lifecycle policy:
aws ecr put-lifecycle-policy --repository-name my-repo --lifecycle-policy-text file://policy.jsonGet lifecycle policy:
aws ecr get-lifecycle-policy --repository-name my-repoVerification Commands
List images:
aws ecr list-images --repository-name my-repoDescribe image (including scan status):
aws ecr describe-images --repository-name my-repoGet scan findings:
aws ecr describe-image-scan-findings --repository-name my-repo --image-id imageTag=latestEnable scanning on push
Before scanning can occur automatically, you must enable scanning on push for the repository. This is done via the AWS Console, CLI, or API. Use `aws ecr put-image-scanning-configuration --repository-name my-repo --image-scanning-configuration scanOnPush=true`. When this is enabled, every new image push triggers a scan. You can also manually start a scan later using `start-image-scan`. The scanning configuration is stored per repository. For enhanced scanning, you enable it at the account level or per repository via Amazon Inspector integration.
Push an image to the repository
Use `docker push` or any container runtime to push an image. For example: `docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo:latest`. ECR stores the image layers and manifests. If scanning on push is enabled, the push API triggers an asynchronous scan request. The scan does not block the push; the image is immediately available for use. You can check the scan status via `describe-images`.
Scan initiates and completes
ECR's scanning service (Clair for basic, Inspector for enhanced) pulls the image manifest and extracts package information from each layer. It compares package names and versions against the CVE database. The scan may take from a few seconds to several minutes depending on image size and number of layers. Basic scanning checks layers independently; enhanced scanning performs a more thorough analysis including transitive dependencies. Upon completion, the scan status changes to COMPLETE, and findings are stored.
View scan findings
You can view findings via Console (under repository -> image -> scan details) or CLI: `aws ecr describe-image-scan-findings --repository-name my-repo --image-id imageTag=latest`. The output includes a list of vulnerabilities with severity, CVE ID, package name, and version. For enhanced scanning, additional fields like network reachability are included. You can also send findings to EventBridge for automation.
Define and apply lifecycle policy
Create a JSON policy document with rules. Each rule defines selection criteria and action (expire). Use `aws ecr put-lifecycle-policy --repository-name my-repo --lifecycle-policy-text file://policy.json`. The policy is evaluated approximately once every 24 hours. The evaluation respects rule priority. Images that match a rule are marked for deletion. The actual deletion occurs shortly after evaluation, but layers are only deleted if no other image references them.
Enterprise Scenario 1: CI/CD Pipeline with Security Gates
A large e-commerce company runs a microservices architecture with hundreds of services. They use AWS CodePipeline to build and deploy Docker images. They need to ensure no image with critical vulnerabilities reaches production. They enable enhanced scanning on all repositories and integrate scan results with EventBridge. A Lambda function subscribes to scan completion events; if any CRITICAL vulnerability is found, it automatically updates the image tag to 'blocked' and sends a notification to the security team. The pipeline is configured to only deploy images tagged 'passed-scan'. This ensures that only safe images are deployed. They also use lifecycle policies to automatically delete images older than 90 days for all tags except 'latest' and 'stable', saving storage costs. A common mistake is forgetting to enable scanning on push for new repositories, which leads to un-scanned images in production. They solved this by using AWS Config rules to enforce scanning on push at the account level.
Enterprise Scenario 2: Multi-Account Compliance
A financial services firm must comply with PCI DSS, which requires vulnerability scanning of all container images. They use a centralized security account with Amazon Inspector to aggregate findings from all member accounts. They enable enhanced scanning at the organization level via AWS Organizations. Lifecycle policies are applied to each repository to expire untagged images after 7 days (since untagged images often result from failed builds). They also retain only the last 10 images per tag prefix (e.g., 'prod-') to limit audit scope. A challenge they faced: lifecycle policies did not run immediately after a security incident, so they had to manually trigger image expiration using a script that calls batch-delete-image. They learned that lifecycle policies are not suitable for immediate cleanup; for urgent removal, direct API calls are needed.
Enterprise Scenario 3: Cost Optimization for Dev/Test
A startup uses ECR for development and testing. Developers push many images daily, causing storage costs to balloon. They implement a lifecycle policy that expires all images older than 30 days for tags with prefix 'dev-' and keeps only the last 3 images for each branch. For untagged images (often from intermediate builds), they expire after 1 day. This reduced storage costs by 70%. They also use basic scanning to catch obvious vulnerabilities early. A common misconfiguration: setting countNumber too low for imageCountMoreThan accidentally deletes all images. They learned to test policies using get-lifecycle-policy-preview API to simulate what would be deleted.
SAA-C03 Exam Focus on ECR Image Scanning and Lifecycle Policies
The SAA-C03 exam tests this topic under Domain 1: Secure Architectures (Objective 1.5: Define mechanisms for secure container-based workloads). You must be able to:
Differentiate between basic and enhanced scanning, including cost and features.
Configure scanning on push vs. on-demand.
Interpret scan findings and integrate with EventBridge or Security Hub.
Write lifecycle policy rules using correct JSON syntax, especially tagStatus, countType, countNumber, and countUnit.
Understand that lifecycle policies run daily, not real-time.
Know that scanning on push is not default.
Recognize that enhanced scanning uses Amazon Inspector and incurs cost.
Common Wrong Answers and Why Candidates Choose Them
Wrong: 'Lifecycle policies can expire images immediately after a push.' Why candidates choose: they think it's real-time. Reality: runs daily.
Wrong: 'Basic scanning provides continuous scanning and rescan on new CVE.' Why: candidates confuse basic with enhanced. Reality: basic only scans on push or manual trigger.
Wrong: 'To expire images older than 30 days, use countType: imageCountMoreThan.' Why: they confuse count-based with age-based. Reality: use sinceImagePushed with countUnit: DAYS.
Wrong: 'Enhanced scanning is free.' Why: they think it's included. Reality: it's a paid feature.
Specific Numbers and Terms Appearing on Exam
countNumber and countUnit: e.g., countNumber: 14, countUnit: DAYS.
tagStatus: tagged, untagged, any.
tagPrefixList: e.g., ["prod-"].
rulePriority: integer, lower number = higher priority.
imageCountMoreThan: expire when count exceeds number.
sinceImagePushed: expire based on age.
Default evaluation frequency: once per day.
Maximum rules per repository: 10 (default).
Edge Cases and Exceptions
If an image has multiple tags, each tag is considered separately for lifecycle rules? No: the image itself is evaluated once. If it matches a rule by any tag, it is expired. Tags are not independent.
For multi-architecture images (manifest lists), the manifest list is treated as a single image.
Lifecycle policy rules cannot be applied to specific image digests; only tags.
Scanning findings are available only while the image exists; if deleted, findings are lost.
How to Eliminate Wrong Answers
If the scenario mentions 'continuous scanning' or 'automatic rescan on new CVE', the answer must be enhanced scanning (Amazon Inspector).
If the scenario mentions 'cost savings' and 'automatic deletion of old images', the answer is lifecycle policy with sinceImagePushed.
If the question asks about 'real-time' or 'immediate' deletion, that's a trap; lifecycle policies are not real-time.
If the question involves 'untagged images' and 'age', the correct rule uses tagStatus: untagged and countType: sinceImagePushed.
Remember: imageCountMoreThan is for count-based expiration, not age.
Basic scanning is free but only scans on push; enhanced scanning is paid but continuous.
Lifecycle policies evaluate daily, not in real-time.
Use `sinceImagePushed` with `countUnit: DAYS` for age-based expiration.
Use `imageCountMoreThan` to keep only a certain number of images.
`tagStatus` can be `tagged`, `untagged`, or `any`.
Lifecycle policies cannot act on scan findings; use EventBridge + Lambda for that.
Scan findings can be retrieved via `describe-image-scan-findings` CLI command.
Enhanced scanning integrates with Amazon Inspector and AWS Security Hub.
These come up on the exam all the time. Here's how to tell them apart.
Basic Scanning
Uses open-source Clair project
Scans on push or on-demand only
No automatic rescan on new CVEs
Free (no additional cost)
Findings only available in ECR
Enhanced Scanning
Uses Amazon Inspector
Continuous scanning (rescans on new CVEs)
Includes network reachability analysis
Paid (per image scan)
Findings integrated with Security Hub and Inspector dashboard
Mistake
ECR image scanning automatically blocks the push of vulnerable images.
Correct
No, scanning is asynchronous and does not block the image push. The image is stored and available immediately. You must implement separate mechanisms (e.g., CI/CD pipeline gating) to prevent deployment of vulnerable images.
Mistake
Lifecycle policies run in real-time after an image is pushed.
Correct
Lifecycle policies are evaluated approximately once every 24 hours. They do not run immediately upon push. For immediate deletion, you must use the `batch-delete-image` API.
Mistake
Basic scanning rescans images when new CVEs are published.
Correct
Basic scanning only scans on push or when manually triggered. It does not automatically rescan. Enhanced scanning (via Amazon Inspector) does continuous rescanning.
Mistake
Enhanced scanning is free and included with ECR.
Correct
Enhanced scanning incurs additional costs based on the number of images scanned per month. See Amazon Inspector pricing for details.
Mistake
Lifecycle policies can be used to delete images based on vulnerability severity.
Correct
Lifecycle policies only evaluate image tags and push timestamps. They cannot inspect scan findings. To automate deletion based on vulnerabilities, you must use EventBridge and Lambda.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
You enable scanning on push by configuring the repository. Use the AWS CLI: `aws ecr put-image-scanning-configuration --repository-name my-repo --image-scanning-configuration scanOnPush=true`. Or in the Console, go to the repository, click 'Edit' and check 'Scan on push'. For enhanced scanning, enable Amazon Inspector and associate the repository.
Basic scanning uses Clair, is free, scans only on push or manual trigger, and does not rescan on new CVEs. Enhanced scanning uses Amazon Inspector, is paid, provides continuous scanning (rescans when new CVEs are published), includes network reachability, and integrates with Security Hub.
No. Lifecycle policies only evaluate image tags and push timestamps. They cannot read scan findings. To delete images based on vulnerabilities, you must use EventBridge to capture scan events and trigger a Lambda function that calls `batch-delete-image`.
Lifecycle policies are evaluated approximately once every 24 hours. It is not real-time. For immediate deletion, use the `batch-delete-image` API.
The image manifest and its tags are deleted. The underlying layers are deleted only if no other image references them. Layers are reference-counted, so shared layers are preserved.
Yes, use the `get-lifecycle-policy-preview` API or the Console preview feature. It simulates the rules and shows which images would be expired without actually deleting them.
Yes, the default maximum is 10 rules per repository. You can request a service quota increase.
You've just covered ECR Image Scanning and Lifecycle Policies — now see how well it sticks with free SAA-C03 practice questions. Full explanations included, no account needed.
Done with this chapter?