Skip to main content

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

  1. Open the AWS Backup console
  2. In the left navigation, click Backup vaults
  3. Click Create backup vault
  4. Enter a name for your vault (e.g., encrypted-backup-vault)
  5. 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
  6. Click Create backup vault

Step 2: Update your backup plans to use the encrypted vault

  1. In the left navigation, click Backup plans
  2. Select your existing backup plan
  3. Click Edit on the backup rule
  4. Under Backup vault, select your new encrypted vault
  5. 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:

  1. Go to Backup vaults and select the unencrypted vault
  2. Find the recovery point you want to migrate
  3. Select the recovery point and click Actions > Copy
  4. Choose your encrypted vault as the destination
  5. 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:

  • 123456789012 with your AWS account ID
  • abcd1234-ab12-cd34-ef56-abcdef123456 with your recovery point ID
  • unencrypted-vault with your source vault name
  • AWSBackupDefaultServiceRole with 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:

  1. Go to AWS Backup > Backup vaults in the console
  2. Click on your vault name
  3. Verify that Encryption key shows either aws/backup or your customer-managed key ARN
  4. 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

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/backup key 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.