AWS KMS Customer Managed Keys Should Not Be Multi-Region
Overview
This check identifies AWS KMS customer managed keys (CMKs) that have the multi-region property enabled. Multi-region keys share key material across AWS regions, which can introduce security and compliance concerns.
Single-region keys keep your encryption material contained within one region, simplifying access control and auditing.
Risk
Multi-region KMS keys create several security concerns:
- Expanded attack surface: Access granted in one region could decrypt data from another region, potentially violating data residency requirements
- Complex access management: Managing consistent key policies and access controls across multiple regions increases the chance of misconfigurations
- Audit complexity: Tracking key usage across regions makes it harder to detect unauthorized access
- Integrity risks: For signing or HMAC keys, compromise in one region could enable signature forgery affecting data integrity across all regions
Remediation Steps
Prerequisites
You need:
- Access to the AWS Console with permissions to manage KMS keys
- Understanding of which services and applications use the affected key
Important: Before replacing a multi-region key, identify all resources that use it. Changing keys requires re-encrypting data or updating service configurations.
AWS Console Method
- Sign in to the AWS Console and go to KMS (Key Management Service)
- Select Customer managed keys in the left navigation
- Look for keys with Multi-Region: Yes in the key details
- For each multi-region key you want to replace:
- Click Create key
- Choose your key type (Symmetric or Asymmetric)
- Leave Multi-Region unchecked (this creates a single-region key)
- Complete the key configuration and create it
- Update your services and applications to use the new single-region key
- Re-encrypt any data that was encrypted with the old multi-region key
- Once all resources are migrated, disable the old multi-region key
- After a waiting period, schedule the old key for deletion
AWS CLI (optional)
List all KMS keys and identify multi-region keys:
# List all customer managed keys
aws kms list-keys --region us-east-1
# Check if a specific key is multi-region
aws kms describe-key \
--key-id <your-key-id> \
--region us-east-1 \
--query 'KeyMetadata.MultiRegion'
Create a new single-region key:
aws kms create-key \
--description "Single-region key for enhanced security" \
--key-usage ENCRYPT_DECRYPT \
--key-spec SYMMETRIC_DEFAULT \
--region us-east-1
Note: By default, create-key creates a single-region key. Multi-region keys require the --multi-region flag, which we omit here.
Create an alias for the new key:
aws kms create-alias \
--alias-name alias/my-single-region-key \
--target-key-id <new-key-id> \
--region us-east-1
Disable the old multi-region key (after migration):
aws kms disable-key \
--key-id <old-multi-region-key-id> \
--region us-east-1
Schedule deletion (after confirming no resources use it):
aws kms schedule-key-deletion \
--key-id <old-multi-region-key-id> \
--pending-window-in-days 30 \
--region us-east-1
CloudFormation (optional)
Use this template to create a single-region KMS key:
AWSTemplateFormatVersion: '2010-09-09'
Description: Single-region KMS key for enhanced security
Parameters:
KeyAlias:
Type: String
Description: Alias for the KMS key
Default: alias/my-single-region-key
Resources:
SingleRegionKMSKey:
Type: AWS::KMS::Key
Properties:
Description: Single-region KMS key for enhanced security and compliance
Enabled: true
EnableKeyRotation: true
KeySpec: SYMMETRIC_DEFAULT
KeyUsage: ENCRYPT_DECRYPT
MultiRegion: false
KeyPolicy:
Version: '2012-10-17'
Id: key-default-policy
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action: 'kms:*'
Resource: '*'
Tags:
- Key: Environment
Value: Production
- Key: MultiRegion
Value: 'false'
KMSKeyAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: !Ref KeyAlias
TargetKeyId: !Ref SingleRegionKMSKey
Outputs:
KeyId:
Description: The ID of the KMS key
Value: !Ref SingleRegionKMSKey
KeyArn:
Description: The ARN of the KMS key
Value: !GetAtt SingleRegionKMSKey.Arn
KeyAlias:
Description: The alias of the KMS key
Value: !Ref KMSKeyAlias
Deploy the stack:
aws cloudformation deploy \
--template-file template.yaml \
--stack-name single-region-kms-key \
--region us-east-1
Terraform (optional)
# KMS Key - Single Region Configuration
variable "key_alias" {
description = "Alias for the KMS key"
type = string
default = "alias/my-single-region-key"
}
variable "description" {
description = "Description for the KMS key"
type = string
default = "Single-region KMS key for enhanced security"
}
variable "deletion_window_in_days" {
description = "Duration in days after which the key is deleted after destruction"
type = number
default = 30
}
variable "enable_key_rotation" {
description = "Enable automatic key rotation"
type = bool
default = true
}
variable "tags" {
description = "Tags to apply to the KMS key"
type = map(string)
default = {}
}
# Single-region KMS key
resource "aws_kms_key" "single_region" {
description = var.description
deletion_window_in_days = var.deletion_window_in_days
enable_key_rotation = var.enable_key_rotation
multi_region = false # Explicitly set to false for single-region
key_usage = "ENCRYPT_DECRYPT"
customer_master_key_spec = "SYMMETRIC_DEFAULT"
tags = merge(
var.tags,
{
"MultiRegion" = "false"
}
)
}
# Create an alias for the key
resource "aws_kms_alias" "single_region" {
name = var.key_alias
target_key_id = aws_kms_key.single_region.key_id
}
output "key_id" {
description = "The ID of the KMS key"
value = aws_kms_key.single_region.key_id
}
output "key_arn" {
description = "The ARN of the KMS key"
value = aws_kms_key.single_region.arn
}
output "alias_arn" {
description = "The ARN of the KMS key alias"
value = aws_kms_alias.single_region.arn
}
Apply the configuration:
terraform init
terraform plan
terraform apply
Verification
After remediation, verify that your KMS keys are single-region:
- In the AWS Console, go to KMS > Customer managed keys
- Click on each key and confirm Multi-Region shows No
CLI Verification
# List all keys and check their multi-region status
for key_id in $(aws kms list-keys --region us-east-1 --query 'Keys[*].KeyId' --output text); do
multi_region=$(aws kms describe-key --key-id "$key_id" --region us-east-1 --query 'KeyMetadata.MultiRegion' --output text)
echo "Key: $key_id - Multi-Region: $multi_region"
done
All keys should show Multi-Region: False.
Run the Prowler check:
prowler aws --checks kms_cmk_not_multi_region --region us-east-1
Additional Resources
Notes
- Data migration required: Replacing a multi-region key means re-encrypting all data that was protected by that key. Plan this carefully for large datasets.
- Service dependencies: Many AWS services (S3, EBS, RDS, etc.) can use KMS keys. Audit all services before disabling the old key.
- Key deletion is irreversible: Once a key is deleted, data encrypted with it cannot be recovered. Use the 7-30 day waiting period wisely.
- Legitimate use cases exist: Some organizations genuinely need multi-region keys for disaster recovery or global applications. Document exceptions with proper justification and enhanced monitoring.
- Replica keys: If you have replica keys in other regions, they will need to be deleted separately before the primary multi-region key can be fully retired.