Kinesis streams should be encrypted with CMK
AWS-managed keys for Kinesis (alias/aws/kinesis) encrypt data at rest but give you zero control over key policy, key deletion scheduling, or cross-account access grants. A customer-managed CMK lets you restrict which IAM principals can decrypt stream data, audit every Decrypt and GenerateDataKey call in CloudTrail, and revoke access instantly by modifying the key policy or disabling the key.
Without CMK encryption, an attacker who compromises a broadly scoped IAM role can read stream records with no additional barrier. CMK-based encryption adds a second authorization gate: even with kinesis:GetRecords permission, the caller must also hold kms:Decrypt on the specific key.
Retrofit consideration
Enabling or changing encryption on a running Kinesis stream moves it into an UPDATING state. Producers and consumers may hit transient errors during that window. Test in a non-production environment first and give downstream consumers a heads-up before applying to anything in active use.
Implementation
Choose the approach that matches how you manage Terraform.
Use AWS provider resources directly. See docs for the resources involved: aws_kinesis_stream.
resource "aws_kinesis_stream" "this" {
encryption_type = "KMS"
name = "pofix-abc123"
retention_period = 168
shard_count = 1
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}
What this control checks
The aws_kinesis_stream resource must have encryption_type set to "KMS" and kms_key_id set to the ARN or alias of a customer-managed KMS key (aws_kms_key resource you control). It fails if encryption_type is "NONE" or omitted, or if kms_key_id resolves to the AWS-managed key (alias/aws/kinesis). The referenced aws_kms_key should have is_enabled = true and a key policy granting the Kinesis service principal kms:GenerateDataKey and kms:Decrypt.
Example passing configuration: encryption_type = "KMS" and kms_key_id = aws_kms_key.kinesis.arn on the aws_kinesis_stream resource.
Common pitfalls
AWS-managed key does not satisfy this control
Setting
encryption_type = "KMS"without specifyingkms_key_id, or pointing it atalias/aws/kinesis, hands key control back to AWS. The data is encrypted, but this control fails because you have no access to the key policy. Always supply an explicitaws_kms_keyresource ARN inkms_key_id.Missing KMS key policy grants
Even with the correct
kms_key_id, if the key policy does not grantkms:GenerateDataKey,kms:Decrypt, andkms:DescribeKeyto the Kinesis service principal or the producing and consuming IAM roles, writes and reads will returnAccessDeniedException. Get this wrong and the stream fails silently from an application perspective until you trace the error back to KMS.Key deletion disables the stream
Schedule the CMK for deletion or disable it via
aws kms disable-keyand everyPutRecordandGetRecordscall fails withKMSDisabledException. Setdeletion_window_in_daysto an appropriate value (7-30 days) and monitor for that error in CloudWatch before it becomes an incident.Cross-region replication needs region-local keys
A CMK in one region cannot decrypt data in another. If you replicate Kinesis data cross-region, provision a separate CMK in each destination region and wire up the key policies accordingly. Reusing the source region's key ARN across regions will not work.
Audit evidence
Config rule evaluation results for kinesis-stream-encrypted (with a custom parameter requiring CMK) should show all streams as COMPLIANT. Back that up with aws kinesis describe-stream --stream-name <name> output showing EncryptionType: KMS and a KeyId that resolves to a customer-managed key, confirmed by aws kms describe-key --key-id <id> returning KeyManager: CUSTOMER.
CloudTrail logs showing kms:GenerateDataKey and kms:Decrypt calls referencing the stream's key ARN demonstrate ongoing enforcement. Prowler or Steampipe scan reports flagging streams without CMK encryption round out the continuous monitoring picture.
Framework-specific interpretation
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
kinesis_stream_encrypted_with_kms_cmkAWS Config Managed Rule:
KINESIS_STREAM_ENCRYPTEDCheckov Check:
CKV_AWS_185Powerpipe Control:
aws_compliance.control.kinesis_stream_encrypted_with_kms_cmkProwler Check:
kinesis_stream_encrypted_at_restAWS Security Hub Control:
Kinesis.1KICS Queries:
5c6dd5e7-1fe0-4cae-8f81-4c122717cef3,862fe4bf-3eec-4767-a517-40f378886b88Trivy Check:
AWS-0064
Last reviewed: 2026-03-09