AnalysisType: policy
Filename: aws_cloudwatch_loggroup_data_retention.py
PolicyID: "AWS.CloudWatchLogs.DataRetention1Year"
DisplayName: "AWS CloudWatch Logs Data Retention"
Enabled: true
ResourceTypes:
- AWS.CloudWatch.LogGroup
Tags:
- AWS
- Panther
Severity: Low
Description: >
By default, logs are kept indefinitely and never expire. You can adjust the retention policy
for each log group, keeping the indefinite retention, or choosing a specific retention period.
Runbook: |
Change the CloudWatch log group retention from the CloudWatch Logs web console,
SDK, CloudFormation, or any other supported method.
Reference: https://docs.aws.amazon.com/cli/latest/reference/logs/put-retention-policy.html
Tests:
- Name: Unlimited Log Retention
ExpectedResult: true
Resource:
{
"ARN": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"AccountId": "123456789012",
"Arn": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"CreationTime": 1234567890123,
"KmsKeyId": "arn:aws:kms:us-west-2:123456789012:key/12345678-1234-1234-1234-123456789012",
"LogGroupName": "LogGroup-2",
"MetricFilterCount": 0,
"Name": "LogGroup-2",
"Region": "us-west-2",
"ResourceID": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"ResourceType": "AWS.CloudWatch.LogGroup",
"RetentionInDays": null,
"StoredBytes": 0,
"Tags": { "Key1Name": "Value1" },
"TimeCreated": "2009-02-13T15:31:30.000-08:00",
}
- Name: Logs Retained 1 Year
ExpectedResult: true
Resource:
{
"ARN": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"AccountId": "123456789012",
"Arn": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"CreationTime": 1234567890123,
"KmsKeyId": null,
"LogGroupName": "LogGroup-2",
"MetricFilterCount": 0,
"Name": "LogGroup-2",
"Region": "us-west-2",
"ResourceID": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"ResourceType": "AWS.CloudWatch.LogGroup",
"RetentionInDays": 365,
"StoredBytes": 0,
"Tags": { "Key1Name": "Value1" },
"TimeCreated": "2009-02-13T15:31:30.000-08:00",
}
- Name: Logs Retained 2 Years
ExpectedResult: true
Resource:
{
"ARN": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"AccountId": "123456789012",
"Arn": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"CreationTime": 1234567890123,
"KmsKeyId": null,
"LogGroupName": "LogGroup-2",
"MetricFilterCount": 0,
"Name": "LogGroup-2",
"Region": "us-west-2",
"ResourceID": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"ResourceType": "AWS.CloudWatch.LogGroup",
"RetentionInDays": 730,
"StoredBytes": 0,
"Tags": { "Key1Name": "Value1" },
"TimeCreated": "2009-02-13T15:31:30.000-08:00",
}
- Name: Logs Retained 1 Week
ExpectedResult: false
Resource:
{
"ARN": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"AccountId": "123456789012",
"Arn": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"CreationTime": 1234567890123,
"KmsKeyId": null,
"LogGroupName": "LogGroup-2",
"MetricFilterCount": 0,
"Name": "LogGroup-2",
"Region": "us-west-2",
"ResourceID": "arn:aws:logs:us-west-2:1234456789012:log-group:LogGroup-2",
"ResourceType": "AWS.CloudWatch.LogGroup",
"RetentionInDays": 7,
"StoredBytes": 0,
"Tags": { "Key1Name": "Value1" },
"TimeCreated": "2009-02-13T15:31:30.000-08:00",
}
# ------ paired body: aws_cloudwatch_loggroup_data_retention.py ------
MIN_DAYS_TO_RETAIN_LOGS = 365
def policy(resource):
retention_in_days = resource["RetentionInDays"]
# If retention is None, logs will never expire.
return retention_in_days is None or retention_in_days >= MIN_DAYS_TO_RETAIN_LOGS