AWS Backup Recovery Point Encryption
Overview
This check verifies that AWS Backup recovery points are encrypted at rest. Recovery points are the actual backup copies of your data stored in backup vaults. Even if your source resources (like EC2 volumes or RDS databases) are encrypted, the recovery points themselves need vault-level encryption to be protected.
Risk
Unencrypted recovery points create several security vulnerabilities:
- Data theft: If someone gains access to your backup vault, they can read or copy unencrypted backups and analyze the data offline
- Data tampering: Attackers could modify snapshots or restore points without detection
- Recovery disruption: Compromised backups can lead to corrupted restores, affecting your disaster recovery capability
Remediation Steps
Prerequisites
You need:
- AWS Console access with permissions to manage Backup vaults and KMS keys
- Permission to create or modify backup plans
Required IAM permissions
Your IAM user or role needs these permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"backup:CreateBackupVault",
"backup:DescribeBackupVault",
"backup:ListBackupVaults",
"backup:StartCopyJob",
"backup:UpdateBackupPlan",
"kms:CreateKey",
"kms:CreateAlias",
"kms:DescribeKey",
"kms:ListAliases"
],
"Resource": "*"
}
]
}
AWS Console Method
Step 1: Create an encrypted backup vault
- Open the AWS Backup console
- In the left navigation, click Backup vaults
- Click Create backup vault
- Enter a name for your vault (e.g.,
encrypted-backup-vault) - Under Encryption key, choose one of:
- AWS managed key (aws/backup) - simplest option, AWS manages the key
- Choose a KMS key - select an existing customer-managed key for more control
- Create a KMS key - create a new customer-managed key
- Click Create backup vault
Step 2: Update your backup plans to use the encrypted vault
- In the left navigation, click Backup plans
- Select your existing backup plan
- Click Edit on the backup rule
- Under Backup vault, select your new encrypted vault
- Click Save
Step 3: Migrate existing unencrypted recovery points (if any)
For existing recovery points in unencrypted vaults, you need to copy them to your new encrypted vault:
- Go to Backup vaults and select the unencrypted vault
- Find the recovery point you want to migrate
- Select the recovery point and click Actions > Copy
- Choose your encrypted vault as the destination
- After the copy completes, you can delete the original unencrypted recovery point
AWS CLI (optional)
Create an encrypted backup vault with AWS-managed key:
aws backup create-backup-vault \
--backup-vault-name encrypted-backup-vault \
--region us-east-1
Create an encrypted backup vault with a customer-managed KMS key:
# First, create a KMS key (or use an existing one)
KEY_ARN=$(aws kms create-key \
--description "Key for AWS Backup vault encryption" \
--region us-east-1 \
--query 'KeyMetadata.Arn' \
--output text)
# Create the vault with the key
aws backup create-backup-vault \
--backup-vault-name encrypted-backup-vault \
--encryption-key-arn "$KEY_ARN" \
--region us-east-1
Copy an existing recovery point to an encrypted vault:
aws backup start-copy-job \
--recovery-point-arn "arn:aws:backup:us-east-1:123456789012:recovery-point:abcd1234-ab12-cd34-ef56-abcdef123456" \
--source-backup-vault-name unencrypted-vault \
--destination-backup-vault-arn "arn:aws:backup:us-east-1:123456789012:backup-vault:encrypted-backup-vault" \
--iam-role-arn "arn:aws:iam::123456789012:role/AWSBackupDefaultServiceRole" \
--region us-east-1
Replace the placeholder values:
123456789012with your AWS account IDabcd1234-ab12-cd34-ef56-abcdef123456with your recovery point IDunencrypted-vaultwith your source vault nameAWSBackupDefaultServiceRolewith your backup service role name
CloudFormation (optional)
This template creates an encrypted backup vault with an optional customer-managed KMS key:
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS Backup Vault with KMS Encryption
Parameters:
VaultName:
Type: String
Description: Name of the backup vault
Default: encrypted-backup-vault
UseCustomerManagedKey:
Type: String
AllowedValues:
- 'true'
- 'false'
Default: 'false'
Description: Use a customer-managed KMS key instead of AWS managed key
Conditions:
CreateCustomKey: !Equals [!Ref UseCustomerManagedKey, 'true']
Resources:
BackupVaultKey:
Type: AWS::KMS::Key
Condition: CreateCustomKey
Properties:
Description: KMS key for AWS Backup vault encryption
EnableKeyRotation: true
KeyPolicy:
Version: '2012-10-17'
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action: 'kms:*'
Resource: '*'
- Sid: Allow Backup Service
Effect: Allow
Principal:
Service: backup.amazonaws.com
Action:
- 'kms:Encrypt'
- 'kms:Decrypt'
- 'kms:ReEncrypt*'
- 'kms:GenerateDataKey*'
- 'kms:DescribeKey'
Resource: '*'
Tags:
- Key: Purpose
Value: BackupVaultEncryption
BackupVaultKeyAlias:
Type: AWS::KMS::Alias
Condition: CreateCustomKey
Properties:
AliasName: !Sub 'alias/${VaultName}-key'
TargetKeyId: !Ref BackupVaultKey
EncryptedBackupVault:
Type: AWS::Backup::BackupVault
Properties:
BackupVaultName: !Ref VaultName
EncryptionKeyArn: !If
- CreateCustomKey
- !GetAtt BackupVaultKey.Arn
- !Sub 'arn:aws:kms:${AWS::Region}:${AWS::AccountId}:alias/aws/backup'
Outputs:
BackupVaultArn:
Description: ARN of the encrypted backup vault
Value: !GetAtt EncryptedBackupVault.BackupVaultArn
BackupVaultName:
Description: Name of the encrypted backup vault
Value: !Ref EncryptedBackupVault
KmsKeyArn:
Condition: CreateCustomKey
Description: ARN of the customer-managed KMS key
Value: !GetAtt BackupVaultKey.Arn
Deploy with AWS-managed key:
aws cloudformation deploy \
--template-file template.yaml \
--stack-name encrypted-backup-vault \
--region us-east-1
Deploy with customer-managed key:
aws cloudformation deploy \
--template-file template.yaml \
--stack-name encrypted-backup-vault \
--parameter-overrides UseCustomerManagedKey=true \
--region us-east-1
Terraform (optional)
# AWS Backup Vault with KMS Encryption
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0"
}
}
}
variable "vault_name" {
description = "Name of the backup vault"
type = string
default = "encrypted-backup-vault"
}
variable "use_customer_managed_key" {
description = "Use a customer-managed KMS key instead of AWS managed key"
type = bool
default = false
}
variable "tags" {
description = "Tags to apply to resources"
type = map(string)
default = {}
}
# Customer-managed KMS key (optional)
resource "aws_kms_key" "backup_vault" {
count = var.use_customer_managed_key ? 1 : 0
description = "KMS key for AWS Backup vault encryption"
deletion_window_in_days = 30
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow Backup Service"
Effect = "Allow"
Principal = {
Service = "backup.amazonaws.com"
}
Action = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]
Resource = "*"
}
]
})
tags = merge(var.tags, {
Purpose = "BackupVaultEncryption"
})
}
resource "aws_kms_alias" "backup_vault" {
count = var.use_customer_managed_key ? 1 : 0
name = "alias/${var.vault_name}-key"
target_key_id = aws_kms_key.backup_vault[0].key_id
}
# Data source for account ID
data "aws_caller_identity" "current" {}
# Encrypted backup vault
resource "aws_backup_vault" "encrypted" {
name = var.vault_name
kms_key_arn = var.use_customer_managed_key ? aws_kms_key.backup_vault[0].arn : null
tags = var.tags
}
output "backup_vault_arn" {
description = "ARN of the encrypted backup vault"
value = aws_backup_vault.encrypted.arn
}
output "backup_vault_name" {
description = "Name of the encrypted backup vault"
value = aws_backup_vault.encrypted.name
}
output "kms_key_arn" {
description = "ARN of the customer-managed KMS key (if created)"
value = var.use_customer_managed_key ? aws_kms_key.backup_vault[0].arn : null
}
Apply with AWS-managed key:
terraform apply
Apply with customer-managed key:
terraform apply -var="use_customer_managed_key=true"
Verification
After completing the remediation:
- Go to AWS Backup > Backup vaults in the console
- Click on your vault name
- Verify that Encryption key shows either
aws/backupor your customer-managed key ARN - Check that new recovery points created in this vault show as encrypted
CLI verification commands
Check vault encryption status:
aws backup describe-backup-vault \
--backup-vault-name encrypted-backup-vault \
--region us-east-1 \
--query '{VaultName: BackupVaultName, EncryptionKeyArn: EncryptionKeyArn}'
Expected output should show an EncryptionKeyArn value.
Run Prowler to verify the fix:
prowler aws --checks backup_recovery_point_encrypted --region us-east-1
Additional Resources
- AWS Backup Encryption Documentation
- AWS Security Hub Backup Controls
- AWS KMS Best Practices
- Prowler Check Documentation
Notes
- Existing recovery points cannot be encrypted in place. You must copy them to an encrypted vault and then delete the originals.
- Customer-managed keys provide more control but require additional management overhead. Use them when you need custom key policies, automatic rotation schedules, or cross-account access controls.
- The default
aws/backupkey is sufficient for most use cases and is automatically created when needed. - Cross-region or cross-account copies should always target encrypted vaults to maintain security during disaster recovery scenarios.
- Deleting a KMS key will make recovery points unrecoverable. Set appropriate deletion windows and protect keys with IAM policies.