Skip to content

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_encryption block 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 role kms:GenerateDataKey, kms:Decrypt, and kms:Encrypt on the specified key_arn causes delivery failures. The stream may appear encrypted in the console but will stop processing records.

  • Encryption status can be toggled outside Terraform

    The StopDeliveryStreamEncryption API 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_stream does not enable SSE by default. Unlike some AWS resources that encrypt automatically, if the server_side_encryption block 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

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_enabled

  • AWS Config Managed Rule: KINESIS_FIREHOSE_DELIVERY_STREAM_ENCRYPTED

  • Checkov Check: CKV_AWS_240

  • Powerpipe Control: aws_compliance.control.kinesis_firehose_delivery_stream_server_side_encryption_enabled

  • Prowler Check: firehose_stream_encrypted_at_rest

  • AWS Security Hub Control: DataFirehose.1

  • KICS Query: 5c6dd5e7-1fe0-4cae-8f81-4c122717cef3

Last reviewed: 2026-03-09