Skip to main content

Envelope Encryption

FluentDynamoDB uses envelope encryption to protect sensitive fields, the same pattern used by the AWS Encryption SDK.

How It Works

Instead of encrypting each field directly with your KMS key, the process works in two layers:

  1. Generate a data key — A unique data key is generated via KMS for each encryption operation
  2. Encrypt the field — The field value is encrypted using the data key (fast, local operation)
  3. Encrypt the data key — The data key itself is encrypted using your KMS key
  4. Store both — The encrypted field value and the encrypted data key are stored together in DynamoDB

On decryption, the process reverses: the encrypted data key is decrypted via KMS, then used to decrypt the field value locally.

Why Envelope Encryption?

Encrypting directly with KMS for every field would mean a KMS API call per field per operation. Envelope encryption reduces this to one KMS call per operation regardless of how many fields are encrypted, since the same data key can encrypt multiple fields.

ApproachKMS API CallsLatencyCost
Direct KMS encryption1 per fieldHighHigher
Envelope encryption1 per operationLowLower

AWS Encryption SDK

FluentDynamoDB uses the AWS Encryption SDK under the hood for the actual cryptographic operations. This provides:

  • Standard encryption message format
  • Support for key rotation
  • Multiple key provider support
  • Authenticated encryption (AES-GCM)
  • Key commitment (prevents key substitution attacks)

Storage Format

Encrypted fields are stored as Binary (B) attribute type in DynamoDB using the AWS Encryption SDK message format. This includes:

  • Algorithm suite identifier
  • Encrypted data key(s)
  • Initialization vector (IV)
  • Encrypted content
  • Authentication tag
  • Digital signature (for key commitment)

This format is industry-standard, interoperable with other AWS services, and includes built-in integrity checking.

Encryption in Update Expressions

Encryption works seamlessly in update expressions using a deferred encryption approach:

  1. Expression Translation — The UpdateExpressionTranslator identifies encrypted properties
  2. Parameter Metadata — Parameters requiring encryption are marked in metadata
  3. Async Encryption — The request builder calls IFieldEncryptor.EncryptAsync before sending to DynamoDB
  4. Value Replacement — Encrypted values replace plaintext in ExpressionAttributeValues
// Encryption happens transparently in updates
await table.Users.Update(userId)
.Set(x => new UserUpdateModel { SocialSecurityNumber = newSsn })
.UpdateAsync();
// The SSN is encrypted before being sent to DynamoDB

Performance Considerations

Encryption MethodTypical LatencyNotes
AWS KMS (no cache)10-50ms per fieldNetwork call to KMS
AWS KMS (with cache)1-5ms per fieldCache hit avoids KMS call
AWS Encryption SDK1-5ms per fieldBuilt-in caching

Tips for Performance

  • Enable caching — Set EnableCaching = true in AwsEncryptionSdkOptions
  • Minimize encrypted fields — Only encrypt truly sensitive data
  • Use envelope encryption — The library handles this automatically

See Also