Skip to main content

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

  1. Sign in to the AWS Console and go to KMS (Key Management Service)
  2. Select Customer managed keys in the left navigation
  3. Look for keys with Multi-Region: Yes in the key details
  4. 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
  5. Update your services and applications to use the new single-region key
  6. Re-encrypt any data that was encrypted with the old multi-region key
  7. Once all resources are migrated, disable the old multi-region key
  8. 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:

  1. In the AWS Console, go to KMS > Customer managed keys
  2. 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.