MSK Cluster encryption at rest or in transit is disabled

ID

msk_encryption_disabled

Severity

high

Vendor

AWS

Resource

MSK Cluster

Description

Amazon Managed Streaming for Apache Kafka (Amazon MSK) is a fully managed service that enables you to build and run applications that use Apache Kafka to process streaming data

Amazon MSK clusters could be configured for encryption at rest and/or in transit.

When you create an MSK cluster, you can specify the key management service (KMS) for Amazon MSK to use to encrypt your data at rest. If you don’t specify a key management service, Amazon MSK creates an AWS managed KMS for you and uses it on your behalf.

In addition, in transit traffic between cluster nodes is encrypted by default (when the encryption_info block is specified), but it could be disabled in the configuration.

We recommend using encryption in transit and at rest to secure your managed Kafka queue.

For further information: Amazon MSK encryption and aws_msk_cluster resource.

Examples

CloudFormation

{
  "Resources": {
    "Cluster": { (1)
      "Type": "AWS::MSK::Cluster",
      "Properties": {
        "ClusterName": "ClusterWithAllProperties",
        "KafkaVersion": "2.2.1",
        "NumberOfBrokerNodes": 3,
        "EnhancedMonitoring": "PER_BROKER"
      }
    }
  }
}
1 Missing EncryptionInfo block means no EncryptionAtRest nor EncryptionInTransit.
Resources:
  Cluster: (1)
    Type: 'AWS::MSK::Cluster'
    Properties:
      ClusterName: ClusterWithAllProperties
      KafkaVersion: 2.2.1
      NumberOfBrokerNodes: 3
      EnhancedMonitoring: PER_BROKER
1 Missing EncryptionInfo block means no EncryptionAtRest nor EncryptionInTransit.

Terraform

// no encryption at rest or in transit
resource "aws_msk_cluster" "msk_cluster" { (1)
  cluster_name           = "example"
  kafka_version          = "3.2.0"
  number_of_broker_nodes = 3

  broker_node_group_info {
    client_subnets  = []
    ebs_volume_size = 0
    instance_type   = ""
    security_groups = []
  }
}
1 No encryption_info means no encryption at rest or in transit.

Specifying an insecure configuration for encryption in transit will be also reported:

resource "aws_msk_cluster" "msk_cluster" {
  cluster_name           = "example"
  // ...

  encryption_info {
    encryption_at_rest_kms_key_arn = aws_kms_key.kms.arn

    encryption_in_transit { (1)
      client_broker = "PLAINTEXT"
      in_cluster = false
    }
  }

  // ...
}
1 Flaw, encryption in transit is disabled

Mitigation / Fix

Buildtime

CloudFormation

{
  "Resources": {
    "Cluster": {
      "Type": "AWS::MSK::Cluster",
      "Properties": {
        "ClusterName": "ClusterWithAllProperties",
        "KafkaVersion": "2.2.1",
        "NumberOfBrokerNodes": 3,
        "EnhancedMonitoring": "PER_BROKER",
        "EncryptionInfo": { (1)
          "EncryptionAtRest": {
            "DataVolumeKMSKeyId": "ReplaceWithKmsKeyArn"
          },
          "EncryptionInTransit": {
            "ClientBroker": "TLS",
            "InCluster": true
          }
        }
      }
    }
  }
}
1 EncryptionInfo block with EncryptionAtRest and EncryptionInTransit.
Resources:
  Cluster:
    Type: 'AWS::MSK::Cluster'
    Properties:
      ClusterName: ClusterWithAllProperties
      KafkaVersion: 2.2.1
      NumberOfBrokerNodes: 3
      EnhancedMonitoring: PER_BROKER
      EncryptionInfo: (1)
        EncryptionAtRest:
          DataVolumeKMSKeyId: ReplaceWithKmsKeyArn
        EncryptionInTransit:
          ClientBroker: TLS
          InCluster: true
1 EncryptionInfo block with EncryptionAtRest and EncryptionInTransit.

Terraform

resource "aws_msk_cluster" "msk_cluster" {
  cluster_name           = "example"
  // ...

  // FIXED, default encryption in transit is safe
  encryption_info {
    // This is optional, AWS managed KMS if not given
    encryption_at_rest_kms_key_arn = aws_kms_key.kms.arn
  }

  // ...
}

You may also make explicit encryption in transit:

resource "aws_msk_cluster" "msk_cluster" {
  cluster_name           = "example"
  // ...

  // FIXED, both encryption at rest and in transit
  encryption_info {
    // This is optional, AWS managed KMS if not given
    encryption_at_rest_kms_key_arn = aws_kms_key.kms.arn

    encryption_in_transit {
      client_broker = "PLAINTEXT"
      in_cluster = false
    }
  }

  // ...
}