RDS DB instance storage is encrypted at rest
RDS DB instances are assessed for KMS-based encryption at rest (StorageEncrypted=true), covering instance storage and derived artifacts such as snapshots, automated backups, and read replicas.
Risk
Without encryption at rest, database files, snapshots, and automated backups remain in plaintext. An attacker with access to copied snapshots, compromised backups, or underlying storage can read sensitive data, causing loss of confidentiality and enabling large-scale exfiltration.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks rds_instance_storage_encryptedRecommendation
Enable encryption at rest for all RDS instances. Prefer customer-managed KMS keys to control rotation and fine-grained access, applying least privilege and defense in depth. Restrict key usage, monitor key activity, and manage key lifecycle. Migrate unencrypted instances via encrypted snapshot copy and restore.
Remediation
Terraform
# Terraform: create an encrypted RDS DB instance
resource "aws_db_instance" "<example_resource_name>" {
engine = "<engine>"
instance_class = "<instance_class>"
username = "<username>"
password = "<password>"
allocated_storage = 20
storage_encrypted = true # CRITICAL: enables encryption at rest to pass the check
}NativeIaC
# CloudFormation: create an encrypted RDS DB instance
Resources:
<example_resource_name>:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceClass: "<instance_class>"
Engine: "<engine>"
AllocatedStorage: 20
MasterUsername: "<username>"
MasterUserPassword: "<password>"
StorageEncrypted: true # CRITICAL: enables encryption at rest so the instance passes the checkOther
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.rds.rds_client import rds_client
class rds_instance_storage_encrypted(Check):
def execute(self):
findings = []
for db_instance in rds_client.db_instances.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=db_instance)
if db_instance.encrypted:
report.status = "PASS"
report.status_extended = f"RDS Instance {db_instance.id} is encrypted."
else:
report.status = "FAIL"
report.status_extended = (
f"RDS Instance {db_instance.id} is not encrypted."
)
findings.append(report)
return findingsReferences
- https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/aws/RDS/rds-encryption-enabled.html
- https://aws.amazon.com/blogs/storage/protecting-amazon-rds-db-instances-encrypted-using-kms-aws-managed-key-with-cross-account-and-cross-region-backups/
- https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.html