Proactively Mitigating a Medium-Severity Prowler Issue: Enabling KMS Encryption for CloudWatch Logs (DevSecOps)
Introduction
When running Prowler — a popular open-source tool that checks AWS environments against best practices — you may encounter a Medium-severity finding indicating that one or more of your CloudWatch Log Groups are not encrypted with a Customer Managed Key (CMK). While AWS provides default encryption for some services, enforcing explicit KMS encryption gives you tighter control over your data, meets compliance requirements, and aligns with zero-trust security principles.
In this blog post, we’ll explore:
- The Prowler Finding: Why it appears and what it means.
- Why Encryption Matters: The security implications of using a CMK.
- A CloudFormation-based Solution: How to explicitly define and encrypt your CloudWatch Log Group using your own KMS key.
- (We’ll cover retention period configuration in a follow-up post.)
Let’s dive in!
The Prowler Issue: CloudWatch Log Groups Not Encrypted with KMS
A common Prowler check for CloudWatch logs is something along the lines of:
“Check: CloudWatch Log Groups are encrypted with KMS.”
Finding: FAIL
Severity: Medium
Reason: KMS encryption is not enabled on the log group.
Why You See This Warning
By default, CloudWatch Logs uses an AWS-managed key to encrypt data at rest. However, many security frameworks and internal policies require customer-managed KMS keys for granular control over key rotation, access policies, and cross-account usage. When Prowler detects that a log group does not specify a KmsKeyId
, it flags the resource as non-compliant.
Potential Risks
- Less Granular Key Management: If you rely solely on AWS-managed keys, you cannot specify when or how the key rotates, or set up custom key policies.
- Compliance Gaps: Some regulations (e.g., PCI DSS, HIPAA) may demand using a customer-managed key with strict auditing.
- Visibility and Ownership: With a CMK, you decide exactly who can use the key, which services can decrypt your logs, and how frequently the key rotates.
Why Encryption with a Customer Managed Key (CMK) Matters
- Fine-Grained Access Control
You can tailor the key policy to allow only specific IAM principals or services to encrypt/decrypt the logs. - Cross-Account Trust
If you ever need to share logs across multiple AWS accounts, a CMK can be configured with explicit cross-account grants. - Compliance & Auditing
Many standards require an auditable log of all key usage. With a CMK, you get detailed CloudTrail logs on every encryption/decryption action. - Security Best Practice
Even if not required by compliance, employing a CMK is considered a strong security practice because it minimizes the blast radius of potential incidents and ensures you, not AWS, manage the key lifecycle.
The CloudFormation-Based Solution
In many AWS environments, CloudWatch Log Groups are created automatically by Lambda functions or other services. To explicitly enable CMK-based encryption, you’ll want to define the log group in CloudFormation and specify your KMS key.
Important: If you rely on auto-created log groups (for example, from a new Lambda function), they are typically not associated with your custom KMS key by default. You must create or adopt that log group in CloudFormation with the
KmsKeyId
property.
Step 1: Identify a KMS Key
- Create a CMK in your desired region via the AWS console, or confirm an existing key you want to use.
- Validate the key policy allows the CloudWatch Logs service principal (
logs.<region>.amazonaws.com
) to use it. If not, add a statement similar to:
{
"Sid": "AllowCWLogsServicePrincipal",
"Effect": "Allow",
"Principal": { "Service": "logs.us-east-1.amazonaws.com" },
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:CreateGrant",
"kms:DescribeKey"
],
"Resource": "*"
}
3. Record the KMS key ARN, for example:
arn:aws:kms:us-east-1:123456789012:key/a1b2c3d4-5678-90ab-cdef-EXAMPLEKEY
Step 2: Define the Log Group in CloudFormation
Below is a minimalist example snippet showing one way to define a CloudWatch Log Group named /aws/lambda/MyEncryptedFunction
with your custom KMS key:
AWSTemplateFormatVersion: '2010-09-09'
Description: Enable KMS encryption for a CloudWatch Log Group
Resources:
MyEncryptedFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: "MyEncryptedFunction"
Handler: index.handler
Runtime: python3.9
Role: !GetAtt MyEncryptedLambdaRole.Arn
Code:
ZipFile: |
def lambda_handler(event, context):
print("Hello from an encrypted log group!")
return "Success"
MyEncryptedLambdaLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: "/aws/lambda/MyEncryptedFunction"
KmsKeyId: "arn:aws:kms:us-east-1:123456789012:key/a1b2c3d4-5678-90ab-cdef-EXAMPLEKEY"
# RetentionInDays is optional; see next post for best practices on retention
DeletionPolicy: Retain
Key Points
LogGroupName
must match the function name if you want logs to go here instead of an automatically created group.KmsKeyId
points to your CMK ARN.DeletionPolicy: Retain
ensures logs aren’t wiped out if the stack is deleted—useful for auditing and historical data.
Step 3: Deploy and Verify
- Deploy this CloudFormation stack (e.g.,
aws cloudformation deploy --template-file mytemplate.yaml --stack-name MyEncryptedLogsStack --capabilities CAPABILITY_IAM
). - Invoke the Lambda function to generate logs.
- Check the CloudWatch console → Log groups →
/aws/lambda/MyEncryptedFunction
. - Details: Confirm KMS Key ID is set to your custom ARN, not a dash. That indicates encryption is enabled.
Conclusion and Next Steps
By defining your CloudWatch Log Groups in CloudFormation and specifying a KMS key, you resolve Prowler’s medium-severity finding about unencrypted logs — and you gain better security posture and compliance alignment.
Upcoming Post: Retention Configuration
In our next blog post, we’ll explore how to set the retention period for your logs and why it matters for both cost and compliance. Stay tuned!
Final Thoughts
- Remediate Medium Prowler Findings: Even if it’s “only” medium severity, unencrypted logs can pose serious risks in certain compliance or threat scenarios.
- CMK Control: Using a customer-managed key puts you firmly in the driver’s seat for encryption and decryption policies.
- Keep Testing: After updating your infrastructure, re-run Prowler to ensure the finding no longer appears.
Adopting this approach will strengthen your AWS environment and help maintain a robust security posture. If you have any questions or feedback, feel free to reach out or comment below.
Happy encrypting!
References
Here are a few useful AWS references for further reading:
- Encrypting CloudWatch Logs at Rest Using AWS KMS
https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/encrypt-log-data-kms.html - Using AWS KMS with CloudWatch Logs
https://docs.aws.amazon.com/kms/latest/developerguide/services-cloudwatchlogs.html - Key Policies and Cross-Service Confused Deputy Prevention
https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html
For more info please connect & Follow me:
Github: https://github.com/manikcloud
LinkedIn: https://www.linkedin.com/in/vkmanik/
Email: varunmanik1@gmail.com
Facebook: https://www.facebook.com/cloudvirtualization/
YouTube: https://bit.ly/32fknRN
Twitter: https://twitter.com/varunkmanik