These rules identify ECR repositories that are missing lifecycle policies or have incomplete lifecycle policies, which causes image storage to grow unbounded over time.
| Rule ID | Scan Type | Severity | Name |
|---|---|---|---|
| CLDBRN-AWS-ECR-1 | Discovery and IaC | Low | ECR Repository Missing Lifecycle Policy |
| CLDBRN-AWS-ECR-2 | Discovery and IaC | Low | ECR Lifecycle Policy Missing Untagged Image Expiry |
| CLDBRN-AWS-ECR-3 | Discovery and IaC | Low | ECR Lifecycle Policy Missing Tagged Image Retention Cap |
CLDBRN-AWS-ECR-1
ECR Repository Missing Lifecycle Policy
Scan type: Discovery and IaC
Severity: Low
What it checks
Flags ECR repositories that have no lifecycle policy configured. Without a lifecycle policy, every pushed image is retained indefinitely. Active CI/CD pipelines can push dozens of images per day, causing storage to accumulate rapidly.
Why it matters
ECR charges $0.10 per GB per month for storage. A repository receiving 10 image pushes per day, each 500 MB, accumulates 150 GB per month — $15/month from a single repository. Multiply across all repositories in an organization and the cost compounds quickly. Lifecycle policies expire old and untagged images automatically, keeping storage bounded.
What triggers a finding
hasLifecyclePolicy is false for the repository.
How to remediate
Add a lifecycle policy to expire untagged images and limit the number of tagged images retained. A common starting policy:
{
"rules": [
{
"rulePriority": 1,
"description": "Expire untagged images older than 7 days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 7
},
"action": { "type": "expire" }
},
{
"rulePriority": 2,
"description": "Keep only last 10 tagged images",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["v"],
"countType": "imageCountMoreThan",
"countNumber": 10
},
"action": { "type": "expire" }
}
]
}
IaC resources checked
| IaC Tool | Resource Type |
|---|---|
| Terraform | aws_ecr_repository, aws_ecr_lifecycle_policy |
| CloudFormation | AWS::ECR::Repository |
CLDBRN-AWS-ECR-2
ECR Lifecycle Policy Missing Untagged Image Expiry
Scan type: Discovery and IaC
Severity: Low
What it checks
Flags ECR repositories whose lifecycle policy does not include a rule that expires untagged images. Discovery fetches the live lifecycle policy from each repository and parses it the same way the IaC scan parses the policy document in your template.
Why it matters
Container builds produce untagged images over time. Without a lifecycle rule to expire them, untagged images accumulate storage charges indefinitely. ECR charges $0.10/GB-month for storage.
What triggers a finding
hasLifecyclePolicy is true AND hasUntaggedImageExpiry is false. A policy satisfies the check when it contains an expire rule whose tagStatus is untagged or any.
Coverage
A repository whose lifecycle policy exists but could not be parsed into the hasUntaggedImageExpiry trait is reported as unknown coverage instead of a pass. Repositories with no lifecycle policy at all are outside this rule (CLDBRN-AWS-ECR-1 reports them) and count as assessed.
How to remediate
Add a lifecycle policy rule that expires untagged images after a short retention period (e.g., 1 day). In Terraform, add an aws_ecr_lifecycle_policy resource with a rule targeting untagged images:
{
"rules": [
{
"rulePriority": 1,
"description": "Expire untagged images after 1 day",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 1
},
"action": { "type": "expire" }
}
]
}
IaC resources checked
| IaC Tool | Resource Type |
|---|---|
| Terraform | aws_ecr_repository, aws_ecr_lifecycle_policy |
| CloudFormation | AWS::ECR::Repository |
CLDBRN-AWS-ECR-3
ECR Lifecycle Policy Missing Tagged Image Retention Cap
Scan type: Discovery and IaC
Severity: Low
What it checks
Flags ECR repositories whose lifecycle policy does not cap tagged image retention. Without a cap, every tagged image version is kept forever. Discovery fetches the live lifecycle policy from each repository and parses it the same way the IaC scan parses the policy document in your template.
Why it matters
CI/CD pipelines that tag images with build numbers or commit SHAs create a new tagged image per deployment. Without a retention cap, repositories grow unbounded. A service deploying daily accumulates 365 tagged images per year.
What triggers a finding
hasLifecyclePolicy is true AND hasTaggedImageRetentionCap is false. A policy satisfies the check when it contains an expire rule whose tagStatus is tagged or any and whose countType is imageCountMoreThan, sinceImagePushed, sinceImagePulled, or sinceImageTransitioned with a positive countNumber.
Coverage
A repository whose lifecycle policy exists but could not be parsed into the hasTaggedImageRetentionCap trait is reported as unknown coverage instead of a pass. Repositories with no lifecycle policy at all are outside this rule (CLDBRN-AWS-ECR-1 reports them) and count as assessed.
How to remediate
Add a lifecycle policy rule that retains only the N most recent tagged images (a common cap is 10-30). This keeps enough images for rollback while preventing unbounded growth:
{
"rules": [
{
"rulePriority": 1,
"description": "Keep only the last 10 tagged images",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["v"],
"countType": "imageCountMoreThan",
"countNumber": 10
},
"action": { "type": "expire" }
}
]
}
IaC resources checked
| IaC Tool | Resource Type |
|---|---|
| Terraform | aws_ecr_repository, aws_ecr_lifecycle_policy |
| CloudFormation | AWS::ECR::Repository |
See Also
- CLI discover command — scan live ECR repositories
- CLI scan command — scan IaC templates for ECR issues
- SDK Reference — run scans programmatically