Back to Checks
aws

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 Cloud
Run
prowler aws --checks awslambda_function_env_vars_not_encrypted_with_cmk

Recommendation

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