Navigating S3 Encryption

Erin Willingham
Spectrum Labs
Published in
5 min readMar 13, 2020

Encrypting your data is a fundamental step when operating secure systems and data at rest should be encrypted 99% of the time (I totally made that percent up but unless you are directly giving the data to anyone on the internet, it should probably be encrypted). AWS’s S3 is a fantastic tool for storing massive amounts of data relatively cheaply. However, understanding which type of encryption and key should be used for different circumstances can be a bit confusing at times. The following pictures and notes should help quickly explaining when and why you may choose one method over another.

Server Side Encryption — Using AWS Default Account Key

This is the most common and easiest way to encrypt an S3 bucket and its contents. This is just a S3 bucket using Server Side Encryption (SSE) and allowing AWS to manage the key.

Works

  • Users and Services in the same AWS account (Production in this example) can access objects in the S3 bucket
  • Users and Services in the same AWS account (Production in this example) can access CloudTrail objects in the S3 bucket

Doesn’t Work

  • Users and Services in a different AWS account (Development in this example) cannot access objects in the S3 bucket
  • Users and Services in a different AWS account (Development in this example) cannot access CloudTrail objects in the S3 bucket

Notes

  • Encryption key is managed by AWS, no additional actions need to be taken within the account
  • There is no way to change access or permissions to this key, all access is managed on the S3 bucket

Server Side Encryption — Using AWS Default Account Key (with additional Role)

This is a very similar setup to above except that the Production AWS account creates a Role that users or services in another AWS account can assume. Since the Development user assumes a role in the Production Account, it now has the ability take actions that were impossible before.

Works

  • Users and Services in the same AWS account (Production in this example) can access objects in the S3 bucket
  • Users and Services in the same AWS account (Production in this example) can access CloudTrail objects in the S3 bucket
  • Users and Services in a different AWS account (Development in this example) can access objects in the S3 bucket
  • Users and Services in a different AWS account (Development in this example) can access CloudTrail objects in the S3 bucket

Notes

  • Encryption key is managed by AWS.
  • There is no way to change access or permissions to this key, all access is managed on the S3 bucket
  • A Role in the Production account needs to be created for Users / Services of another account to assume.

Server Side Encryption — Using AWS KMS

The encryption of the objects in this bucket will use a key that is created in KMS. Additional permissions will need to be granted to users and services allowing access to the KMS key that is tied to the S3 bucket.

Works

  • Users and Services in the same AWS account (Production in this example) can access objects in the S3 bucket
  • Users and Services in the same AWS account (Production in this example) can access CloudTrail objects in the S3 bucket
  • Users and Services in a different AWS account (Development in this example) can access objects in the S3 bucket
  • Users and Services in a different AWS account (Development in this example) can access CloudTrail objects in the S3 bucket

Notes

  • Encryption key is created by the Production Account.
  • This key CAN have modified access and permissions.
  • Users and Services in a different account will still need to be granted explicit permission to use the key, otherwise they won’t be able to access the S3 objects.
  • Users / Services in the other account need to use an additional step when uploading contents, they need to grant the account owner ownership over the contents. --acl bucket-owner-full-control

Server Side Encryption — Using AWS KMS (Customer-Provided Keys)

SSE — KMS (CPK) S3 bucket encryption adds even more complexity. You need to create an encryption key (not through AWS) and add it to AWS KMS. The key isn’t stored by AWS so extra flags need to be passed to the aws cli every time a request to the S3 bucket objects is made. This type of encryption is also not supported for CloudTrail (because AWS doesn’t store the key and would have no way to encrypt the data sent to the bucket)
See AWS’s docs for more info here.
https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html

Works

  • Users and Services in the same AWS account (Production in this example) can access objects in the S3 bucket
  • Users and Services in a different AWS account (Development in this example) can access objects in the S3 bucket

Notes

  • Encryption key is created and then uploaded to AWS KMS.
  • This key CAN have modified access and permissions.
  • Users and Services in a different account will still need to be granted explicit permission to use the key, otherwise they won’t be able to access the S3 objects.
  • Users / Services in the other account need to use an additional step when uploading contents, they need to grant the account owner ownership over the contents.
  • Users / Services need to pass additional information (encryption key) when interacting with the S3 bucket contents.
  • CloudTrail Bucket can’t use this encryption type.

--

--