Back to Checks
Lambda function environment variables are encrypted with a customer-managed KMS key
awslambda_function_env_vars_not_encrypted_with_cmk
Service: awslambdaSeverity: medium
OfficialBuilt-inVerified
Categories:encryption
Resource Type:AwsLambdaFunction
AWS Lambda function environment variables are encrypted at rest using a customer-managed KMS key (CMK) rather than the default AWS-managed Lambda service key.
The presence of a KMSKeyArn on the function configuration indicates CMK-based encryption is active.
Risk
Without a CMK, environment variables are encrypted with an AWS-managed key, removing customer control over rotation, auditing, and revocation.
If variables contain secrets or connection strings, loss of key control weakens confidentiality and can fail compliance requirements (PCI-DSS, HIPAA, FedRAMP) that mandate customer-controlled encryption.
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks awslambda_function_env_vars_not_encrypted_with_cmkRecommendation
Encrypt Lambda environment variables with a customer-managed KMS key to maintain full control over key lifecycle and access.
- Create a dedicated KMS key per application or per function for blast-radius isolation
- Enable automatic key rotation (
EnableKeyRotation: true) - Grant only the Lambda execution role decrypt access via a key policy condition on
kms:ViaService - Prefer AWS Secrets Manager or SSM Parameter Store (SecureString) for secrets — environment variables should hold non-secret configuration only
Remediation
CLI
aws lambda update-function-configuration --function-name <function-name> --kms-key-arn <cmk-arn>Terraform
resource "aws_kms_key" "lambda_env" {
description = "Lambda env var encryption key"
enable_key_rotation = true
deletion_window_in_days = 30
}
resource "aws_lambda_function" "example" {
function_name = "<example_resource_name>"
role = "<example_role_arn>"
handler = "index.handler"
runtime = "python3.12"
filename = "<example_package.zip>"
kms_key_arn = aws_kms_key.lambda_env.arn
environment {
variables = {
MY_CONFIG = "<value>"
}
}
}NativeIaC
AWSTemplateFormatVersion: '2010-09-09'
Resources:
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: <example_resource_name>
Role: <example_role_arn>
Handler: index.handler
Runtime: python3.12
Code:
S3Bucket: <example_code_bucket>
S3Key: <example_code_key>
KmsKeyArn: <cmk-arn>
Environment:
Variables:
MY_CONFIG: <value>Other
1Create or identify a KMS CMK in the same region as the function
2Grant the Lambda execution role `kms:Decrypt` and `kms:GenerateDataKey` on the key
3In the Lambda console go to Configuration > Environment variables > Edit
4Under Encryption configuration, select your CMK
5Save — Lambda re-encrypts all environment variables with the chosen key
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.awslambda.awslambda_client import awslambda_client
class awslambda_function_env_vars_not_encrypted_with_cmk(Check):
def execute(self):
findings = []
for function in awslambda_client.functions.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=function)
if not function.environment:
report.status = "PASS"
report.status_extended = (
f"Lambda function {function.name} has no environment variables."
)
elif function.kms_key_arn:
report.status = "PASS"
report.status_extended = (
f"Lambda function {function.name} environment variables are "
f"encrypted with KMS key {function.kms_key_arn}."
)
else:
report.status = "FAIL"
report.status_extended = (
f"Lambda function {function.name} has environment variables "
f"but they are not encrypted with a customer-managed KMS key."
)
findings.append(report)
return findings