Data Loss Prevention and encryption are critical controls for protecting sensitive information in cloud environments. This guide covers implementing DLP policies, encryption strategies, and key management best practices across major cloud providers.
Data Classification
Before implementing DLP, classify your data into categories:
- Public: No restrictions on access
- Internal: Business data, not for external sharing
- Confidential: Sensitive business information
- Restricted: PII, PHI, financial data, credentials
AWS Macie for Data Discovery
# Terraform - Enable Macie
resource "aws_macie2_account" "main" {
finding_publishing_frequency = "FIFTEEN_MINUTES"
status = "ENABLED"
}
resource "aws_macie2_classification_job" "pii_scan" {
name = "pii-discovery-job"
job_type = "SCHEDULED"
job_status = "RUNNING"
s3_job_definition {
bucket_definitions {
account_id = data.aws_caller_identity.current.account_id
buckets = ["sensitive-data-bucket"]
}
}
schedule_frequency {
daily_schedule = true
}
}Encryption at Rest
# KMS key with rotation
resource "aws_kms_key" "data_key" {
description = "Key for encrypting sensitive data"
deletion_window_in_days = 30
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable IAM policies"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow service use"
Effect = "Allow"
Principal = {
Service = "s3.amazonaws.com"
}
Action = [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey*"
]
Resource = "*"
}
]
})
}
# S3 bucket with encryption
resource "aws_s3_bucket_server_side_encryption_configuration" "encrypted" {
bucket = aws_s3_bucket.sensitive.id
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.data_key.arn
sse_algorithm = "aws:kms"
}
bucket_key_enabled = true
}
}Encryption in Transit
# Enforce TLS 1.2+ on S3
resource "aws_s3_bucket_policy" "enforce_tls" {
bucket = aws_s3_bucket.sensitive.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "EnforceTLS"
Effect = "Deny"
Principal = "*"
Action = "s3:*"
Resource = [
aws_s3_bucket.sensitive.arn,
"${aws_s3_bucket.sensitive.arn}/*"
]
Condition = {
Bool = {
"aws:SecureTransport" = "false"
}
}
}
]
})
}Application-Level Encryption
# Python - Field-level encryption
import boto3
from cryptography.fernet import Fernet
import base64
class FieldEncryption:
def __init__(self, kms_key_id):
self.kms = boto3.client('kms')
self.key_id = kms_key_id
def encrypt_field(self, plaintext):
# Generate data key
response = self.kms.generate_data_key(
KeyId=self.key_id,
KeySpec='AES_256'
)
# Encrypt with data key
fernet = Fernet(base64.urlsafe_b64encode(response['Plaintext']))
ciphertext = fernet.encrypt(plaintext.encode())
return {
'encrypted_key': base64.b64encode(response['CiphertextBlob']).decode(),
'ciphertext': ciphertext.decode()
}
def decrypt_field(self, encrypted_data):
# Decrypt data key
response = self.kms.decrypt(
CiphertextBlob=base64.b64decode(encrypted_data['encrypted_key'])
)
# Decrypt field
fernet = Fernet(base64.urlsafe_b64encode(response['Plaintext']))
return fernet.decrypt(encrypted_data['ciphertext'].encode()).decode()DLP Policy Example
# AWS Config rule for unencrypted resources
resource "aws_config_config_rule" "encrypted_volumes" {
name = "encrypted-volumes"
source {
owner = "AWS"
source_identifier = "ENCRYPTED_VOLUMES"
}
}
resource "aws_config_config_rule" "s3_bucket_ssl" {
name = "s3-bucket-ssl-requests-only"
source {
owner = "AWS"
source_identifier = "S3_BUCKET_SSL_REQUESTS_ONLY"
}
}Conclusion
Effective data protection requires a layered approach combining classification, DLP scanning, encryption at rest and in transit, and proper key management. Regular audits and automated compliance checks ensure these controls remain effective over time.

