Kafka cluster has encryption in transit enabled
Amazon MSK clusters are evaluated for encryption in transit on both paths: clientbroker set to TLS only and inter-broker encryption enabled. Serverless clusters provide this by default.
The finding highlights clusters where client-broker traffic isn't TLS-only or inter-broker encryption is turned off.
Risk
Unencrypted or mixed (TLS_PLAINTEXT/PLAINTEXT) traffic enables interception of records, credentials, and metadata, supporting MITM, replay, and message tampering.
Plaintext inter-broker links expose replication data within the VPC, enabling lateral movement and topic poisoning, degrading data confidentiality and integrity.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks kafka_cluster_in_transit_encryption_enabledRecommendation
Enforce end-to-end transport protection:
- Require
client_broker=TLSfor all clients - Enable
in_cluster=truefor broker-to-broker links
Apply defense in depth: restrict network paths, prefer private connectivity, and use strong client authentication with least privilege authorization to limit blast radius.
Remediation
Terraform
# Terraform: MSK cluster with encryption in transit enforced
resource "aws_msk_cluster" "<example_resource_name>" {
cluster_name = "<example_resource_name>"
kafka_version = "<VERSION>"
number_of_broker_nodes = 3
broker_node_group_info {
instance_type = "kafka.m5.large"
client_subnets = [
"subnet-<example_resource_id>",
"subnet-<example_resource_id>",
]
}
encryption_info {
encryption_in_transit {
client_broker = "TLS" # Critical: forces client-to-broker TLS only
in_cluster = true # Critical: enables inter-broker encryption
}
}
}NativeIaC
# CloudFormation: MSK cluster with encryption in transit enforced
Resources:
<example_resource_name>:
Type: AWS::MSK::Cluster
Properties:
ClusterName: <example_resource_name>
KafkaVersion: <VERSION>
NumberOfBrokerNodes: 3
BrokerNodeGroupInfo:
ClientSubnets:
- <example_resource_id>
- <example_resource_id>
InstanceType: kafka.m5.large
EncryptionInfo:
EncryptionInTransit:
ClientBroker: TLS # Critical: forces client-to-broker TLS only
InCluster: true # Critical: enables inter-broker encryptionOther
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.kafka.kafka_client import kafka_client
class kafka_cluster_in_transit_encryption_enabled(Check):
def execute(self):
findings = []
for cluster in kafka_client.clusters.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=cluster)
report.status = "FAIL"
report.status_extended = f"Kafka cluster '{cluster.name}' does not have encryption in transit enabled."
# Serverless clusters always have encryption in transit enabled by default
if cluster.kafka_version == "SERVERLESS":
report.status = "PASS"
report.status_extended = f"Kafka cluster '{cluster.name}' is serverless and always has encryption in transit enabled by default."
# For provisioned clusters, check the encryption configuration
elif (
cluster.encryption_in_transit.client_broker == "TLS"
and cluster.encryption_in_transit.in_cluster
):
report.status = "PASS"
report.status_extended = (
f"Kafka cluster '{cluster.name}' has encryption in transit enabled."
)
findings.append(report)
return findings