3

(This is a generalization/variation on this question based on what I've learned in solving this.)

I use AWS Cloudfront with an S3 origin (i.e. to serve S3 objects).

I want to add server-side encryption to my bucket but continue to be able to access the objects via cloudfront.

I am agnostic about the precise SSE strategy used (so long as it is secure).

webelo
  • 1,646
  • 1
  • 14
  • 32

1 Answers1

5

If you have latitude over the SSE encryption type, it is possible to add SSE without the use of a lambda.

The key is to set the encryption type on the bucket to SSE-S3 (Amazon S3 Key).

The main steps are:

  1. Set the bucket encryption to SSE-S3 in Properties (tab) ~> Default encryption (panel) ~> Edit (button)
  2. Create a cloudfront distribution
  3. Link the bucket and cloudfront distribution via an Origin Access Identity
  4. Add a bucket policy that links the Origin Access Identity to the bucket.

Following the article, "Serving SSE-KMS encrypted content from S3 using CloudFront", here is an alternative CloudFormation stack corresponding to this distribution:

Resources:
  S3Bucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Join
        - "-"
        - - !Ref "AWS::StackName"
          - s3bucket
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256

  S3BucketPolicy:
    Type: "AWS::S3::BucketPolicy"
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Statement:
          - Action:
              - "s3:GetObject"
            Effect: Allow
            Resource: !Join
              - ""
              - - "arn:aws:s3:::"
                - !Ref S3Bucket
                - /*
            Principal:
              CanonicalUser:
                Fn::GetAtt: [OAI, S3CanonicalUserId]

  OAI:
    Type: "AWS::CloudFront::CloudFrontOriginAccessIdentity"
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: Origin Access Identity for S3

  Cloudfront:
    Type: "AWS::CloudFront::Distribution"
    Properties:
      DistributionConfig:
        Comment: How to serve content encrypted with SSE-S3 from S3 using CloudFront
        Origins:
          - DomainName: !Join
              - .
              - - !Ref S3Bucket
                - s3
                - !Ref "AWS::Region"
                - amazonaws.com
            Id: S3-regional-endpoint
            S3OriginConfig:
              OriginAccessIdentity: !Join
                - /
                - - origin-access-identity
                  - cloudfront
                  - !Ref OAI
        DefaultCacheBehavior:
          TargetOriginId: S3-regional-endpoint
          ForwardedValues:
            QueryString: "false"
          ViewerProtocolPolicy: redirect-to-https
        Enabled: "true"
  • Relative to the above-cited article, this requires specifying an Origin Access Identity (OAI) as well as a bucket policy (S3BucketPolicy) but no KMS resources.
  • In CloudFormation and terraform, you can specify encryption type to be SSE-S3 by specifying AES256 (see line SSEAlgorithm: AES256).

If you are using terraform, there are a few modules (e.g. here and here) that essentially do the above with some additional goodies.

webelo
  • 1,646
  • 1
  • 14
  • 32