Kinesis firehose delivery streams should have server side encryption enabled
Firehose delivery streams often carry high-volume event data destined for S3, Redshift, OpenSearch, or HTTP endpoints. Without SSE, data buffered within the Firehose service sits unencrypted, leaving it readable if the underlying storage layer is ever compromised. Encryption at the stream level closes this gap regardless of whether the downstream destination has its own at-rest encryption.
SSE also satisfies the at-rest encryption baseline for compliance programs that cover data protection with a single configuration toggle. It's one of the lowest-effort controls in a streaming pipeline.
Retrofit consideration
Enabling SSE on an existing delivery stream causes no downtime, but if switching to CUSTOMER_MANAGED_CMK, verify that the Firehose service role has kms:GenerateDataKey and kms:Decrypt permissions on the specified KMS key.
Implementation
Choose the approach that matches how you manage Terraform.
Use AWS provider resources directly. See docs for the resources involved: aws_kinesis_firehose_delivery_stream.
resource "aws_kinesis_firehose_delivery_stream" "this" {
destination = "extended_s3"
extended_s3_configuration {
bucket_arn = "arn:aws:s3:::example-bucket-abc123"
role_arn = "arn:aws:iam::123456789012:role/example-role"
}
name = "pofix-abc123"
server_side_encryption {
enabled = true
}
}
What this control checks
The control validates the server_side_encryption block on aws_kinesis_firehose_delivery_stream. To pass, enabled must be true within that block. key_type accepts either AWS_OWNED_CMK (the default, no additional KMS config needed) or CUSTOMER_MANAGED_CMK (requires a key_arn pointing to a valid KMS key ARN). It fails when the server_side_encryption block is omitted entirely or when enabled = false. For CUSTOMER_MANAGED_CMK, the referenced key must exist and the Firehose IAM role must hold kms:GenerateDataKey, kms:Decrypt, and kms:Encrypt on it.
Common pitfalls
SSE does not encrypt data in transit to destinations
The
server_side_encryptionblock only covers data at rest within the Firehose buffer. Data delivered to S3, Redshift, or HTTP endpoints relies on separate TLS and destination-level encryption settings. Don't assume SSE alone covers end-to-end encryption.CUSTOMER_MANAGED_CMK requires explicit KMS permissions
Get the IAM permissions wrong and the stream breaks silently at delivery time. Setting
key_type = "CUSTOMER_MANAGED_CMK"without granting the Firehose delivery rolekms:GenerateDataKey,kms:Decrypt, andkms:Encrypton the specifiedkey_arncauses delivery failures. The stream may appear encrypted in the console but will stop processing records.Encryption status can be toggled outside Terraform
The
StopDeliveryStreamEncryptionAPI call can disable SSE without changing Terraform state. If drift detection is not running, the stream may silently revert to unencrypted. Use AWS Config continuous evaluation to catch this.Omitting the block defaults to no encryption
aws_kinesis_firehose_delivery_streamdoes not enable SSE by default. Unlike some AWS resources that encrypt automatically, if theserver_side_encryptionblock is missing entirely, the stream is created unencrypted with no warning.
Audit evidence
An auditor expects to see the AWS Config rule kinesis-firehose-delivery-stream-encrypted returning compliant evaluations for all in-scope delivery streams. Supporting that, aws firehose describe-delivery-stream output should show DeliveryStreamEncryptionConfiguration.Status as ENABLED and KeyType matching organizational policy (e.g., CUSTOMER_MANAGED_CMK for stricter requirements). Console screenshots or CLI exports showing per-stream encryption status work as point-in-time evidence. CloudTrail events for StartDeliveryStreamEncryption establish when encryption was activated on each stream.
Framework-specific interpretation
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
kinesis_firehose_delivery_stream_server_side_encryption_enabledAWS Config Managed Rule:
KINESIS_FIREHOSE_DELIVERY_STREAM_ENCRYPTEDCheckov Check:
CKV_AWS_240Powerpipe Control:
aws_compliance.control.kinesis_firehose_delivery_stream_server_side_encryption_enabledProwler Check:
firehose_stream_encrypted_at_restAWS Security Hub Control:
DataFirehose.1KICS Query:
5c6dd5e7-1fe0-4cae-8f81-4c122717cef3
Last reviewed: 2026-03-09