Cloud Data Loss Prevention (DLP) and Encryption Best Practices

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.